mirror of https://github.com/sbt/sbt.git
first update of io for 2.8
This commit is contained in:
parent
5eed8ccbef
commit
d1260eebd1
|
|
@ -82,8 +82,9 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
}
|
||||
trait TestDependencies extends Project
|
||||
{
|
||||
val sc = "org.scala-tools.testing" %% "scalacheck" % "1.6" % "test"
|
||||
val sp = "org.scala-tools.testing" % "specs" % "1.6.0" % "test"
|
||||
val sc = "org.scala-tools.testing" %% "scalacheck" % "1.7" % "test"
|
||||
val sp = "org.scala-tools.testing" %% "specs" % "1.6.5-SNAPSHOT" % "test"
|
||||
val snaps = ScalaToolsSnapshots
|
||||
}
|
||||
class StandardTaskProject(info: ProjectInfo) extends Base(info)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.{ByteArrayInputStream, File, InputStream}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ object Hash
|
|||
/** Calculates the SHA-1 hash of the given String.*/
|
||||
def apply(s: String): Array[Byte] = apply(new ByteArrayInputStream(s.getBytes("UTF-8")))
|
||||
/** Calculates the SHA-1 hash of the given file.*/
|
||||
def apply(file: File): Array[Byte] = OpenResource.fileInputStream(file)(apply)
|
||||
def apply(file: File): Array[Byte] = Using.fileInputStream(file)(apply)
|
||||
/** Calculates the SHA-1 hash of the given stream, closing it when finished.*/
|
||||
def apply(stream: InputStream): Array[Byte] =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
* Copyright 2008, 2009, 2010 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import OpenResource._
|
||||
import ErrorHandling.translate
|
||||
import Using._
|
||||
import xsbt.ErrorHandling.translate
|
||||
|
||||
import java.io.{ByteArrayOutputStream, BufferedWriter, File, FileInputStream, InputStream, OutputStream}
|
||||
import java.net.{URI, URISyntaxException, URL}
|
||||
|
|
@ -15,7 +15,7 @@ import scala.collection.mutable.HashSet
|
|||
import scala.reflect.{Manifest => SManifest}
|
||||
import Function.tupled
|
||||
|
||||
object FileUtilities
|
||||
object IO
|
||||
{
|
||||
/** The maximum number of times a unique temporary filename is attempted to be created.*/
|
||||
private val MaximumTries = 10
|
||||
|
|
@ -26,7 +26,7 @@ object FileUtilities
|
|||
private val BufferSize = 8192
|
||||
private val Newline = System.getProperty("line.separator")
|
||||
|
||||
def utf8 = Charset.forName("UTF-8")
|
||||
val utf8 = Charset.forName("UTF-8")
|
||||
|
||||
def classLocation(cl: Class[_]): URL =
|
||||
{
|
||||
|
|
@ -91,8 +91,7 @@ object FileUtilities
|
|||
else
|
||||
error(failBase)
|
||||
}
|
||||
def unzip(from: File, toDirectory: File): Set[File] = unzip(from, toDirectory, AllPassFilter)
|
||||
def unzip(from: File, toDirectory: File, filter: NameFilter): Set[File] = fileInputStream(from)(in => unzip(in, toDirectory, filter))
|
||||
def unzip(from: File, toDirectory: File, filter: NameFilter = AllPassFilter): Set[File] = fileInputStream(from)(in => unzip(in, toDirectory, filter))
|
||||
def unzip(from: InputStream, toDirectory: File, filter: NameFilter): Set[File] =
|
||||
{
|
||||
createDirectory(toDirectory)
|
||||
|
|
@ -187,7 +186,7 @@ object FileUtilities
|
|||
create(0)
|
||||
}
|
||||
|
||||
private[xsbt] def jars(dir: File): Iterable[File] = listFiles(dir, GlobFilter("*.jar"))
|
||||
private[sbt] def jars(dir: File): Iterable[File] = listFiles(dir, GlobFilter("*.jar"))
|
||||
|
||||
def delete(files: Iterable[File]): Unit = files.foreach(delete)
|
||||
def delete(file: File)
|
||||
|
|
@ -246,21 +245,24 @@ object FileUtilities
|
|||
{
|
||||
def add(sourceFile: File, name: String)
|
||||
{
|
||||
if(sourceFile.isDirectory)
|
||||
()
|
||||
else if(sourceFile.exists)
|
||||
{
|
||||
val nextEntry = createEntry(normalizeName(name))
|
||||
nextEntry.setTime(sourceFile.lastModified)
|
||||
output.putNextEntry(nextEntry)
|
||||
transferAndClose(new FileInputStream(sourceFile), output)
|
||||
}
|
||||
else
|
||||
if(!sourceFile.exists)
|
||||
error("Source " + sourceFile + " does not exist.")
|
||||
val isDirectory = sourceFile.isDirectory
|
||||
val relName = if(isDirectory) normalizeDirName(name) else normalizeName(name)
|
||||
val nextEntry = createEntry(relName)
|
||||
nextEntry.setTime(sourceFile.lastModified)
|
||||
output.putNextEntry(nextEntry)
|
||||
if(!isDirectory)
|
||||
transfer(new FileInputStream(sourceFile), output)
|
||||
}
|
||||
sources.foreach(tupled(add))
|
||||
sources.foreach((add _).tupled)
|
||||
output.closeEntry()
|
||||
}
|
||||
private def normalizeDirName(name: String) =
|
||||
{
|
||||
val norm1 = normalizeName(name)
|
||||
if(norm1.endsWith("/")) norm1 else (norm1 + "/")
|
||||
}
|
||||
private def normalizeName(name: String) =
|
||||
{
|
||||
val sep = File.separatorChar
|
||||
|
|
@ -308,10 +310,8 @@ object FileUtilities
|
|||
{
|
||||
val cp = baseFile.getAbsolutePath
|
||||
assert(cp.length > 0)
|
||||
if(cp.charAt(cp.length - 1) == File.separatorChar)
|
||||
Some(cp)
|
||||
else
|
||||
Some(cp + File.separatorChar)
|
||||
val normalized = if(cp.charAt(cp.length - 1) == File.separatorChar) cp else cp + File.separatorChar
|
||||
Some(normalized)
|
||||
}
|
||||
else
|
||||
None
|
||||
|
|
@ -344,9 +344,7 @@ object FileUtilities
|
|||
}
|
||||
}
|
||||
def defaultCharset = utf8
|
||||
def write(toFile: File, content: String): Unit = write(toFile, content, defaultCharset)
|
||||
def write(toFile: File, content: String, charset: Charset): Unit = write(toFile, content, charset, false)
|
||||
def write(file: File, content: String, charset: Charset, append: Boolean): Unit =
|
||||
def write(file: File, content: String, charset: Charset = defaultCharset, append: Boolean = false): Unit =
|
||||
writeCharset(file, content, charset, append) { _.write(content) }
|
||||
|
||||
def writeCharset[T](file: File, content: String, charset: Charset, append: Boolean)(f: BufferedWriter => T): T =
|
||||
|
|
@ -357,17 +355,14 @@ object FileUtilities
|
|||
error("String cannot be encoded by charset " + charset.name)
|
||||
}
|
||||
|
||||
def read(file: File): String = read(file, defaultCharset)
|
||||
def read(file: File, charset: Charset): String =
|
||||
def read(file: File, charset: Charset = defaultCharset): String =
|
||||
{
|
||||
val out = new ByteArrayOutputStream(file.length.toInt)
|
||||
fileInputStream(file){ in => transfer(in, out) }
|
||||
out.toString(charset.name)
|
||||
}
|
||||
/** doesn't close the InputStream */
|
||||
def read(in: InputStream): String = read(in, defaultCharset)
|
||||
/** doesn't close the InputStream */
|
||||
def read(in: InputStream, charset: Charset): String =
|
||||
def readStream(in: InputStream, charset: Charset = defaultCharset): String =
|
||||
{
|
||||
val out = new ByteArrayOutputStream
|
||||
transfer(in, out)
|
||||
|
|
@ -383,8 +378,7 @@ object FileUtilities
|
|||
}
|
||||
|
||||
// Not optimized for large files
|
||||
def readLines(file: File): List[String] = readLines(file, defaultCharset)
|
||||
def readLines(file: File, charset: Charset): List[String] =
|
||||
def readLines(file: File, charset: Charset = defaultCharset): List[String] =
|
||||
{
|
||||
fileReader(charset)(file){ in =>
|
||||
def readLine(accum: List[String]): List[String] =
|
||||
|
|
@ -395,9 +389,7 @@ object FileUtilities
|
|||
readLine(Nil)
|
||||
}
|
||||
}
|
||||
def writeLines(file: File, lines: Seq[String]): Unit = writeLines(file, lines, defaultCharset)
|
||||
def writeLines(file: File, lines: Seq[String], charset: Charset): Unit = writeLines(file, lines, charset, false)
|
||||
def writeLines(file: File, lines: Seq[String], charset: Charset, append: Boolean): Unit =
|
||||
def writeLines(file: File, lines: Seq[String], charset: Charset = defaultCharset, append: Boolean = false): Unit =
|
||||
writeCharset(file, lines.headOption.getOrElse(""), charset, append) { w =>
|
||||
lines.foreach { line => w.write(line); w.newLine() }
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.File
|
||||
|
||||
trait PathMapper extends NotNull
|
||||
{
|
||||
def apply(file: File): String
|
||||
def apply(files: Set[File]): Iterable[(File,String)] = files.projection.map(f => (f,apply(f)))
|
||||
def apply(files: Set[File]): Iterable[(File,String)] = files.view.map(f => (f,apply(f)))
|
||||
}
|
||||
final case class RelativePathMapper(base: File) extends PMapper(file => FileUtilities.relativize(base, file).getOrElse(file.getPath))
|
||||
final case class RelativePathMapper(base: File) extends PMapper(file => IO.relativize(base, file).getOrElse(file.getPath))
|
||||
final case object BasicPathMapper extends PMapper(_.getPath)
|
||||
final case object FlatPathMapper extends PMapper(_.getName)
|
||||
class PMapper(val f: File => String) extends PathMapper
|
||||
|
|
@ -22,7 +22,7 @@ object PathMapper
|
|||
val basic: PathMapper = BasicPathMapper
|
||||
def relativeTo(base: File): PathMapper = RelativePathMapper(base)
|
||||
def rebase(oldBase: File, newBase: File): PathMapper =
|
||||
new PMapper(file => if(file == oldBase) "." else FileUtilities.relativize(oldBase, file).getOrElse(error(file + " not a descendent of " + oldBase)))
|
||||
new PMapper(file => if(file == oldBase) "." else IO.relativize(oldBase, file).getOrElse(error(file + " not a descendent of " + oldBase)))
|
||||
val flat = FlatPathMapper
|
||||
def apply(f: File => String): PathMapper = new PMapper(f)
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ object PathMapper
|
|||
trait FileMapper extends NotNull
|
||||
{
|
||||
def apply(file: File): File
|
||||
def apply(files: Set[File]): Iterable[(File,File)] = files.projection.map(f => (f,apply(f)))
|
||||
def apply(files: Set[File]): Iterable[(File,File)] = files.view.map(f => (f,apply(f)))
|
||||
}
|
||||
class FMapper(f: File => File) extends FileMapper
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009, 2010 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
|
@ -28,7 +28,7 @@ trait PathBase extends NotNull
|
|||
def urls: Array[URL] = files.toArray[File].map(_.toURI.toURL)
|
||||
def x(mapper: PathMapper): Iterable[(File,String)] = mapper(files)
|
||||
def x(mapper: FileMapper): Iterable[(File,File)] = mapper(files)
|
||||
def *(filter: java.io.FileFilter): Set[File] = files.flatMap(FileUtilities.listFiles(filter))
|
||||
def *(filter: java.io.FileFilter): Set[File] = files.flatMap(IO.listFiles(filter))
|
||||
def **(filter: java.io.FileFilter): Set[File] = files.filter(filter.accept) ++ files.flatMap(_ * AllPassFilter ** filter)
|
||||
def *** = **(AllPassFilter)
|
||||
def abs = files.map(_.getAbsoluteFile)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.{Closeable, File, FileInputStream, FileOutputStream, InputStream, OutputStream}
|
||||
import java.io.{ByteArrayOutputStream, InputStreamReader, OutputStreamWriter}
|
||||
|
|
@ -13,10 +13,10 @@ import java.nio.channels.FileChannel
|
|||
import java.util.jar.{Attributes, JarEntry, JarFile, JarInputStream, JarOutputStream, Manifest}
|
||||
import java.util.zip.{GZIPOutputStream, ZipEntry, ZipFile, ZipInputStream, ZipOutputStream}
|
||||
|
||||
import ErrorHandling.translate
|
||||
import OpenResource._
|
||||
import xsbt.ErrorHandling.translate
|
||||
import Using._
|
||||
|
||||
abstract class OpenResource[Source, T] extends NotNull
|
||||
abstract class Using[Source, T] extends NotNull
|
||||
{
|
||||
protected def open(src: Source): T
|
||||
def apply[R](src: Source)(f: T => R): R =
|
||||
|
|
@ -28,57 +28,58 @@ abstract class OpenResource[Source, T] extends NotNull
|
|||
protected def close(out: T): Unit
|
||||
}
|
||||
import scala.reflect.{Manifest => SManifest}
|
||||
abstract class WrapOpenResource[Source, T](implicit srcMf: SManifest[Source], targetMf: SManifest[T]) extends OpenResource[Source, T]
|
||||
abstract class WrapUsing[Source, T](implicit srcMf: SManifest[Source], targetMf: SManifest[T]) extends Using[Source, T]
|
||||
{
|
||||
protected def label[S](m: SManifest[S]) = m.erasure.getSimpleName
|
||||
protected def openImpl(source: Source): T
|
||||
protected final def open(source: Source): T =
|
||||
translate("Error wrapping " + label(srcMf) + " in " + label(targetMf) + ": ") { openImpl(source) }
|
||||
}
|
||||
trait OpenFile[T] extends OpenResource[File, T]
|
||||
trait OpenFile[T] extends Using[File, T]
|
||||
{
|
||||
protected def openImpl(file: File): T
|
||||
protected final def open(file: File): T =
|
||||
{
|
||||
val parent = file.getParentFile
|
||||
if(parent != null)
|
||||
FileUtilities.createDirectory(parent)
|
||||
IO.createDirectory(parent)
|
||||
openImpl(file)
|
||||
}
|
||||
}
|
||||
object OpenResource
|
||||
object Using
|
||||
{
|
||||
def wrap[Source, T<: Closeable](openF: Source => T)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): OpenResource[Source,T] =
|
||||
wrap(openF, _.close)
|
||||
def wrap[Source, T](openF: Source => T, closeF: T => Unit)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): OpenResource[Source,T] =
|
||||
new WrapOpenResource[Source, T]
|
||||
def wrap[Source, T<: Closeable](openF: Source => T)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): Using[Source,T] =
|
||||
wrap(openF, closeCloseable)
|
||||
def wrap[Source, T](openF: Source => T, closeF: T => Unit)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): Using[Source,T] =
|
||||
new WrapUsing[Source, T]
|
||||
{
|
||||
def openImpl(source: Source) = openF(source)
|
||||
def close(t: T) = closeF(t)
|
||||
}
|
||||
|
||||
def resource[Source, T <: Closeable](openF: Source => T): OpenResource[Source,T] =
|
||||
resource(openF, _.close)
|
||||
def resource[Source, T](openF: Source => T, closeF: T => Unit): OpenResource[Source,T] =
|
||||
new OpenResource[Source,T]
|
||||
def resource[Source, T <: Closeable](openF: Source => T): Using[Source,T] =
|
||||
resource(openF, closeCloseable)
|
||||
def resource[Source, T](openF: Source => T, closeF: T => Unit): Using[Source,T] =
|
||||
new Using[Source,T]
|
||||
{
|
||||
def open(s: Source) = openF(s)
|
||||
def close(s: T) = closeF(s)
|
||||
}
|
||||
def file[T <: Closeable](openF: File => T): OpenFile[T] = file(openF, _.close())
|
||||
def file[T <: Closeable](openF: File => T): OpenFile[T] = file(openF, closeCloseable)
|
||||
def file[T](openF: File => T, closeF: T => Unit): OpenFile[T] =
|
||||
new OpenFile[T]
|
||||
{
|
||||
def openImpl(file: File) = openF(file)
|
||||
def close(t: T) = closeF(t)
|
||||
}
|
||||
private def closeCloseable[T <: Closeable]: T => Unit = _.close()
|
||||
|
||||
def fileOutputStream(append: Boolean) = file(f => new FileOutputStream(f, append))
|
||||
def fileOutputStream(append: Boolean = false) = file(f => new FileOutputStream(f, append))
|
||||
def fileInputStream = file(f => new FileInputStream(f))
|
||||
def urlInputStream = resource( (u: URL) => translate("Error opening " + u + ": ")(u.openStream))
|
||||
def fileOutputChannel = file(f => new FileOutputStream(f).getChannel)
|
||||
def fileInputChannel = file(f => new FileInputStream(f).getChannel)
|
||||
def fileWriter(charset: Charset, append: Boolean) =
|
||||
def fileWriter(charset: Charset = IO.utf8, append: Boolean = false) =
|
||||
file(f => new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, append), charset)) )
|
||||
def fileReader(charset: Charset) = file(f => new BufferedReader(new InputStreamReader(new FileInputStream(f), charset)) )
|
||||
def jarFile(verify: Boolean) = file(f => new JarFile(f, verify), (_: JarFile).close())
|
||||
|
|
@ -1,37 +1,37 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008 Mark Harrah */
|
||||
|
||||
package xsbt
|
||||
package sbt
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
|
||||
object NameFilterSpecification extends Properties("NameFilter")
|
||||
{
|
||||
specify("All pass accepts everything", (s: String) => AllPassFilter.accept(s))
|
||||
specify("Exact filter matches provided string",
|
||||
(s1: String, s2: String) => (new ExactFilter(s1)).accept(s2) == (s1 == s2) )
|
||||
specify("Exact filter matches valid string", (s: String) => (new ExactFilter(s)).accept(s) )
|
||||
property("All pass accepts everything") = forAll{ (s: String) => AllPassFilter.accept(s) }
|
||||
property("Exact filter matches provided string") = forAll {
|
||||
(s1: String, s2: String) => (new ExactFilter(s1)).accept(s2) == (s1 == s2) }
|
||||
property("Exact filter matches valid string") = forAll{ (s: String) => (new ExactFilter(s)).accept(s) }
|
||||
|
||||
specify("Glob filter matches provided string if no *s",
|
||||
property("Glob filter matches provided string if no *s") = forAll {
|
||||
(s1: String, s2: String) =>
|
||||
{
|
||||
val stripped = stripAsterisksAndControl(s1)
|
||||
(GlobFilter(stripped).accept(s2) == (stripped == s2))
|
||||
})
|
||||
specify("Glob filter matches valid string if no *s",
|
||||
} }
|
||||
property("Glob filter matches valid string if no *s") = forAll {
|
||||
(s: String) =>
|
||||
{
|
||||
val stripped = stripAsterisksAndControl(s)
|
||||
GlobFilter(stripped).accept(stripped)
|
||||
})
|
||||
}}
|
||||
|
||||
specify("Glob filter matches valid",
|
||||
property("Glob filter matches valid") = forAll {
|
||||
(list: List[String]) =>
|
||||
{
|
||||
val stripped = list.map(stripAsterisksAndControl)
|
||||
GlobFilter(stripped.mkString("*")).accept(stripped.mkString)
|
||||
})
|
||||
}}
|
||||
|
||||
/** Raw control characters are stripped because they are not allowed in expressions.
|
||||
* Asterisks are stripped because they are added under the control of the tests.*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package xsbt
|
||||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import FileUtilities.{withTemporaryDirectory, write}
|
||||
import IO.{withTemporaryDirectory, write}
|
||||
|
||||
object WithFiles
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue