diff --git a/compile/ComponentCompiler.scala b/compile/ComponentCompiler.scala index 5af5e0db4..9def56761 100644 --- a/compile/ComponentCompiler.scala +++ b/compile/ComponentCompiler.scala @@ -44,7 +44,12 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) withTemporaryDirectory { outputDirectory => val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail) manager.log.info("'" + id + "' not yet compiled for Scala " + compiler.scalaInstance.actualVersion + ". Compiling...") - try { compiler(Set() ++ sourceFiles, Set() ++ xsbtiJars, outputDirectory, Nil, true) } + val start = System.currentTimeMillis + try + { + compiler(Set() ++ sourceFiles, Set() ++ xsbtiJars, outputDirectory, Nil, true) + manager.log.info(" Compilation completed in " + (System.currentTimeMillis - start) / 1000.0 + " s") + } catch { case e: xsbti.CompileFailed => throw new CompileFailed(e.arguments, "Error compiling sbt component '" + id + "'") } copy(resources x (FileMapper.rebase(dir, outputDirectory))) zip((outputDirectory ***) x (PathMapper.relativeTo(outputDirectory)), targetJar) diff --git a/launch/Cache.scala b/launch/Cache.scala index ed50dfbe8..07d681970 100644 --- a/launch/Cache.scala +++ b/launch/Cache.scala @@ -2,18 +2,19 @@ package xsbt.boot import java.util.HashMap -final class Cache[K,V <: AnyRef](create: K => V) extends NotNull +final class Cache[K,V](create: K => V) extends NotNull { private[this] val delegate = new HashMap[K,V] def apply(k: K): V = { val existing = delegate.get(k) - if(existing eq null) newEntry(k) else existing + if(existing == null) newEntry(k) else existing } private[this] def newEntry(k: K): V = { val v = create(k) + Pre.assert(v != null, "Value for key " + k + " was null") delegate.put(k, v) v } -} \ No newline at end of file +} diff --git a/launch/Launch.scala b/launch/Launch.scala index 5830b53a2..62ca5ea89 100644 --- a/launch/Launch.scala +++ b/launch/Launch.scala @@ -6,8 +6,8 @@ import java.net.URL object Launch { - val start = System.currentTimeMillis - def time(label: String) = System.out.println(label + " : " + (System.currentTimeMillis - start) / 1000.0 + " s") + //val start = System.currentTimeMillis + def time(label: String) = ()//System.out.println(label + " : " + (System.currentTimeMillis - start) / 1000.0 + " s") def apply(arguments: List[String]): Unit = apply( (new File("")).getAbsoluteFile , arguments ) def apply(currentDirectory: File, arguments: List[String]): Unit = diff --git a/launch/ListMap.scala b/launch/ListMap.scala index a59869175..726ef5b41 100644 --- a/launch/ListMap.scala +++ b/launch/ListMap.scala @@ -23,6 +23,7 @@ sealed class ListMap[K,V] private(backing: List[(K,V)]) extends Iterable[(K,V)] override def apply(k: K) = super.get(k).getOrElse(defaultF(k)) override def copy(newBacking: List[(K,V)]) = super.copy(newBacking).default(defaultF) } + override def toString = backing.mkString("ListMap(",",",")") } object ListMap { diff --git a/launch/Update.scala b/launch/Update.scala index b87e77a3b..7b913c4f4 100644 --- a/launch/Update.scala +++ b/launch/Update.scala @@ -82,10 +82,12 @@ final class Update(config: UpdateConfiguration) case UpdateScala => addDependency(moduleID, ScalaOrg, CompilerModuleName, scalaVersion, "default") addDependency(moduleID, ScalaOrg, LibraryModuleName, scalaVersion, "default") + System.out.println("Getting Scala " + scalaVersion + " ...") case u: UpdateApp => val app = u.id val resolvedName = if(app.crossVersioned) app.name + "_" + scalaVersion else app.name addDependency(moduleID, app.groupID, resolvedName, app.getVersion, "default(compile)") + System.out.println("Getting " + app.groupID + " " + resolvedName + " " + app.getVersion + " ...") } update(moduleID, target) } diff --git a/launch/src/main/resources/sbt/sbt.boot.properties b/launch/src/main/resources/sbt/sbt.boot.properties index 93b9bf1bb..a03f8c0c6 100644 --- a/launch/src/main/resources/sbt/sbt.boot.properties +++ b/launch/src/main/resources/sbt/sbt.boot.properties @@ -15,7 +15,7 @@ # Sbt Repository, http://simple-build-tool.googlecode.com/svn/artifacts/, [revision]/[type]s/[artifact].[ext] maven-central scala-tools-releases -# scala-tools-snapshots + scala-tools-snapshots [boot] directory: project/boot @@ -29,9 +29,9 @@ [app-properties] project.name: quick=set(test), new=prompt(Name), fill=prompt(Name) + project.organization: new=prompt(Organization) project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0] - build.init.scala.version: quick=set(2.7.5), new=prompt(Scala version)[2.7.5] - scala.version: quick=set(2.7.5), new=set(2.7.5), fill=set(2.7.5) + scala.version: quick=set(2.7.5), new=prompt(Scala version)[2.7.5], fill=prompt(Scala version)[2.7.5] sbt.version: quick=set(0.5.6-SNAPSHOT), new=prompt(sbt version)[0.5.6-SNAPSHOT], fill=prompt(sbt version)[0.5.6-SNAPSHOT] project.scratch: quick=set(true) project.initialize: quick=set(true), new=set(true) \ No newline at end of file diff --git a/launch/src/test/scala/CacheTest.scala b/launch/src/test/scala/CacheTest.scala new file mode 100644 index 000000000..6a3a6bbe6 --- /dev/null +++ b/launch/src/test/scala/CacheTest.scala @@ -0,0 +1,15 @@ +package xsbt.boot + +import org.scalacheck._ +import Prop._ + +object CacheTest extends Properties("Cache") +{ + implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.elements(identity[Int], i => -i, i=>i/2, i => i+1) } + + property("Cache") = Prop.forAll { (key: Int, keys: List[Int], map: Int => Int) => + val cache = new Cache(map) + def toProperty(key: Int) = ("Key " + key) |: ("Value: " + map(key)) |: (cache.apply(key) == map(key)) + Prop.all( keys.map(toProperty) : _*) + } +} \ No newline at end of file diff --git a/launch/src/test/scala/EnumerationTest.scala b/launch/src/test/scala/EnumerationTest.scala new file mode 100644 index 000000000..8fcc540cd --- /dev/null +++ b/launch/src/test/scala/EnumerationTest.scala @@ -0,0 +1,55 @@ +package xsbt.boot + +import org.scalacheck._ +import Prop.{Exception => _,_} + +object EnumerationTest extends Properties("Enumeration") +{ + property("MultiEnum.toValue") = checkToValue(MultiEnum, multiElements : _*) + property("MultiEnum.elements") = checkElements(MultiEnum, multiElements : _*) + property("EmptyEnum.toValue") = checkToValue(EmptyEnum) + property("EmptyEnum.elements") = EmptyEnum.elements.isEmpty + property("SingleEnum.toValue") = checkToValue( SingleEnum, singleElements ) + property("SingleEnum.elements") = checkElements( SingleEnum,singleElements ) + + def singleElements = ("A", SingleEnum.a) + def multiElements = + { + import MultiEnum.{a,b,c} + List(("A" -> a), ("B" -> b), ("C" -> c)) + } + + def checkElements(enum: Enumeration, mapped: (String, Enumeration#Value)*) = + { + val elements = enum.elements + ("elements: " + elements) |: + ( mapped.forall{ case (s,v) => elements.contains(v) } && (elements.length == mapped.length) ) + } + def checkToValue(enum: Enumeration, mapped: (String, Enumeration#Value)*) = + { + def invalid(s: String) = + ("valueOf(" + s + ")") |: + Prop.throws(enum.toValue(s), classOf[Exception]) + def valid(s: String, expected: Enumeration#Value) = + ("valueOf(" + s + ")") |: + ("Expected " + expected) |: + ( enum.toValue(s) == expected ) + val map = Map( mapped : _*) + Prop.forAll( (s: String) => + map.get(s) match { + case Some(v) => valid(s, v) + case None => invalid(s) + } ) + } + object MultiEnum extends Enumeration + { + val a = value("A") + val b = value("B") + val c = value("C") + } + object SingleEnum extends Enumeration + { + val a = value("A") + } + object EmptyEnum extends Enumeration +} \ No newline at end of file diff --git a/launch/src/test/scala/ListMapTest.scala b/launch/src/test/scala/ListMapTest.scala new file mode 100644 index 000000000..ff867101a --- /dev/null +++ b/launch/src/test/scala/ListMapTest.scala @@ -0,0 +1,39 @@ +package xsbt.boot + +import org.scalacheck._ + +object ListMapProperties extends Properties("ListMap") +{ + implicit val genListMap = Arbitrary ( for(list <- Arbitrary.arbitrary[List[(Int,Int)]]) yield ListMap(list : _*) ) + + property("ListMap from List contains all members of that List") = Prop.forAll { (list: List[(Int,Int)]) => + val map = ListMap(list : _*) + list forall { entry => map contains entry._1 } + } + property("contains added entry") = Prop.forAll { (map: ListMap[Int,Int], key: Int, value: Int) => + { (map + (key, value) ) contains(key) } && + { (map + (key, value) )(key) == value } && + { (map + (key, value) ).get(key) == Some(value) } + } + property("remove") = Prop.forAll { (map: ListMap[Int,Int], key: Int) => + { Prop.throws((map - key)(key), classOf[Exception]) } && + { !(map - key).contains(key) } && + { (map - key).get(key).isEmpty } + } + property("empty") = Prop.forAll { (key: Int) => + { Prop.throws(ListMap.empty(key), classOf[Exception]) } + { !ListMap.empty.contains(key) } && + { ListMap.empty.get(key).isEmpty } + } +} + +object ListMapEmpty extends Properties("ListMap.empty") +{ + import ListMap.empty + property("isEmpty") = empty.isEmpty + property("toList.isEmpty") = empty.toList.isEmpty + property("toSeq.isEmpty") = empty.toSeq.isEmpty + property("toStream.isEmpty") = empty.toStream.isEmpty + property("keys.isEmpty") = empty.keys.isEmpty + property("elements.isEmpty") = !empty.elements.hasNext +} \ No newline at end of file diff --git a/launch/src/test/scala/PreTest.scala b/launch/src/test/scala/PreTest.scala new file mode 100644 index 000000000..6cdbc9e9a --- /dev/null +++ b/launch/src/test/scala/PreTest.scala @@ -0,0 +1,22 @@ +package xsbt.boot + +import org.scalacheck._ + +object PreTest extends Properties("Pre") +{ + import Pre._ + property("isEmpty") = Prop.forAll( (s: String) => (s.isEmpty == isEmpty(s)) ) + property("isNonEmpty") = Prop.forAll( (s: String) => (isEmpty(s) != isNonEmpty(s)) ) + property("assert true") = { assert(true); true } + property("assert false") = Prop.throws(assert(false), classOf[AssertionError]) + property("assert true with message") = Prop.forAll { (s: String) => assert(true, s); true } + property("assert false with message") = Prop.forAll( (s: String) => Prop.throws(assert(false, s), classOf[AssertionError] ) ) + property("require false") = Prop.forAll( (s: String) => Prop.throws(require(false, s), classOf[IllegalArgumentException]) ) + property("require true") = Prop.forAll { (s: String) => require(true, s); true } + property("error") = Prop.forAll( (s: String) => Prop.throws(error(s), classOf[BootException]) ) + property("toBoolean") = Prop.forAll( (s: String) => trap(toBoolean(s)) == trap(java.lang.Boolean.parseBoolean(s)) ) + property("toArray") = Prop.forAll( (list: List[Int]) => list.toArray deepEquals toArray(list) ) + property("toArray") = Prop.forAll( (list: List[String]) => list.toArray deepEquals toArray(list) ) + + def trap[T](t: => T): Option[T] = try { Some(t) } catch { case e: Exception => None } +} \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index d69084ecb..cd82460af 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,7 +1,7 @@ #Project properties -#Wed Oct 07 13:14:09 EDT 2009 +#Sun Oct 18 13:26:05 EDT 2009 project.organization=org.scala-tools.sbt project.name=xsbt -sbt.version=0.5.5 +sbt.version=0.5.6-p1 project.version=0.7.0_13 scala.version=2.7.5 diff --git a/project/build/LauncherProguard.scala b/project/build/LauncherProguard.scala index 58bb1a325..1d441cd18 100644 --- a/project/build/LauncherProguard.scala +++ b/project/build/LauncherProguard.scala @@ -3,6 +3,7 @@ import java.io.File trait ProguardLaunch extends ProguardProject { + override def basicOptions = super.basicOptions ++ Seq(keepJLine) def outputJar = rootProject.outputPath / ("xsbt-launch-" + version + ".jar") override def keepClasses = "org.apache.ivy.plugins.resolver.URLResolver" :: diff --git a/project/build/XSbt.scala b/project/build/XSbt.scala index 236485965..75038e013 100644 --- a/project/build/XSbt.scala +++ b/project/build/XSbt.scala @@ -77,7 +77,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) } trait TestDependencies extends Project { - val sc = "org.scala-tools.testing" % "scalacheck" % "1.5" % "test" + val sc = "org.scala-tools.testing" %% "scalacheck" % "1.6" % "test" val sp = "org.scala-tools.testing" % "specs" % "1.6.0" % "test" } class StandardTaskProject(info: ProjectInfo) extends Base(info)