mirror of https://github.com/sbt/sbt.git
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.
This commit is contained in:
parent
96b2ca7ce4
commit
a4c059cb7e
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -36,18 +36,20 @@ trait Plugin
|
|||
object Build
|
||||
{
|
||||
val defaultEmpty: Build = new Build { override def projects = Nil }
|
||||
val default: Build = new Build { override def projectDefinitions(base: File) = defaultProject(base) :: Nil }
|
||||
def defaultAggregated(aggregate: Seq[ProjectRef]): Build = new Build {
|
||||
override def projectDefinitions(base: File) = defaultAggregatedProject(base, aggregate) :: Nil
|
||||
val default: Build = new Build { override def projectDefinitions(base: File) = defaultProject(defaultID(base), base) :: Nil }
|
||||
def defaultAggregated(id: String, aggregate: Seq[ProjectRef]): Build = new Build {
|
||||
override def projectDefinitions(base: File) = defaultAggregatedProject(id, base, aggregate) :: Nil
|
||||
}
|
||||
|
||||
def defaultID(base: File): String = "default-" + Hash.trimHashString(base.getAbsolutePath, 6)
|
||||
def defaultProject(base: File): Project = Project(defaultID(base), base).settings(
|
||||
def defaultID(base: File, prefix: String = "default"): String = prefix + "-" + Hash.trimHashString(base.getAbsolutePath, 6)
|
||||
@deprecated("Explicitly specify the ID", "0.13.0")
|
||||
def defaultProject(base: File): Project = defaultProject(defaultID(base), base)
|
||||
def defaultProject(id: String, base: File): Project = Project(id, base).settings(
|
||||
// if the user has overridden the name, use the normal organization that is derived from the name.
|
||||
organization <<= (thisProject, organization, name) { (p, o, n) => if(p.id == n) "default" else o }
|
||||
)
|
||||
def defaultAggregatedProject(base: File, agg: Seq[ProjectRef]): Project =
|
||||
defaultProject(base).aggregate(agg : _*)
|
||||
def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project =
|
||||
defaultProject(id, base).aggregate(agg : _*)
|
||||
|
||||
@deprecated("Use Attributed.data", "0.13.0")
|
||||
def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ object GlobalPlugin
|
|||
|
||||
def build(base: File, s: State, config: LoadBuildConfiguration): (BuildStructure, State) =
|
||||
{
|
||||
val globalConfig = config.copy(injectSettings = config.injectSettings.copy(global = config.injectSettings.global ++ globalPluginSettings))
|
||||
val newInject = config.injectSettings.copy(global = config.injectSettings.global ++ globalPluginSettings)
|
||||
val globalConfig = config.copy(injectSettings = newInject, pluginManagement = config.pluginManagement.forGlobalPlugin)
|
||||
val (eval, structure) = Load(base, s, globalConfig)
|
||||
val session = Load.initialSession(structure, eval)
|
||||
(structure, Project.setProject(session, structure, s))
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ object Load
|
|||
val compilers = Compiler.compilers(ClasspathOptions.boot)(state.configuration, log)
|
||||
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
|
||||
val delegates = defaultDelegates
|
||||
val initialID = baseDirectory.getName
|
||||
val pluginMgmt = PluginManagement(loader)
|
||||
val inject = InjectSettings(injectGlobal(state), Nil, const(Nil))
|
||||
new sbt.LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass, delegates,
|
||||
|
|
@ -405,7 +406,7 @@ object Load
|
|||
val normBase = localBase.getCanonicalFile
|
||||
val defDir = projectStandard(normBase)
|
||||
|
||||
val plugs = plugins(defDir, s, config)
|
||||
val plugs = plugins(defDir, s, config.copy(pluginManagement = config.pluginManagement.forPlugin))
|
||||
val defNames = analyzed(plugs.fullClasspath) flatMap findDefinitions
|
||||
val defsScala = if(defNames.isEmpty) Nil else loadDefinitions(plugs.loader, defNames)
|
||||
val imports = BuildUtil.getImports(plugs.pluginNames, defNames)
|
||||
|
|
@ -421,7 +422,10 @@ object Load
|
|||
if(hasRoot)
|
||||
(loadedProjectsRaw, Build.defaultEmpty)
|
||||
else {
|
||||
val b = Build.defaultAggregated(loadedProjectsRaw.map(p => ProjectRef(uri, p.id)))
|
||||
val existingIDs = loadedProjectsRaw.map(_.id)
|
||||
val refs = existingIDs.map(id => ProjectRef(uri, id))
|
||||
val defaultID = autoID(normBase, config.pluginManagement.context, existingIDs)
|
||||
val b = Build.defaultAggregated(defaultID, refs)
|
||||
val defaultProjects = loadProjects(projectsFromBuild(b, normBase))
|
||||
(defaultProjects ++ loadedProjectsRaw, b)
|
||||
}
|
||||
|
|
@ -430,6 +434,17 @@ object Load
|
|||
val loadedDefs = new sbt.LoadedDefinitions(defDir, Nil, plugs.loader, defs, loadedProjects, defNames)
|
||||
new sbt.BuildUnit(uri, normBase, loadedDefs, plugs)
|
||||
}
|
||||
private[this] def autoID(localBase: File, context: PluginManagement.Context, existingIDs: Seq[String]): String =
|
||||
{
|
||||
import StringUtilities.{normalize => norm}
|
||||
def nthParentName(f: File, i: Int): String =
|
||||
if(f eq null) Build.defaultID(localBase) else if(i <= 0) norm(f.getName) else nthParentName(f.getParentFile, i - 1)
|
||||
val pluginDepth = context.pluginProjectDepth
|
||||
val postfix = "-build" * pluginDepth
|
||||
val idBase = if(context.globalPluginProject) "global-plugins" else nthParentName(localBase, pluginDepth)
|
||||
val tryID = idBase + postfix
|
||||
if(existingIDs.contains(tryID)) Build.defaultID(localBase) else tryID
|
||||
}
|
||||
private[this] def projectsFromBuild(b: Build, base: File): Seq[Project] =
|
||||
b.projectDefinitions(base).map(resolveBase(base))
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ package sbt
|
|||
|
||||
import java.net.{URI,URL,URLClassLoader}
|
||||
|
||||
final case class PluginManagement(overrides: Set[ModuleID], applyOverrides: Set[ModuleID], loader: PluginClassLoader, initialLoader: ClassLoader)
|
||||
final case class PluginManagement(overrides: Set[ModuleID], applyOverrides: Set[ModuleID], loader: PluginClassLoader, initialLoader: ClassLoader, context: Context)
|
||||
{
|
||||
def shift: PluginManagement =
|
||||
PluginManagement(Set.empty, overrides, new PluginClassLoader(initialLoader), initialLoader)
|
||||
PluginManagement(Set.empty, overrides, new PluginClassLoader(initialLoader), initialLoader, context)
|
||||
|
||||
def addOverrides(os: Set[ModuleID]): PluginManagement =
|
||||
copy(overrides = overrides ++ os)
|
||||
|
|
@ -20,11 +20,17 @@ final case class PluginManagement(overrides: Set[ModuleID], applyOverrides: Set[
|
|||
def inject: Seq[Setting[_]] = Seq(
|
||||
Keys.dependencyOverrides ++= overrides
|
||||
)
|
||||
|
||||
def forGlobalPlugin: PluginManagement = copy(context = Context(globalPluginProject = true, pluginProjectDepth = 0))
|
||||
def forPlugin: PluginManagement = copy(context = context.copy(pluginProjectDepth = context.pluginProjectDepth + 1))
|
||||
}
|
||||
object PluginManagement
|
||||
{
|
||||
final case class Context private[sbt](globalPluginProject: Boolean, pluginProjectDepth: Int)
|
||||
val emptyContext: Context = Context(false, 0)
|
||||
|
||||
def apply(initialLoader: ClassLoader): PluginManagement =
|
||||
PluginManagement(Set.empty, Set.empty, new PluginClassLoader(initialLoader), initialLoader)
|
||||
PluginManagement(Set.empty, Set.empty, new PluginClassLoader(initialLoader), initialLoader, emptyContext)
|
||||
|
||||
def extractOverrides(classpath: Classpath): Set[ModuleID] =
|
||||
classpath flatMap { _.metadata get Keys.moduleID.key map keepOverrideInfo } toSet;
|
||||
|
|
|
|||
Loading…
Reference in New Issue