first update of io for 2.8

This commit is contained in:
Mark Harrah 2010-06-09 00:56:07 -04:00
parent 5eed8ccbef
commit d1260eebd1
9 changed files with 75 additions and 81 deletions

View File

@ -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)
{

View File

@ -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] =
{

View File

@ -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() }
}

View File

@ -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

View File

@ -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
{

View File

@ -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)

View File

@ -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())

View File

@ -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.*/

View File

@ -1,7 +1,7 @@
package xsbt
package sbt
import java.io.File
import FileUtilities.{withTemporaryDirectory, write}
import IO.{withTemporaryDirectory, write}
object WithFiles
{