mirror of https://github.com/sbt/sbt.git
compile, discover, append commands
This commit is contained in:
parent
ab78c8791a
commit
23bda55124
|
|
@ -88,8 +88,15 @@ ReloadCommand + """
|
|||
"""
|
||||
|
||||
def Multi = ";"
|
||||
def MultiBrief = ("( " + Multi + " command )+", MultiDetailed)
|
||||
def MultiDetailed = "Runs the provided semicolon-separated commands."
|
||||
def MultiBrief = ("( " + Multi + " command )+", "Runs the provided semicolon-separated commands.")
|
||||
def MultiDetailed =
|
||||
Multi + " command1 " + Multi + """ command2 ...
|
||||
Runs the specified commands.
|
||||
"""
|
||||
|
||||
def Append = "append"
|
||||
def AppendLastBrief = (Append + " command", AppendLastDetailed)
|
||||
def AppendLastDetailed = "Appends `command` to list of commands to run."
|
||||
|
||||
val AliasCommand = "alias"
|
||||
def AliasBrief = (AliasCommand, "Adds, removes, or prints command aliases.")
|
||||
|
|
@ -112,6 +119,48 @@ AliasCommand + """ name=
|
|||
Removes the alias for `name`.
|
||||
"""
|
||||
|
||||
def Discover = "discover"
|
||||
def DiscoverBrief = (DiscoverSyntax, "Finds annotated classes and subclasses.")
|
||||
def DiscoverSyntax = Discover + " [-module true|false] [-sub <names>] [-annot <names>]"
|
||||
def DiscoverDetailed =
|
||||
DiscoverSyntax + """
|
||||
|
||||
Looks for public, concrete classes that match the requested query using the current sbt.inc.Analysis instance.
|
||||
|
||||
-module
|
||||
Specifies whether modules (true) or classes (false) are found.
|
||||
The default is classes/traits (false).
|
||||
|
||||
-sub
|
||||
Specifies comma-separated class names.
|
||||
Classes that have one or more of these classes as an ancestor are included in the resulting list.
|
||||
|
||||
-annot
|
||||
Specifies comma-separated annotation names.
|
||||
Classes with one or more of these annotations on the class or one of its non-private methods are included in the resulting list.
|
||||
"""
|
||||
|
||||
def Compile = "compile"
|
||||
def CompileBrief = (CompileSyntax, "Incrementally compiles the provided sources.")
|
||||
def CompileSyntax = Compile + " -src <paths> [-cp <paths>] [-d <path>]"
|
||||
def CompileDetailed =
|
||||
CompileSyntax + """
|
||||
|
||||
Incrementally compiles Scala and Java sources.
|
||||
Java source support is limited at this time.
|
||||
|
||||
<paths> are explicit paths separated by the platform path separator.
|
||||
|
||||
The specified output path will contain the following directory structure:
|
||||
|
||||
scala_<version>/
|
||||
classes/
|
||||
cache/
|
||||
|
||||
Compiled classes will be written to the 'classes' directory.
|
||||
Cached information about the compilation will be written to 'cache'.
|
||||
"""
|
||||
|
||||
def Load = "load"
|
||||
def LoadLabel = "a project"
|
||||
def LoadCommand = "load-commands"
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ object Build
|
|||
case BinaryLoad(classpath, module, name) =>
|
||||
binary(classpath, module, name, loader(configuration), allowMultiple)
|
||||
case SourceLoad(classpath, sourcepath, output, module, auto, name) =>
|
||||
source(classpath, sourcepath, output, module, auto, name, configuration, allowMultiple)._1
|
||||
source(classpath, sourcepath, output, module, auto, name, configuration, allowMultiple)
|
||||
case ProjectLoad(base, auto, name) =>
|
||||
project(base, auto, name, configuration, allowMultiple)._1
|
||||
project(base, auto, name, configuration, allowMultiple)
|
||||
}
|
||||
|
||||
def project(base: File, auto: Auto.Value, name: String, configuration: xsbti.AppConfiguration, allowMultiple: Boolean): Seq[Any] =
|
||||
|
|
@ -48,33 +48,33 @@ object Build
|
|||
}
|
||||
}
|
||||
|
||||
def source(classpath: Seq[File], sources: Seq[File], output: Option[File], module: Boolean, auto: Auto.Value, name: String, configuration: xsbti.AppConfiguration, allowMultiple: Boolean = false): (Seq[Any], Analysis) =
|
||||
def compile(command: CompileCommand, configuration: xsbti.AppConfiguration): Analysis =
|
||||
{
|
||||
import command._
|
||||
compile(classpath, sources, output, options, configuration)
|
||||
}
|
||||
def compile(classpath: Seq[File], sources: Seq[File], output: Option[File], options: Seq[String], configuration: xsbti.AppConfiguration): Analysis =
|
||||
compile(new Compile(classpath, sources, output, options, configuration))
|
||||
|
||||
def compile(conf : Compile): Analysis =
|
||||
{
|
||||
import conf._
|
||||
// TODO: accept Logger as an argument
|
||||
val log = new ConsoleLogger with Logger with sbt.IvyLogger
|
||||
|
||||
val scalaProvider = configuration.provider.scalaProvider
|
||||
val launcher = scalaProvider.launcher
|
||||
val instance = ScalaInstance(scalaProvider.version, launcher)
|
||||
|
||||
val out = output.getOrElse(configuration.baseDirectory / "target" asFile)
|
||||
val target = out / ("scala_" + instance.actualVersion)
|
||||
val outputDirectory = target / "classes"
|
||||
val cacheDirectory = target / "cache"
|
||||
val projectClasspath = outputDirectory.asFile +: classpath
|
||||
val compileClasspath = projectClasspath ++ configuration.provider.mainClasspath.toSeq
|
||||
|
||||
|
||||
val componentManager = new ComponentManager(launcher.globalLock, configuration.provider.components, log)
|
||||
val compiler = new AnalyzingCompiler(instance, componentManager, log)
|
||||
val javac = JavaCompiler.directOrFork(compiler.cp, compiler.scalaInstance)( (args: Seq[String], log: Logger) => Process("javac", args) ! log )
|
||||
|
||||
val agg = new AggressiveCompile(cacheDirectory)
|
||||
val analysis = agg(compiler, javac, sources, compileClasspath, outputDirectory, Nil, Nil)(log)
|
||||
|
||||
agg(compiler, javac, sources, compileClasspath, outputDirectory, Nil, options)(log)
|
||||
}
|
||||
def source(classpath: Seq[File], sources: Seq[File], output: Option[File], module: Boolean, auto: Auto.Value, name: String, configuration: xsbti.AppConfiguration, allowMultiple: Boolean = false): Seq[Any] =
|
||||
{
|
||||
val conf = new Compile(classpath, sources, output, Nil, configuration)
|
||||
val analysis = compile(conf)
|
||||
val discovered = discover(analysis, module, auto, name)
|
||||
val loaded = binaries(projectClasspath, module, check(discovered, allowMultiple), loader(configuration))
|
||||
|
||||
(loaded, analysis)
|
||||
binaries(conf.projectClasspath, module, check(discovered, allowMultiple), loader(configuration))
|
||||
}
|
||||
def discover(analysis: inc.Analysis, module: Boolean, auto: Auto.Value, name: String): Seq[String] =
|
||||
{
|
||||
|
|
@ -85,6 +85,9 @@ object Build
|
|||
case Annotation => discover(analysis, module, new inc.Discovery(Set.empty, Set(name)))
|
||||
}
|
||||
}
|
||||
def discover(analysis: inc.Analysis, command: DiscoverCommand): Seq[String] =
|
||||
discover(analysis, command.module, command.discovery)
|
||||
|
||||
def discover(analysis: inc.Analysis, module: Boolean, discovery: inc.Discovery): Seq[String] =
|
||||
{
|
||||
for(src <- analysis.apis.internal.values.toSeq;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package build
|
||||
|
||||
import inc.Analysis
|
||||
import java.io.File
|
||||
import Path._
|
||||
|
||||
final class Compile(val classpath: Seq[File], val sources: Seq[File], output: Option[File], val options: Seq[String], val configuration: xsbti.AppConfiguration)
|
||||
{
|
||||
val scalaProvider = configuration.provider.scalaProvider
|
||||
val launcher = scalaProvider.launcher
|
||||
val instance = ScalaInstance(scalaProvider.version, launcher)
|
||||
|
||||
val out = output.getOrElse(configuration.baseDirectory / "target" asFile)
|
||||
val target = out / ("scala_" + instance.actualVersion)
|
||||
val outputDirectory = target / "classes"
|
||||
val cacheDirectory = target / "cache"
|
||||
val projectClasspath = outputDirectory.asFile +: classpath
|
||||
val compileClasspath = projectClasspath ++ configuration.provider.mainClasspath.toSeq
|
||||
}
|
||||
final class Compiled(val config: Compile, val analysis: Analysis)
|
||||
|
|
@ -16,3 +16,5 @@ object Auto extends Enumeration
|
|||
val Subclass, Annotation, Explicit = Value
|
||||
}
|
||||
|
||||
final case class CompileCommand(classpath: Seq[File], sources: Seq[File], output: Option[File], options: Seq[String])
|
||||
final case class DiscoverCommand(module: Boolean, discovery: inc.Discovery)
|
||||
|
|
@ -9,7 +9,7 @@ import java.io.File
|
|||
final class ParseException(msg: String) extends RuntimeException(msg)
|
||||
|
||||
/** Parses a load command. The implementation is a quick hack.
|
||||
It is not robust and feedback is not helpful.*/
|
||||
It is not robust and errors are not helpful.*/
|
||||
object Parse
|
||||
{
|
||||
def helpBrief(name: String, label: String): (String, String) = (name + " <options>", "Loads " + label + " according to the specified options.")
|
||||
|
|
@ -44,7 +44,7 @@ The command has the following syntax:
|
|||
def error(msg: String) = throw new ParseException(msg)
|
||||
def apply(commandString: String)(implicit base: File): LoadCommand =
|
||||
{
|
||||
val args = commandString.split("""\s+""").toSeq
|
||||
val args = arguments(commandString)
|
||||
val srcs = sourcepath(args)
|
||||
val nme = name(args)
|
||||
|
||||
|
|
@ -60,6 +60,21 @@ The command has the following syntax:
|
|||
ProjectLoad(proj, auto(args), nme)
|
||||
}
|
||||
|
||||
def arguments(in: String) = in.split("""\s+""").toSeq
|
||||
|
||||
def compile(commandString: String)(implicit base: File): CompileCommand =
|
||||
{
|
||||
val args = arguments(commandString)
|
||||
CompileCommand(classpath(args), sourcepath(args), output(args), Nil)
|
||||
}
|
||||
def discover(commandString: String): DiscoverCommand =
|
||||
{
|
||||
val args = arguments(commandString)
|
||||
val subs = names("sub", args)
|
||||
val annots = names("annot", args)
|
||||
DiscoverCommand(module(args), new inc.Discovery(subs, annots))
|
||||
}
|
||||
|
||||
def auto(args: Seq[String]): Auto.Value =
|
||||
getArg(args, "auto") match {
|
||||
case None => Auto.Explicit
|
||||
|
|
@ -75,6 +90,9 @@ The command has the following syntax:
|
|||
case Some(x) => error("Expected boolean, got '" + x + "'")
|
||||
}
|
||||
|
||||
def names(label: String, args: Seq[String]): Set[String] =
|
||||
getArg(args, label) match { case Some(ns) => ns.split(",").toSet; case None => Set.empty }
|
||||
|
||||
def name(args: Seq[String]): String =
|
||||
getArg(args, "name") getOrElse("")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue