mirror of https://github.com/sbt/sbt.git
* 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:
parent
a863e866d5
commit
8bea7ec316
|
|
@ -1,5 +1,5 @@
|
|||
project.organization=org.scala-tools.sbt
|
||||
project.name=Simple Build Tool
|
||||
sbt.version=0.5.6
|
||||
project.version=0.6.13
|
||||
project.version=0.7.0-SNAPSHOT
|
||||
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] =
|
||||
{
|
||||
val mappings = new mutable.OpenHashMap[String, T]
|
||||
val mappings = new mutable.HashMap[String, T]
|
||||
for ((name, value) <- ReflectUtilities.allVals[T](obj))
|
||||
mappings(ReflectUtilities.transformCamelCase(name, '-')) = value
|
||||
mappings
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ private sealed abstract class BasicBuilderProject extends InternalProject
|
|||
|
||||
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)
|
||||
{
|
||||
type AnalysisType = BuilderCompileAnalysis
|
||||
|
|
@ -111,9 +111,9 @@ private sealed abstract class BasicBuilderProject extends InternalProject
|
|||
override final def methods = Map.empty
|
||||
}
|
||||
/** 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)
|
||||
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
|
||||
}
|
||||
override def projectClasspath = super.projectClasspath +++
|
||||
pluginProject.map(_.pluginClasspath).getOrElse(Path.emptyPathFinder) +++
|
||||
additional
|
||||
pluginProject.map(_.pluginClasspath).getOrElse(Path.emptyPathFinder)
|
||||
def tpe = "project definition"
|
||||
|
||||
override def compileTask = super.compileTask dependsOn(pluginProject.map(_.syncPlugins).toList : _*)
|
||||
|
||||
final class PluginBuilderProject(val info: ProjectInfo) extends BasicBuilderProject
|
||||
{
|
||||
val pluginUptodate = propertyOptional[Boolean](false)
|
||||
lazy val pluginUptodate = propertyOptional[Boolean](false)
|
||||
def tpe = "plugin definition"
|
||||
def managedSourcePath = path(BasicDependencyPaths.DefaultManagedSourceDirectoryName)
|
||||
def managedDependencyPath = crossPath(BasicDependencyPaths.DefaultManagedDirectoryName)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,15 @@ trait LineReader extends NotNull
|
|||
class Completors(val projectAction: String, val projectNames: Iterable[String],
|
||||
val generalCommands: Iterable[String], val propertyActions: Iterable[String],
|
||||
val specificPrefix: String, val scalaVersions: Iterable[String],
|
||||
val prefixes: Iterable[String], val taskNames: Iterable[String],
|
||||
val propertyNames: Iterable[String], val extra: Iterable[(String, Iterable[String])]) extends NotNull
|
||||
val prefixes: Iterable[String], val taskNames: Iterable[String],
|
||||
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}
|
||||
abstract class JLine extends LineReader
|
||||
|
|
@ -91,8 +98,10 @@ object MainCompletor
|
|||
val specific = simpleCompletor(specificPrefix :: Nil) // TODO
|
||||
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 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 baseCompletor = new MultiCompletor(baseCompletors.toArray)
|
||||
|
||||
|
|
|
|||
|
|
@ -310,7 +310,8 @@ class xMain extends xsbti.AppMain
|
|||
lazy val projectNames = baseProject.projectClosure.map(_.name)
|
||||
val prefixes = ContinuousExecutePrefix :: CrossBuildPrefix :: Nil
|
||||
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)
|
||||
val reader = new LazyJLineReader(baseProject.historyPath, MainCompletor(completors), baseProject.log)
|
||||
reader.readLine("> ").getOrElse(ExitCommand)
|
||||
|
|
|
|||
|
|
@ -233,16 +233,21 @@ trait Project extends TaskManager with Dag[Project] with BasicEnvironment
|
|||
def buildScalaInstance = buildScalaInstance0
|
||||
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
|
||||
log.error(e.getMessage)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
private def replace(originalV: String, newV: String) = buildScalaVersions.value.replaceAll("""\b\Q""" + originalV + """\E\b""", newV)
|
||||
def getScalaInstance(version: String) =
|
||||
localScalaInstances.find(_.version == version) getOrElse
|
||||
xsbt.ScalaInstance(version, info.launcher)
|
||||
|
|
@ -407,28 +412,40 @@ object Project
|
|||
}
|
||||
val useName = p.projectName.get.getOrElse("at " + p.info.projectDirectory.getAbsolutePath)
|
||||
checkDependencies(useName, p.info.dependencies, log)
|
||||
p.buildScalaInstance // done so that build Scala version is initialized on project startup
|
||||
p
|
||||
}
|
||||
/** Compiles the project definition classes and returns the project definition class name
|
||||
* 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 }] =
|
||||
{
|
||||
val builderProjectPath = info.builderPath / BuilderProjectDirectoryName
|
||||
if(builderProjectPath.asFile.isDirectory)
|
||||
getProjectBuilder(info, buildLog) match
|
||||
{
|
||||
val pluginProjectPath = info.builderPath / PluginProjectDirectoryName
|
||||
val additionalPaths = info.sbtClasspath
|
||||
val builderInfo = ProjectInfo(builderProjectPath.asFile, Nil, None)(buildLog, info.app, Some(info.definitionScalaVersion))
|
||||
val builderProject = new BuilderProject(builderInfo, pluginProjectPath, additionalPaths, buildLog)
|
||||
builderProject.compile.run.toLeft(()).right.flatMap { ignore =>
|
||||
builderProject.projectDefinition.right.map {
|
||||
case Some(definition) => getProjectClass[Project](definition, builderProject.projectClasspath, getClass.getClassLoader)
|
||||
case None => DefaultBuilderClass
|
||||
}
|
||||
case Some(builder) => buildProjectDefinition(builder)
|
||||
case None => Right(DefaultBuilderClass)
|
||||
}
|
||||
private def buildProjectDefinition(builderProject: BuilderProject): Either[String, Class[P] forSome { type P <: Project }] =
|
||||
builderProject.compile.run.toLeft(()).right.flatMap { ignore =>
|
||||
builderProject.projectDefinition.right.map {
|
||||
case Some(definition) => getProjectClass[Project](definition, builderProject.projectClasspath, getClass.getClassLoader)
|
||||
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
|
||||
Right(DefaultBuilderClass)
|
||||
None
|
||||
}
|
||||
/** Verifies that the given list of project dependencies contains no nulls. The
|
||||
* String argument should be the project name with the dependencies.*/
|
||||
|
|
|
|||
|
|
@ -109,11 +109,8 @@ object Run
|
|||
override def createInterpreter()
|
||||
{
|
||||
val projectLoader = project.getClass.getClassLoader
|
||||
val launcherJar = FileUtilities.classLocationFile[xsbti.Launcher]
|
||||
val app = project.info.app
|
||||
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)
|
||||
val classpath = Project.getProjectClasspath(project)
|
||||
compilerSettings.classpath.value = Path.makeString(classpath.get ++ Path.fromFiles(project.info.app.scalaProvider.jars))
|
||||
project.log.debug(" Compiler classpath: " + compilerSettings.classpath.value)
|
||||
|
||||
in = InteractiveReader.createDefault()
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ trait ScalaProject extends SimpleScalaProject with FileTasks with MultiTaskProje
|
|||
val Private = Value("private")
|
||||
}
|
||||
|
||||
def javapTask(classpath: PathFinder, conditional: CompileConditional, compilePath: Path) =
|
||||
def javapTask(classpath: PathFinder, conditional: => CompileConditional, compilePath: Path) =
|
||||
task { args =>
|
||||
val cp = classpath +++ Path.fromFile(FileUtilities.scalaLibraryJar) +++ Path.fromFile(FileUtilities.scalaCompilerJar)
|
||||
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)
|
||||
|
||||
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) }
|
||||
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) }
|
||||
def scaladocTask(label: String, sources: PathFinder, outputDirectory: Path, classpath: PathFinder, options: ScaladocOption*): Task =
|
||||
scaladocTask(label, sources, outputDirectory, classpath, options)
|
||||
|
|
|
|||
Loading…
Reference in New Issue