mirror of
https://github.com/sbt/sbt.git
synced 2026-08-22 14:17:13 +02:00
* Make tab completion of method tasks lazy, so that javap and test-only don't slow down initial tab completion.
* cleanup of builder related code, including removing duplication from classpath in console-project * only replace relevant version in build.scala.versions when user enters new Scala version to replace bad entry
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
project.organization=org.scala-tools.sbt
|
project.organization=org.scala-tools.sbt
|
||||||
project.name=Simple Build Tool
|
project.name=Simple Build Tool
|
||||||
sbt.version=0.5.6
|
sbt.version=0.5.6
|
||||||
project.version=0.6.13
|
project.version=0.7.0-SNAPSHOT
|
||||||
scala.version=2.7.7
|
scala.version=2.7.7
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ object Reflective
|
|||||||
{
|
{
|
||||||
def reflectiveMappings[T](obj: AnyRef)(implicit m: scala.reflect.Manifest[T]): Map[String, T] =
|
def reflectiveMappings[T](obj: AnyRef)(implicit m: scala.reflect.Manifest[T]): Map[String, T] =
|
||||||
{
|
{
|
||||||
val mappings = new mutable.OpenHashMap[String, T]
|
val mappings = new mutable.HashMap[String, T]
|
||||||
for ((name, value) <- ReflectUtilities.allVals[T](obj))
|
for ((name, value) <- ReflectUtilities.allVals[T](obj))
|
||||||
mappings(ReflectUtilities.transformCamelCase(name, '-')) = value
|
mappings(ReflectUtilities.transformCamelCase(name, '-')) = value
|
||||||
mappings
|
mappings
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ private sealed abstract class BasicBuilderProject extends InternalProject
|
|||||||
|
|
||||||
import xsbt.ScalaInstance
|
import xsbt.ScalaInstance
|
||||||
|
|
||||||
val definitionCompileConditional = new BuilderCompileConditional(definitionCompileConfiguration, buildCompiler, tpe)
|
lazy val definitionCompileConditional = new BuilderCompileConditional(definitionCompileConfiguration, buildCompiler, tpe)
|
||||||
final class BuilderCompileConditional(config: BuilderCompileConfiguration, compiler: xsbt.AnalyzingCompiler, tpe: String) extends AbstractCompileConditional(config, compiler)
|
final class BuilderCompileConditional(config: BuilderCompileConfiguration, compiler: xsbt.AnalyzingCompiler, tpe: String) extends AbstractCompileConditional(config, compiler)
|
||||||
{
|
{
|
||||||
type AnalysisType = BuilderCompileAnalysis
|
type AnalysisType = BuilderCompileAnalysis
|
||||||
@@ -111,9 +111,9 @@ private sealed abstract class BasicBuilderProject extends InternalProject
|
|||||||
override final def methods = Map.empty
|
override final def methods = Map.empty
|
||||||
}
|
}
|
||||||
/** The project definition used to build project definitions. */
|
/** The project definition used to build project definitions. */
|
||||||
private final class BuilderProject(val info: ProjectInfo, val pluginPath: Path, additional: PathFinder, rawLogger: Logger) extends BasicBuilderProject
|
private final class BuilderProject(val info: ProjectInfo, val pluginPath: Path, rawLogger: Logger) extends BasicBuilderProject
|
||||||
{
|
{
|
||||||
private lazy val pluginProject =
|
lazy val pluginProject =
|
||||||
{
|
{
|
||||||
if(pluginPath.exists)
|
if(pluginPath.exists)
|
||||||
Some(new PluginBuilderProject(ProjectInfo(pluginPath.asFile, Nil, None)(rawLogger, info.app, info.buildScalaVersion)))
|
Some(new PluginBuilderProject(ProjectInfo(pluginPath.asFile, Nil, None)(rawLogger, info.app, info.buildScalaVersion)))
|
||||||
@@ -121,15 +121,14 @@ private final class BuilderProject(val info: ProjectInfo, val pluginPath: Path,
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
override def projectClasspath = super.projectClasspath +++
|
override def projectClasspath = super.projectClasspath +++
|
||||||
pluginProject.map(_.pluginClasspath).getOrElse(Path.emptyPathFinder) +++
|
pluginProject.map(_.pluginClasspath).getOrElse(Path.emptyPathFinder)
|
||||||
additional
|
|
||||||
def tpe = "project definition"
|
def tpe = "project definition"
|
||||||
|
|
||||||
override def compileTask = super.compileTask dependsOn(pluginProject.map(_.syncPlugins).toList : _*)
|
override def compileTask = super.compileTask dependsOn(pluginProject.map(_.syncPlugins).toList : _*)
|
||||||
|
|
||||||
final class PluginBuilderProject(val info: ProjectInfo) extends BasicBuilderProject
|
final class PluginBuilderProject(val info: ProjectInfo) extends BasicBuilderProject
|
||||||
{
|
{
|
||||||
val pluginUptodate = propertyOptional[Boolean](false)
|
lazy val pluginUptodate = propertyOptional[Boolean](false)
|
||||||
def tpe = "plugin definition"
|
def tpe = "plugin definition"
|
||||||
def managedSourcePath = path(BasicDependencyPaths.DefaultManagedSourceDirectoryName)
|
def managedSourcePath = path(BasicDependencyPaths.DefaultManagedSourceDirectoryName)
|
||||||
def managedDependencyPath = crossPath(BasicDependencyPaths.DefaultManagedDirectoryName)
|
def managedDependencyPath = crossPath(BasicDependencyPaths.DefaultManagedDirectoryName)
|
||||||
|
|||||||
@@ -11,7 +11,14 @@ class Completors(val projectAction: String, val projectNames: Iterable[String],
|
|||||||
val generalCommands: Iterable[String], val propertyActions: Iterable[String],
|
val generalCommands: Iterable[String], val propertyActions: Iterable[String],
|
||||||
val specificPrefix: String, val scalaVersions: Iterable[String],
|
val specificPrefix: String, val scalaVersions: Iterable[String],
|
||||||
val prefixes: Iterable[String], val taskNames: Iterable[String],
|
val prefixes: Iterable[String], val taskNames: Iterable[String],
|
||||||
val propertyNames: Iterable[String], val extra: Iterable[(String, Iterable[String])]) extends NotNull
|
val propertyNames: Iterable[String], val extra: ExtraCompletions) extends NotNull
|
||||||
|
|
||||||
|
trait ExtraCompletions extends NotNull
|
||||||
|
{
|
||||||
|
def names: Iterable[String]
|
||||||
|
def completions(name: String): Iterable[String]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
import jline.{Completor, ConsoleReader}
|
import jline.{Completor, ConsoleReader}
|
||||||
abstract class JLine extends LineReader
|
abstract class JLine extends LineReader
|
||||||
@@ -91,8 +98,10 @@ object MainCompletor
|
|||||||
val specific = simpleCompletor(specificPrefix :: Nil) // TODO
|
val specific = simpleCompletor(specificPrefix :: Nil) // TODO
|
||||||
new ArgumentCompletor( Array( specific, simpleCompletor(scalaVersions), baseCompletor ) )
|
new ArgumentCompletor( Array( specific, simpleCompletor(scalaVersions), baseCompletor ) )
|
||||||
}
|
}
|
||||||
|
def extraCompletor(name: String) =
|
||||||
|
repeatedArgumentCompletor(simpleCompletor(name :: Nil), new LazyCompletor(simpleCompletor(extra.completions(name))))
|
||||||
val taskCompletor = simpleCompletor(TreeSet(taskNames.toSeq : _*))
|
val taskCompletor = simpleCompletor(TreeSet(taskNames.toSeq : _*))
|
||||||
val extraCompletors = for( (first, repeat) <- extra) yield repeatedArgumentCompletor(simpleCompletor(first :: Nil), simpleCompletor(repeat))
|
val extraCompletors = extra.names.map(extraCompletor)
|
||||||
val baseCompletors = generalCompletor :: taskCompletor :: projectCompletor :: propertyCompletor(propertyNames) :: extraCompletors.toList
|
val baseCompletors = generalCompletor :: taskCompletor :: projectCompletor :: propertyCompletor(propertyNames) :: extraCompletors.toList
|
||||||
val baseCompletor = new MultiCompletor(baseCompletors.toArray)
|
val baseCompletor = new MultiCompletor(baseCompletors.toArray)
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,8 @@ class xMain extends xsbti.AppMain
|
|||||||
lazy val projectNames = baseProject.projectClosure.map(_.name)
|
lazy val projectNames = baseProject.projectClosure.map(_.name)
|
||||||
val prefixes = ContinuousExecutePrefix :: CrossBuildPrefix :: Nil
|
val prefixes = ContinuousExecutePrefix :: CrossBuildPrefix :: Nil
|
||||||
lazy val scalaVersions = baseProject.crossScalaVersions ++ Seq(baseProject.defScalaVersion.value)
|
lazy val scalaVersions = baseProject.crossScalaVersions ++ Seq(baseProject.defScalaVersion.value)
|
||||||
lazy val methodCompletions = for( (name, method) <- project.methods) yield (name, method.completions)
|
lazy val methods = project.methods
|
||||||
|
lazy val methodCompletions = new ExtraCompletions { def names = methods.keys.toList; def completions(name: String) = methods(name).completions }
|
||||||
lazy val completors = new Completors(ProjectAction, projectNames, interactiveCommands, List(GetAction, SetAction), SpecificBuildPrefix, scalaVersions, prefixes, project.taskNames, project.propertyNames, methodCompletions)
|
lazy val completors = new Completors(ProjectAction, projectNames, interactiveCommands, List(GetAction, SetAction), SpecificBuildPrefix, scalaVersions, prefixes, project.taskNames, project.propertyNames, methodCompletions)
|
||||||
val reader = new LazyJLineReader(baseProject.historyPath, MainCompletor(completors), baseProject.log)
|
val reader = new LazyJLineReader(baseProject.historyPath, MainCompletor(completors), baseProject.log)
|
||||||
reader.readLine("> ").getOrElse(ExitCommand)
|
reader.readLine("> ").getOrElse(ExitCommand)
|
||||||
|
|||||||
@@ -233,16 +233,21 @@ trait Project extends TaskManager with Dag[Project] with BasicEnvironment
|
|||||||
def buildScalaInstance = buildScalaInstance0
|
def buildScalaInstance = buildScalaInstance0
|
||||||
final def buildScalaInstance0: ScalaInstance =
|
final def buildScalaInstance0: ScalaInstance =
|
||||||
{
|
{
|
||||||
try { getScalaInstance(buildScalaVersion) }
|
val scalaVersion = buildScalaVersion
|
||||||
|
try { getScalaInstance(scalaVersion) }
|
||||||
catch { case e: xsbti.RetrieveException if info.buildScalaVersion.isEmpty => // only catch the exception if this is the default Scala version
|
catch { case e: xsbti.RetrieveException if info.buildScalaVersion.isEmpty => // only catch the exception if this is the default Scala version
|
||||||
log.error(e.getMessage)
|
log.error(e.getMessage)
|
||||||
SimpleReader.readLine("\nProvide a new Scala version or press enter to exit: ") match
|
SimpleReader.readLine("\nProvide a new Scala version or press enter to exit: ") match
|
||||||
{
|
{
|
||||||
case Some(v) if v.length > 0=> buildScalaVersions() = v; saveEnvironment(); buildScalaInstance0
|
case Some(v) if v.length > 0=>
|
||||||
|
buildScalaVersions() = replace(scalaVersion, v)
|
||||||
|
saveEnvironment()
|
||||||
|
buildScalaInstance0
|
||||||
case _ => throw e
|
case _ => throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private def replace(originalV: String, newV: String) = buildScalaVersions.value.replaceAll("""\b\Q""" + originalV + """\E\b""", newV)
|
||||||
def getScalaInstance(version: String) =
|
def getScalaInstance(version: String) =
|
||||||
localScalaInstances.find(_.version == version) getOrElse
|
localScalaInstances.find(_.version == version) getOrElse
|
||||||
xsbt.ScalaInstance(version, info.launcher)
|
xsbt.ScalaInstance(version, info.launcher)
|
||||||
@@ -407,28 +412,40 @@ object Project
|
|||||||
}
|
}
|
||||||
val useName = p.projectName.get.getOrElse("at " + p.info.projectDirectory.getAbsolutePath)
|
val useName = p.projectName.get.getOrElse("at " + p.info.projectDirectory.getAbsolutePath)
|
||||||
checkDependencies(useName, p.info.dependencies, log)
|
checkDependencies(useName, p.info.dependencies, log)
|
||||||
|
p.buildScalaInstance // done so that build Scala version is initialized on project startup
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
/** Compiles the project definition classes and returns the project definition class name
|
/** Compiles the project definition classes and returns the project definition class name
|
||||||
* and the class loader that should be used to load the definition. */
|
* and the class loader that should be used to load the definition. */
|
||||||
private def getProjectDefinition(info: ProjectInfo, buildLog: Logger): Either[String, Class[P] forSome { type P <: Project }] =
|
private def getProjectDefinition(info: ProjectInfo, buildLog: Logger): Either[String, Class[P] forSome { type P <: Project }] =
|
||||||
{
|
getProjectBuilder(info, buildLog) match
|
||||||
val builderProjectPath = info.builderPath / BuilderProjectDirectoryName
|
|
||||||
if(builderProjectPath.asFile.isDirectory)
|
|
||||||
{
|
{
|
||||||
val pluginProjectPath = info.builderPath / PluginProjectDirectoryName
|
case Some(builder) => buildProjectDefinition(builder)
|
||||||
val additionalPaths = info.sbtClasspath
|
case None => Right(DefaultBuilderClass)
|
||||||
val builderInfo = ProjectInfo(builderProjectPath.asFile, Nil, None)(buildLog, info.app, Some(info.definitionScalaVersion))
|
}
|
||||||
val builderProject = new BuilderProject(builderInfo, pluginProjectPath, additionalPaths, buildLog)
|
private def buildProjectDefinition(builderProject: BuilderProject): Either[String, Class[P] forSome { type P <: Project }] =
|
||||||
builderProject.compile.run.toLeft(()).right.flatMap { ignore =>
|
builderProject.compile.run.toLeft(()).right.flatMap { ignore =>
|
||||||
builderProject.projectDefinition.right.map {
|
builderProject.projectDefinition.right.map {
|
||||||
case Some(definition) => getProjectClass[Project](definition, builderProject.projectClasspath, getClass.getClassLoader)
|
case Some(definition) => getProjectClass[Project](definition, builderProject.projectClasspath, getClass.getClassLoader)
|
||||||
case None => DefaultBuilderClass
|
case None => DefaultBuilderClass
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private[sbt] def getProjectClasspath(project: Project): PathFinder =
|
||||||
|
getProjectBuilder(project.info, project.log) match
|
||||||
|
{
|
||||||
|
case Some(builder) => builder.projectClasspath
|
||||||
|
case None => project.info.sbtClasspath
|
||||||
|
}
|
||||||
|
private[sbt] def getProjectBuilder(info: ProjectInfo, buildLog: Logger): Option[BuilderProject] =
|
||||||
|
{
|
||||||
|
if(info.builderProjectPath.asFile.isDirectory)
|
||||||
|
{
|
||||||
|
val builderInfo = ProjectInfo(info.builderProjectPath.asFile, Nil, None)(buildLog, info.app, Some(info.definitionScalaVersion))
|
||||||
|
val builderProject = new BuilderProject(builderInfo, info.pluginsPath, buildLog)
|
||||||
|
Some(builderProject)
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Right(DefaultBuilderClass)
|
None
|
||||||
}
|
}
|
||||||
/** Verifies that the given list of project dependencies contains no nulls. The
|
/** Verifies that the given list of project dependencies contains no nulls. The
|
||||||
* String argument should be the project name with the dependencies.*/
|
* String argument should be the project name with the dependencies.*/
|
||||||
|
|||||||
@@ -109,11 +109,8 @@ object Run
|
|||||||
override def createInterpreter()
|
override def createInterpreter()
|
||||||
{
|
{
|
||||||
val projectLoader = project.getClass.getClassLoader
|
val projectLoader = project.getClass.getClassLoader
|
||||||
val launcherJar = FileUtilities.classLocationFile[xsbti.Launcher]
|
val classpath = Project.getProjectClasspath(project)
|
||||||
val app = project.info.app
|
compilerSettings.classpath.value = Path.makeString(classpath.get ++ Path.fromFiles(project.info.app.scalaProvider.jars))
|
||||||
val projectJars: Array[File] = projectLoader.asInstanceOf[URLClassLoader].getURLs.flatMap(ClasspathUtilities.asFile).toArray[File]
|
|
||||||
val classpathFiles = app.mainClasspath ++ app.scalaProvider.jars ++ Array(launcherJar) ++ projectJars
|
|
||||||
compilerSettings.classpath.value = classpathFiles.map(_.getAbsolutePath).mkString(File.pathSeparator)
|
|
||||||
project.log.debug(" Compiler classpath: " + compilerSettings.classpath.value)
|
project.log.debug(" Compiler classpath: " + compilerSettings.classpath.value)
|
||||||
|
|
||||||
in = InteractiveReader.createDefault()
|
in = InteractiveReader.createDefault()
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ trait ScalaProject extends SimpleScalaProject with FileTasks with MultiTaskProje
|
|||||||
val Private = Value("private")
|
val Private = Value("private")
|
||||||
}
|
}
|
||||||
|
|
||||||
def javapTask(classpath: PathFinder, conditional: CompileConditional, compilePath: Path) =
|
def javapTask(classpath: PathFinder, conditional: => CompileConditional, compilePath: Path) =
|
||||||
task { args =>
|
task { args =>
|
||||||
val cp = classpath +++ Path.fromFile(FileUtilities.scalaLibraryJar) +++ Path.fromFile(FileUtilities.scalaCompilerJar)
|
val cp = classpath +++ Path.fromFile(FileUtilities.scalaLibraryJar) +++ Path.fromFile(FileUtilities.scalaCompilerJar)
|
||||||
execOut { Process("javap" :: "-classpath" :: Path.makeString(cp.get) :: args.toList) }
|
execOut { Process("javap" :: "-classpath" :: Path.makeString(cp.get) :: args.toList) }
|
||||||
@@ -179,9 +179,9 @@ trait ScalaProject extends SimpleScalaProject with FileTasks with MultiTaskProje
|
|||||||
}
|
}
|
||||||
private def toTask(testTask: NamedTestTask) = task(testTask.run()) named(testTask.name)
|
private def toTask(testTask: NamedTestTask) = task(testTask.run()) named(testTask.name)
|
||||||
|
|
||||||
def graphSourcesTask(outputDirectory: Path, roots: PathFinder, analysis: CompileAnalysis): Task =
|
def graphSourcesTask(outputDirectory: Path, roots: PathFinder, analysis: => CompileAnalysis): Task =
|
||||||
task { DotGraph.sources(analysis, outputDirectory, roots.get, log) }
|
task { DotGraph.sources(analysis, outputDirectory, roots.get, log) }
|
||||||
def graphPackagesTask(outputDirectory: Path, roots: PathFinder, analysis: CompileAnalysis): Task =
|
def graphPackagesTask(outputDirectory: Path, roots: PathFinder, analysis: => CompileAnalysis): Task =
|
||||||
task { DotGraph.packages(analysis, outputDirectory, roots.get, log) }
|
task { DotGraph.packages(analysis, outputDirectory, roots.get, log) }
|
||||||
def scaladocTask(label: String, sources: PathFinder, outputDirectory: Path, classpath: PathFinder, options: ScaladocOption*): Task =
|
def scaladocTask(label: String, sources: PathFinder, outputDirectory: Path, classpath: PathFinder, options: ScaladocOption*): Task =
|
||||||
scaladocTask(label, sources, outputDirectory, classpath, options)
|
scaladocTask(label, sources, outputDirectory, classpath, options)
|
||||||
|
|||||||
Reference in New Issue
Block a user