mirror of https://github.com/sbt/sbt.git
remove long obsolete sbt_pending directory left over from 0.7 conversion
This commit is contained in:
parent
77001a4259
commit
cf175612cb
|
|
@ -1,2 +0,0 @@
|
|||
install/project/boot/
|
||||
scripted/project/boot/
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Copyright (c) 2008, 2009, 2010 Steven Blundy, Josh Cough, Nathan Hamblen, Mark Harrah, David MacIver, Mikko Peltonen, Tony Sloane, Seth Tisue, Vesa Vilhonen
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Simple Build Tool (sbt)
|
||||
Copyright 2008, 2009, 2010 Steven Blundy, Josh Cough, Nathan Hamblen, Mark Harrah, David MacIver, Mikko Peltonen, Tony Sloane, Vesa Vilhonen
|
||||
Licensed under BSD-style license (see LICENSE)
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2009 Mark Harrah
|
||||
*/
|
||||
package sbt.extract
|
||||
|
||||
import java.io.{File, InputStream}
|
||||
import java.util.zip.{ZipEntry, ZipFile}
|
||||
|
||||
object Main
|
||||
{
|
||||
lazy val log: Logger = new ConsoleLogger
|
||||
|
||||
def main(args: Array[String])
|
||||
{
|
||||
if( args contains "debug" )
|
||||
log.setLevel(Level.Debug)
|
||||
val result = OpenResource.zipFile.ioOption(FileUtilities.classLocationFile[Install], "processing", log)(process)
|
||||
for(msg <- result)
|
||||
{
|
||||
log.error(msg)
|
||||
System.exit(1)
|
||||
}
|
||||
}
|
||||
private[this] val packedGzip = ".pack.gz"
|
||||
private def isArchive(name: String) = name.endsWith(".gz") || name.endsWith(".zip")
|
||||
private def process(zip: ZipFile) =
|
||||
{
|
||||
val installEntry = zip.getEntry("install")
|
||||
if(installEntry == null)
|
||||
Some("Install commands not found.")
|
||||
else
|
||||
{
|
||||
val jarAndZip = wrap.Wrappers.toList(zip.entries).filter(entry => isArchive(entry.getName)).partition(_.getName.endsWith(packedGzip))
|
||||
jarAndZip match
|
||||
{
|
||||
case (Nil, _)=> Some("sbt loader not found.")
|
||||
case (_, Nil) => Some("Project to extract and build not found.")
|
||||
case (loaderEntry :: _, projectEntry :: _) => extractAndRun(zip, loaderEntry, projectEntry, installEntry)
|
||||
}
|
||||
}
|
||||
}
|
||||
private def extractAndRun(zip: ZipFile, loaderEntry: ZipEntry, projectEntry: ZipEntry, installEntry: ZipEntry) =
|
||||
{
|
||||
val zipResource = OpenResource.zipEntry(zip)
|
||||
|
||||
import FileUtilities.{gunzip, readString, transfer, unzip, writeStream}
|
||||
val directory = new File(".", trimExtension(projectEntry.getName, ".zip"))
|
||||
assume(!directory.exists, "Could not extract project: directory " + projectEntry.getName + " exists.")
|
||||
|
||||
val loaderBaseName = trimExtension(loaderEntry.getName, packedGzip)
|
||||
val loaderFile = new File(directory, loaderBaseName + ".jar")
|
||||
val tempLoaderFile = new File(directory, loaderBaseName + ".pack")
|
||||
|
||||
def extractLoader() =
|
||||
{
|
||||
implicit def fileToPath(f: File) = Path.fromFile(f)
|
||||
val result =
|
||||
writeStream(tempLoaderFile, log) { out => zipResource.ioOption(loaderEntry, "reading", log)(gunzip(_, out, log)) } orElse
|
||||
Pack.unpack(tempLoaderFile, loaderFile, log)
|
||||
FileUtilities.clean(tempLoaderFile :: Nil, true, log)
|
||||
result.toLeft(loaderFile)
|
||||
}
|
||||
|
||||
Control.thread(zipResource.io(installEntry, "reading", log)(readString(_, log))) { installString =>
|
||||
Control.thread(parseInstall(installString)) { install =>
|
||||
zipResource.io(projectEntry, "reading", log)(unzip(_, Path.fromFile(directory), log)).left.toOption orElse
|
||||
Control.thread(extractLoader()) { loaderFile =>
|
||||
run(loaderFile, directory, install)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private def parseInstall(installString: String): Either[String, Install] =
|
||||
{
|
||||
installString.split(separator) match
|
||||
{
|
||||
case Array(allOptions, allActions) =>
|
||||
val options = allOptions.split("""\n""").toList
|
||||
val actions = allActions.split("""\n""").toList
|
||||
Right( Install(options, actions) )
|
||||
case _ => Left("Invalid install script (no separator found)")
|
||||
}
|
||||
}
|
||||
private def filterEmpty(list: List[String]) = list.filter(!_.isEmpty)
|
||||
private def run(loader: File, project: File, install: Install) =
|
||||
{
|
||||
val command = "java" :: "-jar" :: loader.getAbsolutePath :: filterEmpty(install.options) ::: filterEmpty(install.actions)
|
||||
val builder = new java.lang.ProcessBuilder(command.toArray : _*)
|
||||
builder.directory(project)
|
||||
val exitCode = (Process(builder) !<)
|
||||
if(exitCode == 0)
|
||||
None
|
||||
else
|
||||
Some("sbt exited with nonzero exit code: " + exitCode)
|
||||
}
|
||||
private def trimExtension(name: String, ext: String) =
|
||||
{
|
||||
if(name.endsWith(ext))
|
||||
name.substring(0, name.length - ext.length)
|
||||
else
|
||||
name
|
||||
}
|
||||
// keep this in sync with sbt.extract.SelfExtractingProject
|
||||
private def separator = "===================="
|
||||
}
|
||||
private final case class Install(options: List[String], actions: List[String]) extends NotNull
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2009 Mark Harrah
|
||||
*/
|
||||
package sbt.extract
|
||||
|
||||
import java.io.{ByteArrayOutputStream, File}
|
||||
import FileUtilities.{classLocationFile, clean, createTemporaryDirectory, download, transferAndClose, unzip, write, zip}
|
||||
import SelfExtractingProject.{flat, separator}
|
||||
|
||||
trait SelfExtractingProject extends Project
|
||||
{
|
||||
protected def createSelfExtractingJar(actions: List[String], jvmOptions: List[String], projectZip: Path, outputJar: Path): Option[String] =
|
||||
{
|
||||
def jarForClass(name: String) = Path.fromFile(classLocationFile(Class.forName(name)))
|
||||
val loaderJar = jarForClass("xsbti.Launcher")
|
||||
val bytes = new ByteArrayOutputStream
|
||||
transferAndClose(this.getClass.getResourceAsStream("extract.location"), bytes, log) orElse
|
||||
{
|
||||
val extractorJarLocation = bytes.toString("UTF-8")
|
||||
createSelfExtractingJar(actions, jvmOptions, projectZip, loaderJar, extractorJarLocation, outputJar)
|
||||
}
|
||||
}
|
||||
private def createSelfExtractingJar(actions: List[String], jvmOptions: List[String], projectZip: Path, loaderJar: Path, extractorJarLocation: String, outputJar: Path): Option[String] =
|
||||
{
|
||||
val installContents = jvmOptions.mkString("\n") + separator + actions.mkString("\n")
|
||||
withTemporaryDirectory(log) { tmp =>
|
||||
val tmpPath = Path.fromFile(tmp)
|
||||
write(new File(tmp, "install"), installContents, log) orElse
|
||||
unzip(this.getClass.getResource(extractorJarLocation), tmpPath, log).left.toOption orElse
|
||||
Control.thread(compressLoader(loaderJar)) { compressedLoader =>
|
||||
zip( (tmpPath ###) :: flat(projectZip) :: compressedLoader :: Nil, outputJar, true, log)
|
||||
}
|
||||
}
|
||||
}
|
||||
private def withTemporaryDirectory(log: Logger)(f: File => Option[String]) =
|
||||
{
|
||||
Control.thread(createTemporaryDirectory(log)) { dir =>
|
||||
Control.trapUnitAndFinally("", log)
|
||||
{ f(dir) }
|
||||
{ clean(Path.fromFile(dir) :: Nil, true, log) }
|
||||
}
|
||||
}
|
||||
private def compressLoader(loaderJar: Path): Either[String, Path] =
|
||||
{
|
||||
val jarName = loaderJar.asFile.getName
|
||||
val dotIndex = jarName.lastIndexOf('.')
|
||||
val baseName =
|
||||
if(dotIndex > 0) jarName.substring(0, dotIndex)
|
||||
else jarName
|
||||
val packedName = baseName + ".pack"
|
||||
val packed = outputPath / packedName
|
||||
val packedAndGzip = (outputPath ###) / (packedName + ".gz")
|
||||
val result =
|
||||
Pack.pack(loaderJar, packed, log) orElse
|
||||
FileUtilities.gzip(packed, packedAndGzip, log)
|
||||
result.toLeft(packedAndGzip)
|
||||
}
|
||||
}
|
||||
trait BasicSelfExtractingProject extends BasicScalaProject with SelfExtractingProject
|
||||
{
|
||||
def installActions: List[String] = update.name :: `package`.name :: Nil
|
||||
def jvmOptions: List[String] = Nil
|
||||
def selfExtractingJar: Path = outputPath / (artifactBaseName + "-setup.jar")
|
||||
|
||||
lazy val installer = installerAction
|
||||
def installerAction = task { createSelfExtractingJar(installActions, jvmOptions, packageProjectZip, selfExtractingJar) } dependsOn packageProject
|
||||
}
|
||||
|
||||
object SelfExtractingProject
|
||||
{
|
||||
// keep this in sync with sbt.extract.Main.separator
|
||||
def separator = "===================="
|
||||
private def flat(p: Path) =
|
||||
p match
|
||||
{
|
||||
case rp: RelativePath => (rp.parentPath ###) / rp.component
|
||||
case _ => p
|
||||
}
|
||||
}
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Copyright (c) 2008, 2009, 2010 Steven Blundy, Josh Cough, Nathan Hamblen, Mark Harrah, David MacIver, Mikko Peltonen, Tony Sloane, Vesa Vilhonen
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
|
||||
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
### Major Features
|
||||
* Batch and interactive commands are now unifed. All commands that can be executed at the interactive prompt can be run from the command line. To run commands and then enter interactive prompt, make the last command 'shell'.
|
||||
* Scala version handling has been overhauled.
|
||||
* The version of Scala used to run sbt (currently 2.7.7) is decoupled from the version used to build the project
|
||||
* Easily change between Scala versions with `++<version>`
|
||||
* Improved cross-building: project definition is only compiled against 2.7.7 instead of every Scala version cross-built against
|
||||
* Works with Scala 2.8.0.Beta1; however, classpath handling in Scala 2.8 trunk is changing and sbt currently cannot use 2.8 trunk to build projects until this settles
|
||||
* Using a [local version of Scala](http://code.google.com/p/simple-build-tool/wiki/LocalScala) is easier now.
|
||||
* Dependency management improvements:
|
||||
+ `make-pom` task now uses custom pom generation code instead of Ivy's pom writer
|
||||
- Writes Maven-style repositories to the pom by default
|
||||
- Override the 'pomExtra' method to provide XML (scala.xml.NodeSeq) to insert directly into the generated pom
|
||||
+ sbt's [Ivy interface](http://code.google.com/p/simple-build-tool/wiki/IvyInterface) can be used directly (useful for implementing certain tasks)
|
||||
* Test framework support is now done through a [uniform test interface](http://github.com/harrah/test-interface). Implications:
|
||||
+ New versions of specs, ScalaCheck, and ScalaTest are supported as soon as they are released
|
||||
+ Stefan Zeiger has written an [implementation for running JUnit](http://github.com/szeiger/junit-interface)
|
||||
+ Support is better, since the test framework authors are the ones providing the implementation
|
||||
+ Arguments can be passed to the test framework. In the simplest case: `test-only your.test -- -a -b -c`
|
||||
* Generalized the [launcher](http://code.google.com/p/simple-build-tool/wiki/GeneralizedLauncher) to be able to launch Scala applications, not just sbt
|
||||
* Provide a configuration file to the launcher and it can download the application and its dependencies from a repository and run it
|
||||
* sbt's configuration can be customized. For example,
|
||||
* The default values used to create a new project can be changed
|
||||
* The repositories used to fetch sbt and its dependencies, including Scala, can be configured
|
||||
* The location that sbt is retrieved to is configurable. For example, instead of `project/boot`, `/home/user/.ivy2/sbt/`
|
||||
* Configurable method of project searching (previously configurable by system property)
|
||||
|
||||
### Other Improvements
|
||||
* Jetty 7 support (doesn't work with JRebel at this time)
|
||||
* Control traces with 'on' 'off', 'nosbt', `<level>` (Thanks to Tony Sloane.)
|
||||
* New action 'test-run' method that is analogous to 'run', but for test classes.
|
||||
* New action 'clean-plugins' task that clears built plugins (useful for plugin development).
|
||||
* Can provide commands from a file with <file command (file is the name of the file to read from)
|
||||
* Can provide commands over loopback interface with <port command (port is the number to read commands from)
|
||||
* Launcher is allowed in root directory or `lib/` directory (jar name must match '*sbt-launch*.jar' and will be kept off classpath by default)
|
||||
* Compilation properly tracks certain types of synthetic classes (for comprehension with >30 clauses, for example)
|
||||
* Can provide custom task start and end delimiters by defining the system properties `sbt.start.delimiter` and `sbt.end.delimiter`
|
||||
|
||||
### Migrating from 0.5.6
|
||||
* Get the 0.7.0 launcher and [set it up as usual](http://code.google.com/p/simple-build-tool/wiki/Setup)
|
||||
* In your `project/build.properties`
|
||||
* Rename `scala.version`to `build.scala.versions`. If you previously overrode `crossScalaVersions`, just put the versions in `build.scala.versions` separated by whitespace.
|
||||
* Set `sbt.version` to 0.7.0
|
||||
* Check the compatibility section below
|
||||
|
||||
### Compatibility with 0.5.6
|
||||
* Artifact IDs (like your project's jar and ID for publishing to repositories) and output paths (like `target/` and `lib_managed/`) now have _<scala.version> appended. To keep the old way, `override def disableCrossPaths = true`.
|
||||
* 'reboot' is gone, 'reload' now covers 'reboot'
|
||||
* [Properties](http://code.google.com/p/simple-build-tool/wiki/Properties) need to be declared `lazy val` instead of just `val`.
|
||||
* The way to fork `run` has changed due to reworking the Scala version handling. See [Forking](http://code.google.com/p/simple-build-tool/wiki/Forking) for details. Forking the compiler is no longer supported.
|
||||
* The project definition is always compiled against the version of Scala running sbt (currently, 2.7.7). It was previously the same as the version used to build the project.
|
||||
* The Ivy interface has been broken out into its own subproject and reworked. All functional tests pass, but please report any issues you encounter.
|
||||
* `updateOptions` has been replaced by overriding the appropriate methods directly. Some other advanced configuration options have changed- documentation pending.
|
||||
* Web application support was reworked. Please report any issues you encounter.
|
||||
* Test framework support is now done through the uniform test interface. If you manually manage your test dependencies, you will need the [test-compat implementation](http://github.com/harrah/test-compat) of this interface. The earliest releases of test frameworks supported are:
|
||||
+ specs: 1.6.1
|
||||
+ ScalaCheck: 1.5
|
||||
+ ScalaTest: 1.0
|
||||
|
||||
### Other Notes
|
||||
* A message like `'compiler-interface' not compiled for '2.7.7'` is sbt adapting to your build Scala version (and Java version). It takes 5-20s depending on your machine and is a one time compilation for a given Scala/Java version combination.
|
||||
* Version control is now done with git and the source code is hosted on [Github](http://github.com/harrah). See the [instructions](http://code.google.com/p/simple-build-tool/wiki/Build) for building it locally. [Issue tracking](http://code.google.com/p/simple-build-tool/issues/list) and [documentation](http://code.google.com/p/simple-build-tool/wiki/DocumentationHome) are still on [Google Code](http://code.google.com/p/simple-build-tool).
|
||||
* Reports of performance degradation or improvement in 0.7.0 are useful.
|
||||
* Regular documentation has been updated. API Documentation is pending.
|
||||
* Now using the [posterous-sbt plugin](http://github.com/n8han/posterous-sbt) to generate and publish release notes to [http://implicit.ly/](http://implicit.ly/).
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
### Fixes
|
||||
* Fixed Jetty 7 support to work with JRebel
|
||||
* Fixed make-pom to generate valid repositories section
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
### Fixes
|
||||
* `Process.apply` no longer uses `CommandParser`. This should fix issues with the android-plugin.
|
||||
* Arguments are passed to javac using an argument file (@). This should fix errors on Windows caused by long command lines.
|
||||
* Fixed `console-project` for custom subprojects
|
||||
* Works with Scala 2.8 trunk again.
|
||||
* [API Documentation](http://simple-build-tool.googlecode.com/svn/artifacts/latest/api/index.html) is up again.
|
||||
* Fixed logging level behavior on subprojects.
|
||||
|
||||
### Improvements
|
||||
* Added `sbt.impl.Arguments` for parsing a command like a normal action (for [Processors](http://code.google.com/p/simple-build-tool/wiki/Processors))
|
||||
* `Processor` split into `Processor`/`BasicProcessor`. `Processor` provides a high level of integration with command processing. `BasicProcessor` operates on a `Project` but does not affect command processing. See the [API documentation](http://simple-build-tool.googlecode.com/svn/artifacts/latest/api/sbt/processor$package.html) for the signature change.
|
||||
* Can now use Launcher externally, including launching sbt outside of the official jar. This means a `Project` can now be created from tests.
|
||||
* Added some String generation methods to `PathFinder`: `toString` for debugging and `absString` and `relativeString` for joining the absolute (relative) paths by the platform separator.
|
||||
* All sbt code is now in a [single github repository](http://github.com/harrah/xsbt). Instructions for building from source have been updated.
|
||||
* Added `webappUnmanaged: PathFinder` method to `DefaultWebProject`. `Path`s selected by this `PathFinder` will not be pruned by `prepare-webapp` and will not be packaged by package. For example, to exclude the GAE datastore directory:
|
||||
|
||||
override def webappUnmanaged = (temporaryWarPath / "WEB-INF" / "appengine-generated" ***)
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
### Fixes
|
||||
* Fixed issue with scala.library.jar not being on javac's classpath.
|
||||
* Fixed buffered logging for parallel execution.
|
||||
* Fixed test-* tab completion being permanently set on first completion.
|
||||
* Works with Scala 2.8 trunk again (including the latest 2.8.0-SNAPSHOT).
|
||||
* The latest launcher should fix issues with retrieving Scala 2.8.0-SNAPSHOT versions.
|
||||
* [sxr sources](http://simple-build-tool.googlecode.com/svn/artifacts/latest/sxr/index.html)
|
||||
* Maven local repository excluded when the Scala version is a snapshot. This should fix issues with out of date Scala snapshots.
|
||||
|
||||
### Improvements
|
||||
* Merged Seth's patch to invoke `javac` in the same jvm when `tools.jar` is on the classpath. Macs include `tools.jar` by default, Linux and Windows users would need to add it to their sbt startup script or explicitly add it to `compileClasspath`.
|
||||
* The compiler interface is precompiled against common Scala versions (for this release, 2.7.7 and 2.8.0.Beta1).
|
||||
* There have been some new methods added to `Path` and `PathFinder` recently, such as [PathFinder.distinct](http://simple-build-tool.googlecode.com/svn/artifacts/latest/api/sbt/PathFinder.html#distinct)
|
||||
* Running multiple commands at once at the interactive prompt is now supported. Prefix each command with ';'.
|
||||
* Run and return the output of a process as a String with `!!` or as a (blocking) `Stream[String]` with `lines`.
|
||||
|
||||
### New Feature
|
||||
* Java tests + Annotation detection
|
||||
* Test frameworks can now specify annotation fingerprints. Specify the names of annotations and sbt discovers classes with the annotations on it or one of its methods. Use version 0.5 of the [test-interface](http://github.com/harrah/test-interface).
|
||||
* Detect subclasses and annotations in Java sources (really, their class files).
|
||||
|
||||
### Compatibility
|
||||
This section is important for users that work with the `TestDefinition`, `AnalysisCallback`, or `CompileConfiguration` classes in sbt.
|
||||
|
||||
* Discovered is new root of hierarchy representing discovered subclasses + annotations. `TestDefinition` no longer fulfills this role.
|
||||
* `TestDefinition` is modified to be name+`Fingerprint` and represents a runnable test. It need not be `Discovered` and could be file-based in the future, for example.
|
||||
* Replaced testDefinitionClassNames method with `fingerprints` in `CompileConfiguration`.
|
||||
* Added foundAnnotation to `AnalysisCallback`.
|
||||
* Added `Runner2`, `Fingerprint`, `AnnotationFingerprint`, and `SubclassFingerprint` to the [test-interface](http://github.com/harrah/test-interface). Existing test frameworks should still work. Implement `Runner2` to use fingerprints other than `SubclassFingerprint`.
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
### Fixes
|
||||
* Fixed issue with using 2.8.0.RC1 (or later) compiler in tests.
|
||||
* Fix `FileUtilities.unzip` to be tail-recursive again.
|
||||
* Honor `-Xfatal-warnings` option added to compiler in 2.8.0.RC2.
|
||||
* Derive Java source file from name of class file when no SourceFile attribute is present in the class file. Improves tracking when -g:none option is used.
|
||||
* Properly support sftp/ssh repositories using key-based authentication. See the updated section of the [Resolvers](http://code.google.com/p/simple-build-tool/wiki/Resolvers#SFTP_and_SSH_Repositories) page.
|
||||
|
||||
### Improvements
|
||||
* Prefix continuous compilation with the run number. This useful when the logging level is 'warn', for example.
|
||||
* Added `pomRepositoryFilter(repo: MavenRepository): Boolean` that can be overridden to exclude repositories from the pom generated by `make-pom`
|
||||
* Added `pomPostProcess(pom: Node): Node` to make advanced manipulation of the default pom easier (`pomExtra` already covers basic cases).
|
||||
* Added `reset` command to reset JLine terminal. This needs to be run after suspending and then resuming sbt.
|
||||
* More accurate detection of invalid test names. Invalid test names now generate an error and prevent the test action from running instead of just logging a warning.
|
||||
* Precompile compiler interface against 2.8.0.RC2
|
||||
* Add `consoleOptions` for specifying options to the console. It defaults to `compileOptions`.
|
||||
* New section in launcher configuration `[ivy]` with a single label `cache-directory`. Specify this to change the cache location used by the launcher.
|
||||
* Added method `ivyUpdateLogging` to control logging level when running `update`. Override it to be `UpdateLogging.DownloadOnly, Full, or Quiet`. The default is `DownloadOnly`. `Full` will log metadata resolution and provide a final summary. `Quiet` only logs problems.
|
||||
* Make `scaladocTask` a `fileTask` so that it runs only when `index.html` is older than some input source.
|
||||
* Sort input source files for consistency, addressing scalac's issues with source file ordering.
|
||||
* `offline` property for disabling checking for newer dynamic revisions (like `-SNAPSHOT`). This allows working offline with remote snapshots. Not honored for plugins yet.
|
||||
|
||||
### New Feature
|
||||
* Commands for working with history. Run `!` to see history command help.
|
||||
|
||||
### Compatibility
|
||||
* Plugins can now only be Scala sources. BND should be usable in a plugin now.
|
||||
|
|
@ -1 +0,0 @@
|
|||
[Simple Build Tool](http://code.google.com/p/simple-build-tool/) is a build tool for Scala projects that aims to do the basics well.
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah, David MacIver, Josh Cough
|
||||
*/
|
||||
package sbt
|
||||
|
||||
/** The default project when no project is explicitly configured and the common base class for
|
||||
* configuring a project.*/
|
||||
class DefaultProject(val info: ProjectInfo) extends BasicScalaProject with MavenStyleScalaPaths
|
||||
class DefaultWebProject(val info: ProjectInfo) extends BasicWebScalaProject with MavenStyleWebScalaPaths
|
||||
|
||||
|
||||
import BasicScalaProject._
|
||||
import ScalaProject.{optionsAsString, javaOptionsAsString}
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.util.jar.Attributes
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
/** This class defines concrete instances of actions from ScalaProject using overridable paths,
|
||||
* options, and configuration. */
|
||||
abstract class BasicScalaProject extends ScalaProject with BasicDependencyProject with ScalaPaths
|
||||
{
|
||||
/** The options provided to the 'doc' and 'docTest' actions.*/
|
||||
def documentOptions: Seq[ScaladocOption] =
|
||||
documentTitle(name + " " + version + " API") ::
|
||||
(if(isScala27) only27Options else Nil)
|
||||
private def only27Options =
|
||||
windowTitle(name + " " + version + " API") :: Nil
|
||||
/** The options provided to the 'test' action..*/
|
||||
def testOptions: Seq[TestOption] =
|
||||
TestListeners(testListeners) ::
|
||||
TestFilter(includeTest) ::
|
||||
Nil
|
||||
|
||||
private def succeededTestPath = testAnalysisPath / "succeeded-tests"
|
||||
protected final def quickOptions(failedOnly: Boolean) =
|
||||
{
|
||||
val path = succeededTestPath
|
||||
val analysis = testCompileConditional.analysis
|
||||
TestFilter(new impl.TestQuickFilter(analysis, failedOnly, path, log)) :: TestListeners(new impl.TestStatusReporter(path, log) :: Nil) :: Nil
|
||||
}
|
||||
|
||||
|
||||
protected def testAction = defaultTestTask(testOptions)
|
||||
protected def testOnlyAction = testOnlyTask(testOptions)
|
||||
protected def testOnlyTask(testOptions: => Seq[TestOption]) = testQuickMethod(testCompileConditional.analysis, testOptions)(o => defaultTestTask(o)) describedAs (TestOnlyDescription)
|
||||
protected def testQuickAction = defaultTestQuickMethod(false, testOptions) describedAs (TestQuickDescription)
|
||||
protected def testFailedAction = defaultTestQuickMethod(true, testOptions) describedAs (TestFailedDescription)
|
||||
protected def defaultTestQuickMethod(failedOnly: Boolean, testOptions: => Seq[TestOption]) =
|
||||
testQuickMethod(testCompileConditional.analysis, testOptions)(options => defaultTestTask(quickOptions(failedOnly) ::: options.toList))
|
||||
protected def defaultTestTask(testOptions: => Seq[TestOption]) =
|
||||
testTask(testFrameworks, testClasspath, testCompileConditional.analysis, testOptions).dependsOn(testCompile, copyResources, copyTestResources) describedAs TestDescription
|
||||
|
||||
protected def docAllAction = (doc && docTest) describedAs DocAllDescription
|
||||
protected def packageAllAction = task { None} dependsOn(`package`, packageTest, packageSrc, packageTestSrc, packageDocs) describedAs PackageAllDescription
|
||||
protected def graphSourcesAction = graphSourcesTask(graphSourcesPath, mainSourceRoots, mainCompileConditional.analysis).dependsOn(compile)
|
||||
protected def graphPackagesAction = graphPackagesTask(graphPackagesPath, mainSourceRoots, mainCompileConditional.analysis).dependsOn(compile)
|
||||
protected def incrementVersionAction = task { incrementVersionNumber(); None } describedAs IncrementVersionDescription
|
||||
|
||||
lazy val javap = javapTask(runClasspath, mainCompileConditional, mainCompilePath)
|
||||
lazy val testJavap = javapTask(testClasspath, testCompileConditional, testCompilePath)
|
||||
|
||||
}
|
||||
abstract class BasicWebScalaProject extends BasicScalaProject with WebScalaProject with WebScalaPaths
|
||||
{ p =>
|
||||
import BasicWebScalaProject._
|
||||
override def watchPaths = super.watchPaths +++ webappResources
|
||||
|
||||
/** Override this to define paths that `prepare-webapp` and `package` should ignore.
|
||||
* They will not be pruned by prepare-webapp and will not be included in the war.*/
|
||||
def webappUnmanaged: PathFinder = Path.emptyPathFinder
|
||||
|
||||
lazy val prepareWebapp = prepareWebappAction
|
||||
protected def prepareWebappAction =
|
||||
prepareWebappTask(webappResources, temporaryWarPath, webappClasspath, mainDependencies.scalaJars, webappUnmanaged) dependsOn(compile, copyResources)
|
||||
|
||||
lazy val jettyInstance = new JettyRunner(jettyConfiguration)
|
||||
|
||||
def jettyConfiguration: JettyConfiguration =
|
||||
new DefaultJettyConfiguration
|
||||
{
|
||||
def classpath = jettyRunClasspath
|
||||
def jettyClasspath = p.jettyClasspath
|
||||
def war = jettyWebappPath
|
||||
def contextPath = jettyContextPath
|
||||
def classpathName = "test"
|
||||
def parentLoader = buildScalaInstance.loader
|
||||
def scanDirectories = Path.getFiles(p.scanDirectories).toSeq
|
||||
def scanInterval = p.scanInterval
|
||||
def port = jettyPort
|
||||
def log = p.log
|
||||
def jettyEnv = jettyEnvXml
|
||||
def webDefaultXml = jettyWebDefaultXml
|
||||
}
|
||||
/** This is the classpath used to determine what classes, resources, and jars to put in the war file.*/
|
||||
def webappClasspath = publicClasspath
|
||||
/** This is the classpath containing Jetty.*/
|
||||
def jettyClasspath = testClasspath --- jettyRunClasspath
|
||||
/** This is the classpath containing the web application.*/
|
||||
def jettyRunClasspath = publicClasspath
|
||||
def jettyWebappPath = temporaryWarPath
|
||||
lazy val jettyRun = jettyRunAction
|
||||
lazy val jetty = task { idle() } dependsOn(jettyRun) describedAs(JettyDescription)
|
||||
protected def jettyRunAction = jettyRunTask(jettyInstance) dependsOn(prepareWebapp) describedAs(JettyRunDescription)
|
||||
private def idle() =
|
||||
{
|
||||
log.info("Waiting... (press any key to interrupt)")
|
||||
def doWait()
|
||||
{
|
||||
try { Thread.sleep(1000) } catch { case _: InterruptedException => () }
|
||||
if(System.in.available() <= 0)
|
||||
doWait()
|
||||
}
|
||||
doWait()
|
||||
while (System.in.available() > 0) System.in.read()
|
||||
None
|
||||
}
|
||||
|
||||
/** The directories that should be watched to determine if the web application needs to be reloaded..*/
|
||||
def scanDirectories: Seq[Path] = jettyWebappPath :: Nil
|
||||
/** The time in seconds between scans that check whether the web application should be reloaded.*/
|
||||
def scanInterval: Int = JettyRunner.DefaultScanInterval
|
||||
/** The port that Jetty runs on. */
|
||||
def jettyPort: Int = JettyRunner.DefaultPort
|
||||
|
||||
def jettyEnvXml : Option[File] = None
|
||||
def jettyWebDefaultXml : Option[File] = None
|
||||
|
||||
lazy val jettyReload = task { jettyInstance.reload(); None } describedAs(JettyReloadDescription)
|
||||
lazy val jettyRestart = jettyStop && jettyRun
|
||||
lazy val jettyStop = jettyStopAction
|
||||
protected def jettyStopAction = jettyStopTask(jettyInstance) describedAs(JettyStopDescription)
|
||||
|
||||
/** The clean action for a web project is modified so that it first stops jetty if it is running,
|
||||
* since the webapp directory will be removed by the clean.*/
|
||||
override def cleanAction = super.cleanAction dependsOn jettyStop
|
||||
|
||||
/** Redefine the `package` action to make a war file.*/
|
||||
override protected def packageAction = packageWarAction(temporaryWarPath, webappUnmanaged, warPath, Nil) dependsOn(prepareWebapp) describedAs PackageWarDescription
|
||||
|
||||
/** Redefine the default main artifact to be a war file.*/
|
||||
override protected def defaultMainArtifact = Artifact(artifactID, "war", "war")
|
||||
}
|
||||
|
||||
object BasicScalaProject
|
||||
{
|
||||
val CleanDescription =
|
||||
"Deletes all generated files (the target directory)."
|
||||
val MainCompileDescription =
|
||||
"Compiles main sources."
|
||||
val TestCompileDescription =
|
||||
"Compiles test sources."
|
||||
val TestDescription =
|
||||
"Runs all tests detected during compilation."
|
||||
val TestOnlyDescription =
|
||||
"Runs the tests provided as arguments."
|
||||
val TestFailedDescription =
|
||||
"Runs the tests provided as arguments if they have not succeeded."
|
||||
val TestQuickDescription =
|
||||
"Runs the tests provided as arguments if they have not succeeded or their dependencies changed."
|
||||
val DocDescription =
|
||||
"Generates API documentation for main Scala source files using scaladoc."
|
||||
val TestDocDescription =
|
||||
"Generates API documentation for test Scala source files using scaladoc."
|
||||
val RunDescription =
|
||||
"Runs the main class for the project with the provided arguments."
|
||||
val TestRunDescription =
|
||||
"Runs a test class with a main method with the provided arguments."
|
||||
val ConsoleDescription =
|
||||
"Starts the Scala interpreter with the project classes on the classpath."
|
||||
val ConsoleQuickDescription =
|
||||
"Starts the Scala interpreter with the project classes on the classpath without running compile first."
|
||||
val PackageDescription =
|
||||
"Creates a jar file containing main classes and resources."
|
||||
val TestPackageDescription =
|
||||
"Creates a jar file containing test classes and resources."
|
||||
val DocPackageDescription =
|
||||
"Creates a jar file containing generated API documentation."
|
||||
val SourcePackageDescription =
|
||||
"Creates a jar file containing all main source files and resources."
|
||||
val TestSourcePackageDescription =
|
||||
"Creates a jar file containing all test source files and resources."
|
||||
val ProjectPackageDescription =
|
||||
"Creates a zip file containing the entire project, excluding generated files."
|
||||
val PackageAllDescription =
|
||||
"Executes all package tasks except package-project."
|
||||
val DocAllDescription =
|
||||
"Generates both main and test documentation."
|
||||
val IncrementVersionDescription =
|
||||
"Increments the micro part of the version (the third number) by one. (This is only valid for versions of the form #.#.#-*)"
|
||||
val ReleaseDescription =
|
||||
"Compiles, tests, generates documentation, packages, and increments the version."
|
||||
val CopyResourcesDescription =
|
||||
"Copies resources to the target directory where they can be included on classpaths."
|
||||
val CopyTestResourcesDescription =
|
||||
"Copies test resources to the target directory where they can be included on the test classpath."
|
||||
|
||||
private def warnMultipleMainClasses(log: Logger) =
|
||||
{
|
||||
log.warn("No Main-Class attribute will be added automatically added:")
|
||||
log.warn("Multiple classes with a main method were detected. Specify main class explicitly with:")
|
||||
log.warn(" override def mainClass = Some(\"className\")")
|
||||
}
|
||||
}
|
||||
object BasicWebScalaProject
|
||||
{
|
||||
val PackageWarDescription =
|
||||
"Creates a war file."
|
||||
val JettyStopDescription =
|
||||
"Stops the Jetty server that was started with the jetty-run action."
|
||||
val JettyRunDescription =
|
||||
"Starts the Jetty server and serves this project as a web application."
|
||||
val JettyDescription =
|
||||
"Starts the Jetty server and serves this project as a web application. Waits until interrupted, so it is suitable to call this batch-style."
|
||||
val JettyReloadDescription =
|
||||
"Forces a reload of a web application running in a Jetty server started by 'jetty-run'. Does nothing if Jetty is not running."
|
||||
}
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah, David MacIver, Josh Cough
|
||||
*/
|
||||
package sbt
|
||||
|
||||
import FileUtilities._
|
||||
import java.io.File
|
||||
import java.util.jar.{Attributes, Manifest}
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
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) }
|
||||
} completeWith(classNames(conditional, compilePath))
|
||||
private def classNames(conditional: CompileConditional, compilePath: Path) =
|
||||
{
|
||||
val classes = conditional.analysis.allProducts.flatMap(path => Path.relativize(compilePath.asFile, path.asFile))
|
||||
classes.map(_.replace(java.io.File.separatorChar, '.').toList.dropRight(".class".length).mkString).toSeq
|
||||
}
|
||||
|
||||
def syncPathsTask(sources: PathFinder, destinationDirectory: Path): Task =
|
||||
task { FileUtilities.syncPaths(sources, destinationDirectory, log) }
|
||||
def syncTask(sourceDirectory: Path, destinationDirectory: Path): Task =
|
||||
task { FileUtilities.sync(sourceDirectory, destinationDirectory, log) }
|
||||
def copyTask(sources: PathFinder, destinationDirectory: Path): Task =
|
||||
task { FileUtilities.copy(sources.get, destinationDirectory, log).left.toOption }
|
||||
|
||||
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 =
|
||||
task { DotGraph.packages(analysis, outputDirectory, roots.get, log) }
|
||||
|
||||
def zipTask(sources: PathFinder, outputDirectory: Path, zipName: => String): Task =
|
||||
zipTask(sources, outputDirectory / zipName)
|
||||
def zipTask(sources: PathFinder, zipPath: => Path): Task =
|
||||
fileTask("zip", zipPath from sources) { FileUtilities.zip(sources.get, zipPath, false, log) }
|
||||
def incrementVersionNumber()
|
||||
|
||||
protected def testQuickMethod(testAnalysis: CompileAnalysis, options: => Seq[TestOption])(toRun: (Seq[TestOption]) => Task) = {
|
||||
def analysis = Set() ++ testAnalysis.allTests.map(_.className)
|
||||
multiTask(analysis.toList) { (args, includeFunction) =>
|
||||
toRun(TestArgument(args:_*) :: TestFilter(includeFunction) :: options.toList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait WebScalaProject extends ScalaProject
|
||||
{
|
||||
protected def packageWarAction(stagedWarPath: Path, ignore: PathFinder, outputWarPath: => Path, options: => Seq[PackageOption]): Task =
|
||||
packageTask(descendents(stagedWarPath ###, "*") --- ignore, outputWarPath, options)
|
||||
|
||||
@deprecated protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: => Iterable[File]): Task =
|
||||
prepareWebappTask(webappContents, warPath, classpath, Path.finder(extraJars))
|
||||
protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: PathFinder): Task =
|
||||
prepareWebappTask(webappContents, warPath, classpath, extraJars, Path.emptyPathFinder)
|
||||
protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: PathFinder, ignore: PathFinder): Task =
|
||||
task
|
||||
{
|
||||
val webInfPath = warPath / "WEB-INF"
|
||||
val webLibDirectory = webInfPath / "lib"
|
||||
val classesTargetDirectory = webInfPath / "classes"
|
||||
|
||||
val (libs, directories) = classpath.get.toList.partition(ClasspathUtilities.isArchive)
|
||||
val classesAndResources = descendents(Path.lazyPathFinder(directories) ###, "*")
|
||||
if(log.atLevel(Level.Debug))
|
||||
directories.foreach(d => log.debug(" Copying the contents of directory " + d + " to " + classesTargetDirectory))
|
||||
|
||||
import FileUtilities.{copy, copyFlat, copyFilesFlat, clean}
|
||||
(copy(webappContents.get, warPath, log).right flatMap { copiedWebapp =>
|
||||
copy(classesAndResources.get, classesTargetDirectory, log).right flatMap { copiedClasses =>
|
||||
copyFlat(libs, webLibDirectory, log).right flatMap { copiedLibs =>
|
||||
copyFilesFlat(extraJars.getFiles, webLibDirectory, log).right flatMap { copiedExtraLibs =>
|
||||
{
|
||||
val toRemove = scala.collection.mutable.HashSet(((warPath ** "*") --- ignore).get.toSeq : _*)
|
||||
toRemove --= copiedWebapp
|
||||
toRemove --= copiedClasses
|
||||
toRemove --= copiedLibs
|
||||
toRemove --= copiedExtraLibs
|
||||
val (directories, files) = toRemove.toList.partition(_.isDirectory)
|
||||
if(log.atLevel(Level.Debug))
|
||||
files.foreach(r => log.debug("Pruning file " + r))
|
||||
val result =
|
||||
clean(files, true, log) orElse
|
||||
{
|
||||
val emptyDirectories = directories.filter(directory => directory.asFile.listFiles.isEmpty)
|
||||
if(log.atLevel(Level.Debug))
|
||||
emptyDirectories.foreach(r => log.debug("Pruning directory " + r))
|
||||
clean(emptyDirectories, true, log)
|
||||
}
|
||||
result.toLeft(())
|
||||
}
|
||||
}}}}).left.toOption
|
||||
}
|
||||
def jettyRunTask(jettyRun: JettyRunner) = task { jettyRun() }
|
||||
def jettyStopTask(jettyRun: JettyRunner) = task { jettyRun.stop(); None }
|
||||
}
|
||||
object ScalaProject
|
||||
{
|
||||
val DefaultMaximumCompileErrors = 100
|
||||
val AnalysisDirectoryName = "analysis"
|
||||
val MainClassKey = "Main-Class"
|
||||
val TestResourcesProperty = "sbt.test.resources"
|
||||
def optionsAsString(options: Seq[ScalaProject#CompileOption]) = options.map(_.asString).filter(!_.isEmpty)
|
||||
def javaOptionsAsString(options: Seq[ScalaProject#JavaCompileOption]) = options.map(_.asString)
|
||||
}
|
||||
final class TestSetupException(msg: String) extends RuntimeException(msg)
|
||||
trait MultiTaskProject extends Project
|
||||
{
|
||||
def multiTask(allTests: => List[String])(run: (Seq[String], String => Boolean) => Task): MethodTask = {
|
||||
|
||||
task { tests =>
|
||||
|
||||
val (testNames, separatorAndArgs) = tests.toList.span(! _.startsWith("--"))
|
||||
val testArgs = separatorAndArgs.drop(1)
|
||||
|
||||
def filterInclude =
|
||||
{
|
||||
lazy val (exactFilters, testFilters) = testNames.toList.map(GlobFilter.apply).partition(_.isInstanceOf[ExactFilter])
|
||||
lazy val includeTests = exactFilters.map(_.asInstanceOf[ExactFilter].matchName)
|
||||
def checkExistence() =
|
||||
{
|
||||
val toCheck = Set() ++ includeTests -- allTests
|
||||
|
||||
if(!toCheck.isEmpty)
|
||||
{
|
||||
log.error("Test(s) not found:")
|
||||
toCheck.foreach(test => log.error("\t" + test))
|
||||
throw new TestSetupException("Invalid test name(s): " + toCheck.mkString(", "))
|
||||
}
|
||||
}
|
||||
lazy val includeTestsSet =
|
||||
{
|
||||
checkExistence()
|
||||
Set(includeTests: _*)
|
||||
}
|
||||
(test: String) => includeTestsSet.contains(test) || testFilters.exists(_.accept(test))
|
||||
}
|
||||
|
||||
val includeFunction =
|
||||
if(testNames.isEmpty)
|
||||
(test: String) => true
|
||||
else
|
||||
filterInclude
|
||||
run(testArgs, includeFunction)
|
||||
} completeWith allTests
|
||||
}
|
||||
}
|
||||
trait ExecProject extends Project
|
||||
{
|
||||
def execOut(p: => ProcessBuilder) =
|
||||
task
|
||||
{
|
||||
val exitValue = (p !)
|
||||
if(exitValue == 0)
|
||||
None
|
||||
else
|
||||
Some("Nonzero exit value: " + exitValue)
|
||||
}
|
||||
def execTask(buildCommand: => ProcessBuilder): Task =
|
||||
task
|
||||
{
|
||||
val command = buildCommand
|
||||
log.debug("Executing command " + command)
|
||||
val exitValue = command.run(log).exitValue() // don't buffer output
|
||||
if(exitValue == 0)
|
||||
None
|
||||
else
|
||||
Some("Nonzero exit value: " + exitValue)
|
||||
}
|
||||
}
|
||||
trait Exec extends SimpleScalaProject
|
||||
{
|
||||
lazy val sh = task { args => execOut { Process("sh" :: "-c" :: args.mkString(" ") :: Nil) } }
|
||||
lazy val exec = task { args => execOut { Process(args) } }
|
||||
}
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2009 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import scala.xml.{Elem, NodeSeq}
|
||||
import Control._
|
||||
|
||||
/** Defines the configurable parameters for the webstart task. */
|
||||
trait WebstartOptions extends NotNull
|
||||
{
|
||||
/** The main jar to use for webstart.*/
|
||||
def webstartMainJar: Path
|
||||
/** The location to put all generated files for webstart.*/
|
||||
def webstartOutputDirectory: Path
|
||||
/** Generates the .jnlp file using the provided resource descriptions. Each resource description
|
||||
* provides the path of the jar relative to 'webstartOutputDirectory' and whether or not
|
||||
* it is the main jar.*/
|
||||
def jnlpXML(jars: Seq[WebstartJarResource]): Elem
|
||||
/** The location to write the .jnlp file to. It must be in 'webstartOutputDirectory'.*/
|
||||
def jnlpFile: Path
|
||||
/** The location to put all jars that are not the main jar. It must be in 'webstartOutputDirectory'.*/
|
||||
def webstartLibDirectory: Path
|
||||
/** The libraries needed for webstart. Note that only jars are used; directories are discarded.*/
|
||||
def webstartLibraries: PathFinder
|
||||
/** Libraries external to the project needed for webstart. This is mainly for scala libraries.*/
|
||||
def webstartExtraLibraries: PathFinder
|
||||
/** Resources to copy to the webstart output directory.*/
|
||||
def webstartResources: PathFinder
|
||||
/** If defined, this specifies where to create a zip of the webstart output directory. It cannot be
|
||||
* in the output directory.*/
|
||||
def webstartZip: Option[Path]
|
||||
|
||||
/** If defined, configures signing of jars. All jars (main and libraries) are signed using
|
||||
* this configuration.*/
|
||||
def webstartSignConfiguration: Option[SignConfiguration]
|
||||
/** If true, pack200 compression is applied to all jars (main and libraries). A version of each jar
|
||||
* without pack200 compression is still created in the webstart output directory.*/
|
||||
def webstartPack200: Boolean
|
||||
/** If true, gzip compression will be applied to all jars. If pack200 compression is enabled,
|
||||
* gzip compression is also applied to the archives with pack200 compression. A version of
|
||||
* each file without gzip compression is still created in the webstart output directory. */
|
||||
def webstartGzip: Boolean
|
||||
}
|
||||
/** Represents a library included in the webstart distribution. Name is the filename of the jar.
|
||||
* href is the path of the jar relative to the webstart output directory. isMain is true only for
|
||||
* the main jar. */
|
||||
final class WebstartJarResource(val name: String, val href: String, val isMain: Boolean) extends NotNull
|
||||
/** Configuration for signing jars. */
|
||||
final class SignConfiguration(val alias: String, val options: Seq[SignJar.SignOption]) extends NotNull
|
||||
/** A scala project that produces a webstart distribution. */
|
||||
trait WebstartScalaProject extends ScalaProject
|
||||
{
|
||||
import WebstartScalaProject._
|
||||
/** Creates a task that produces a webstart distribution using the given options.*/
|
||||
def webstartTask(options: WebstartOptions) =
|
||||
task
|
||||
{
|
||||
import options._
|
||||
FileUtilities.createDirectories(webstartOutputDirectory :: webstartLibDirectory :: Nil, log) // ignore errors
|
||||
verifyOptions(options)
|
||||
|
||||
def relativize(jar: Path) = Path.relativize(webstartOutputDirectory ###, jar) getOrElse
|
||||
error("Jar (" + jar + ") was not in webstart output directory (" + webstartOutputDirectory + ").")
|
||||
def signAndPack(jars: List[Path], targetDirectory: Path): Either[String, List[Path]] =
|
||||
{
|
||||
lazyFold(jars, Nil: List[Path])
|
||||
{ (allJars, jar) =>
|
||||
val signPackResult =
|
||||
webstartSignConfiguration match
|
||||
{
|
||||
case Some(config) =>
|
||||
if(webstartPack200)
|
||||
signAndPack200(jar, config, targetDirectory, log)
|
||||
else
|
||||
signOnly(jar, config, targetDirectory, log)
|
||||
case None =>
|
||||
if(webstartPack200)
|
||||
pack200Only(jar, targetDirectory, log)
|
||||
else
|
||||
copyJar(jar, targetDirectory, log).right.map(jars => new Jars(jars, Nil))
|
||||
}
|
||||
val deleteOriginal = webstartPack200
|
||||
signPackResult.right flatMap { addJars =>
|
||||
if(webstartGzip)
|
||||
Control.lazyFold(addJars.gzippable, addJars.allJars ::: allJars)
|
||||
{ (accumulate, jar) => gzipJar(jar, deleteOriginal, log).right.map(_ ::: accumulate) }
|
||||
else
|
||||
Right(addJars.allJars ::: allJars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import FileUtilities._
|
||||
|
||||
val jars = (webstartLibraries +++ webstartExtraLibraries).get.filter(ClasspathUtilities.isArchive)
|
||||
def process(jars: Iterable[Path]) = for(jar <- jars if jar.name.endsWith(".jar")) yield relativize(jar)
|
||||
|
||||
thread(signAndPack(webstartMainJar :: Nil, webstartOutputDirectory)) { mainJars =>
|
||||
thread(signAndPack(jars.toList, webstartLibDirectory)) { libJars =>
|
||||
writeXML(jnlpXML(jarResources(process(mainJars), process(libJars))), jnlpFile, log) orElse
|
||||
thread(copy(webstartResources.get, webstartOutputDirectory, log)) { copiedResources =>
|
||||
val keep = jnlpFile +++ Path.lazyPathFinder(mainJars ++ libJars ++ copiedResources) +++
|
||||
webstartOutputDirectory +++ webstartLibDirectory
|
||||
prune(webstartOutputDirectory, keep.get, log) orElse
|
||||
webstartZip.flatMap( zipPath => zip(List(webstartOutputDirectory ###), zipPath, true, log) )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Creates default XML elements for a JNLP file for the given resources.*/
|
||||
protected def defaultElements(resources: Seq[WebstartJarResource]): NodeSeq = NodeSeq.fromSeq(resources.map(defaultElement))
|
||||
/** Creates a default XML element for a JNLP file for the given resource.*/
|
||||
protected def defaultElement(resource: WebstartJarResource): Elem =
|
||||
<jar href={resource.href} main={resource.isMain.toString}/>
|
||||
|
||||
}
|
||||
private class Jars(val gzippable: List[Path], val nonGzippable: List[Path]) extends NotNull
|
||||
{
|
||||
def allJars = gzippable ::: nonGzippable
|
||||
}
|
||||
private object WebstartScalaProject
|
||||
{
|
||||
import FileTasks.{runOption, wrapProduct, wrapProducts}
|
||||
/** Changes the extension of the Path of the given jar from ".jar" to newExtension. If append is true,
|
||||
* the new extension is simply appended to the jar's filename. */
|
||||
private def appendExtension(jar: Path, newExtension: String) =
|
||||
jar match
|
||||
{
|
||||
case rp: RelativePath => rp.parentPath / (rp.component + newExtension)
|
||||
case x => x
|
||||
}
|
||||
private def gzipJarPath(jar: Path) = appendExtension(jar, ".gz")
|
||||
private def packPath(jar: Path) = appendExtension(jar, ".pack")
|
||||
private def signOnly(jar: Path, signConfiguration: SignConfiguration, targetDirectory: Path, log: Logger) =
|
||||
{
|
||||
val targetJar = targetDirectory / jar.name
|
||||
runOption("sign", targetJar from jar, log) {
|
||||
log.debug("Signing " + jar)
|
||||
signAndVerify(jar, signConfiguration, targetJar, log)
|
||||
}.toLeft(new Jars(targetJar :: Nil, Nil))
|
||||
}
|
||||
private def signAndVerify(jar: Path, signConfiguration: SignConfiguration, targetJar: Path, log: Logger) =
|
||||
{
|
||||
import SignJar._
|
||||
sign(jar, signConfiguration.alias, signedJar(targetJar) :: signConfiguration.options.toList, log) orElse
|
||||
verify(jar, signConfiguration.options, log).map(err => "Signed jar failed verification: " + err)
|
||||
}
|
||||
private def gzipJar(jar: Path, deleteOriginal: Boolean, log: Logger) =
|
||||
{
|
||||
val gzipJar = gzipJarPath(jar)
|
||||
runOption("gzip", gzipJar from jar, log)
|
||||
{
|
||||
log.debug("Gzipping " + jar)
|
||||
FileUtilities.gzip(jar, gzipJar, log) orElse
|
||||
(if(deleteOriginal) FileUtilities.clean(jar :: Nil, true, log) else None)
|
||||
}.toLeft(gzipJar :: Nil)
|
||||
}
|
||||
/** Properly performs both signing and pack200 compression and verifies the result. This method only does anything if
|
||||
* its outputs are out of date with respect to 'jar'. Note that it does not determine if the signing configuration has changed.
|
||||
* See java.util.jar.Pack200 for more information.*/
|
||||
private def signAndPack200(jar: Path, signConfiguration: SignConfiguration, targetDirectory: Path, log: Logger) =
|
||||
{
|
||||
val signedJar = targetDirectory / jar.name
|
||||
val packedJar = packPath(signedJar)
|
||||
import signConfiguration._
|
||||
|
||||
runOption("sign and pack200", List(packedJar, signedJar) from jar, log) {
|
||||
log.debug("Applying pack200 compression and signing " + jar)
|
||||
signAndPack(jar, signedJar, packedJar, alias, options, log) orElse
|
||||
signAndVerify(jar, signConfiguration, signedJar, log)
|
||||
}.toLeft(new Jars(packedJar :: Nil, signedJar :: Nil))
|
||||
}
|
||||
/** Properly performs both signing and pack200 compression and verifies the result. See java.util.jar.Pack200 for more information.*/
|
||||
private def signAndPack(jarPath: Path, signedPath: Path, out: Path, alias: String, options: Seq[SignJar.SignOption], log: Logger): Option[String] =
|
||||
{
|
||||
import Pack._
|
||||
import SignJar._
|
||||
pack(jarPath, out, log) orElse
|
||||
unpack(out, signedPath, log) orElse
|
||||
sign(signedPath, alias, options, log) orElse
|
||||
pack(signedPath, out, log) orElse
|
||||
unpack(out, signedPath, log) orElse
|
||||
verify(signedPath, options, log)
|
||||
}
|
||||
private def pack200Only(jar: Path, targetDirectory: Path, log: Logger) =
|
||||
{
|
||||
val targetJar = targetDirectory / jar.name
|
||||
val packedJar = packPath(targetJar)
|
||||
val packResult =
|
||||
runOption("pack200", packedJar from jar, log)
|
||||
{
|
||||
log.debug("Applying pack200 compression to " + jar)
|
||||
Pack.pack(jar, packedJar, log)
|
||||
}
|
||||
packResult match
|
||||
{
|
||||
case Some(err) => Left(err)
|
||||
case None => copyJar(jar, targetDirectory, log).right.map(jars => new Jars(packedJar :: Nil, jars))
|
||||
}
|
||||
}
|
||||
private def copyJar(jar: Path, targetDirectory: Path, log: Logger) =
|
||||
{
|
||||
val targetJar = targetDirectory / jar.name
|
||||
runOption("copy jar", targetJar from jar, log)( FileUtilities.copyFile(jar, targetJar, log) ).toLeft(targetJar :: Nil)
|
||||
}
|
||||
/** Writes the XML string 'xmlString' to the file 'outputPath'.*/
|
||||
private def writeXML(xmlString: String, outputPath: Path, log: Logger): Option[String] =
|
||||
FileUtilities.write(outputPath.asFile, xmlString, log)
|
||||
/** Writes the XML string 'xmlString' to the file 'outputPath' if the hashes are different.*/
|
||||
private def writeXML(xml: Elem, outputPath: Path, log: Logger): Option[String] =
|
||||
{
|
||||
val xmlString =
|
||||
{
|
||||
import scala.xml.Utility
|
||||
object WithToXML {
|
||||
def toXML(xml: Elem, stripComments: Boolean) = Utility.toXML(xml).toString // this will only be called for 2.8, which defaults to stripComments= false, unlike 2.7
|
||||
}
|
||||
implicit def another28Hack(any: AnyRef) = WithToXML
|
||||
scala.xml.Utility.toXML(xml, false) // 2.8 doesn't have this method anymore, so the above implicit will kick in for 2.8 only
|
||||
}
|
||||
if(!outputPath.exists)
|
||||
{
|
||||
log.debug("JNLP file did not exist, writing inline XML to " + outputPath)
|
||||
writeXML(xmlString, outputPath, log)
|
||||
}
|
||||
else
|
||||
{
|
||||
val result =
|
||||
for( xmlHash <- Hash(xmlString, log).right; fileHash <- Hash(outputPath, log).right ) yield
|
||||
{
|
||||
if(xmlHash deepEquals fileHash)
|
||||
{
|
||||
log.debug("JNLP file " + outputPath + " uptodate.")
|
||||
None
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Inline JNLP XML modified, updating file " + outputPath + ".")
|
||||
writeXML(xmlString, outputPath, log)
|
||||
}
|
||||
}
|
||||
result.fold(err => Some(err), x => x)
|
||||
}
|
||||
}
|
||||
private def jarResource(isMain: Boolean)(jar: Path): WebstartJarResource =
|
||||
new WebstartJarResource(jar.name, jar.relativePathString("/"), isMain)
|
||||
private def jarResources(mainJars: Iterable[Path], libraries: Iterable[Path]): Seq[WebstartJarResource] =
|
||||
mainJars.map(jarResource(true)).toList ::: libraries.map(jarResource(false)).toList
|
||||
|
||||
/** True iff 'directory' is an ancestor (strictly) of 'check'.*/
|
||||
private def isInDirectory(directory: Path, check: Path) = Path.relativize(directory, check).isDefined && directory != check
|
||||
/** Checks the paths in the given options for validity. See the documentation for WebstartOptions.*/
|
||||
private def verifyOptions(options: WebstartOptions)
|
||||
{
|
||||
import options._
|
||||
require(isInDirectory(webstartOutputDirectory, webstartLibDirectory),
|
||||
"Webstart dependency directory (" + webstartLibDirectory + ") must be a subdirectory of webstart output directory (" +
|
||||
webstartOutputDirectory + ").")
|
||||
require(isInDirectory(webstartOutputDirectory, jnlpFile), "Webstart JNLP file output location (" + jnlpFile +
|
||||
") must be in the webstart output directory (" + webstartOutputDirectory + ").")
|
||||
for(wz <- webstartZip)
|
||||
require(!isInDirectory(webstartOutputDirectory, wz),
|
||||
"Webstart output zip location (" + wz + " cannot be in webstart output directory (" + webstartOutputDirectory + ").")
|
||||
}
|
||||
}
|
||||
/** The default extension point for a webstart project. There is one method that is required to be defined: jnlpXML.
|
||||
* 'webstartSignConfiguration', 'webstartPack200', and 'webstartGzip' are methods of interest. */
|
||||
abstract class DefaultWebstartProject(val info: ProjectInfo) extends BasicWebstartProject with MavenStyleWebstartPaths
|
||||
/** Defines default implementations of all methods in WebstartOptions except for jnlpXML. packageAction is overridden
|
||||
* to create a webstart distribution after the normal package operation. */
|
||||
abstract class BasicWebstartProject extends BasicScalaProject with WebstartScalaProject with WebstartOptions with WebstartPaths
|
||||
{
|
||||
def webstartSignConfiguration: Option[SignConfiguration] = None
|
||||
|
||||
def webstartExtraLibraries = mainDependencies.scalaJars
|
||||
def webstartLibraries = publicClasspath +++ jarsOfProjectDependencies
|
||||
def webstartResources = descendents(jnlpResourcesPath ###, AllPassFilter)
|
||||
|
||||
def webstartPack200 = true
|
||||
def webstartGzip = true
|
||||
|
||||
override def packageAction = super.packageAction && webstartTask(this)
|
||||
}
|
||||
Loading…
Reference in New Issue