From fe74dbec7f4d82f346e3d9517b28cb5d48eb873b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 2 Apr 2011 18:08:04 -0700 Subject: [PATCH] Major overhaul. --- bin/sbt-setup | 263 ++++++++++++++----------------- bin/util.sh | 14 ++ src/main/resources/support.scala | 89 +++++++++++ src/template/Libraries.scala | 62 ++++++++ src/template/Plugins.scala | 7 + src/template/Repositories.scala | 23 +++ 6 files changed, 314 insertions(+), 144 deletions(-) create mode 100755 bin/util.sh create mode 100644 src/main/resources/support.scala create mode 100644 src/template/Libraries.scala create mode 100644 src/template/Plugins.scala create mode 100644 src/template/Repositories.scala diff --git a/bin/sbt-setup b/bin/sbt-setup index 7d4c775cb..5bc09859c 100755 --- a/bin/sbt-setup +++ b/bin/sbt-setup @@ -1,173 +1,109 @@ -#!/bin/bash +#!/usr/bin/env bash # -PROJECT="$1" +BINDIR=$(abspath $(dirname "$0")) +. $BINDIR/util.sh +BASE=$(abspath $BINDIR/..) -DEFAULT_PACKAGE="template" -PACKAGE=${ORGANIZATION:-$DEFAULT_PACKAGE} +declare -a args +TEMPLATE="simple" SCALA_VERSION="2.8.1" -SCALA_LOCAL_VERSION="2.9.0-local" -SBT_VERSION="0.7.5.RC1" +PROJECT_VERSION="0.0.1" -if [ -z "$PROJECT" ]; then +while [ $# -gt 0 ]; do + case "$1" in + --simple) + TEMPLATE="simple" + shift + ;; + --fancy) + TEMPLATE="fancy" + shift + ;; + --version) + shift + PROJECT_VERSION="$1" + shift + ;; + --28) + SCALA_VERSION="2.8.1" + shift + ;; + --29) + SCALA_VERSION="2.9.0.RC1" + shift + ;; + *) + args=("${args[@]}" "$1") + shift + ;; + esac +done + +# reset "$@" to the remaining args +set -- "${args[@]}" + +if [[ $# -ne 1 ]]; then + cat < [dependencies] + + --simple use simple project template + --fancy use multi-file project template + --28 latest release of scala 2.8.x + --29 latest release of scala 2.9.x + + --version project initial version +EOM + + exit 1 +fi + +if [ -z "$1" ]; then echo "Usage: $0 " exit 1 fi +PROJECT="$1" +PACKAGE=${ORGANIZATION:-template} +SBT_VERSION="0.7.6.RC0" DIR=$(echo ${PROJECT} | tr '[A-Z]' '[a-z]') -PROJECT_UC=$(echo ${PROJECT:0:1} | tr '[a-z]' '[A-Z]')$(echo ${PROJECT:1} | sed -e 's/[^a-zA-Z_]//g;') -PROJECT_CLASS=${PROJECT_UC}Project -SPEC_CLASS=${PROJECT_UC}Spec +PROJECT_CC=`camelCase ${PROJECT}` +PROJECT_CLASS=${PROJECT_CC}Project +SPEC_CLASS=${PROJECT_CC}Spec -mkdir $DIR +[[ -e $DIR ]] && { echo "$DIR exists, please remove it first." ; exit 1; } + +mkdir -p $DIR cd $DIR -echo "Creating sbt project ${PROJECT} in ${PWD}" -echo "" +echo "Creating \"${PACKAGE} % ${PROJECT} % ${PROJECT_VERSION}\" from template \"$TEMPLATE\"." +echo "Building against scala $SCALA_VERSION with sbt $SBT_VERSION." +echo "Repository in ${PWD} ." +echo -cat > .gitignore < project/build/Libraries.scala < ModuleID) -object ArtifactConfig { - implicit def defaultArtifactConfig: ArtifactConfig = new ArtifactConfig("", identity[ModuleID]) - implicit def testArtifactConfig: ArtifactConfig = new ArtifactConfig("test", identity[ModuleID]) -} - -trait LowPriorityLibraries { - self: DefaultProject => - - // "latest.integration", "latest.milestone", "latest.release" - def defaultRevision = "latest.integration" - protected implicit def defaultArtifactRevision = new ArtifactRevision(defaultRevision) - // protected implicit def defaultArtifactConfig = new ArtifactConfig("", identity[ModuleID]) - - protected implicit def autoConfig - (artifact: GroupArtifactID) - (implicit rev: ArtifactRevision, config: ArtifactConfig): ModuleID = - { - val ArtifactConfig(confs, fn) = config - fn( - if (confs == "") artifact % rev.revision - else artifact % rev.revision % config.confs - ) - } -} - -trait TestLibraries extends LowPriorityLibraries { - self: DefaultProject => - - private implicit val testDepConfig = ArtifactConfig("test", _.withSources) - val specs: ModuleID = "org.scala-tools.testing" %% "specs" - val scalacheck: ModuleID = "org.scala-tools.testing" %% "scalacheck" -} - -trait Libraries extends Repositories with TestLibraries { - self: DefaultProject => - - import ArtifactConfig.defaultArtifactConfig - - // val ant: ModuleID = "org.apache.ant" % "ant" - // val asmAll: ModuleID = "asm" % "asm-all" withSources() - // val commonsVFS: ModuleID = "org.apache.commons" % "commons-vfs-project" - // val easymock: ModuleID = "org.easymock" % "easymock" - // val guava: ModuleID = "com.google.guava" % "guava" - // val ivy: ModuleID = "org.apache.ivy" % "ivy" - // val jdt: ModuleID = "org.eclipse.jdt" % "core" notTransitive() - // val jetty: ModuleID = "org.mortbay.jetty" % "jetty" - // val jmock: ModuleID = "org.jmock" % "jmock" - // val jodaTime: ModuleID = "joda-time" % "joda-time" - // val liftJson: ModuleID = "net.liftweb" %% "lift-json" - // val maven: ModuleID = "org.apache.maven" % "maven-ant-tasks" - // val scalaARM: ModuleID = "com.github.jsuereth.scala-arm" %% "scala-arm" withSources() - // val scalaImproving: ModuleID = "org.improving" %% "scala-improving" - // val scalaSTM: ModuleID = "org.scala-tools" %% "scala-stm" - // val scalariform: ModuleID = "org.scalariform" %% "scalariform" - // val scalazCore: ModuleID = "org.scalaz" %% "scalaz-core" withSources() - // val scalazHttp: ModuleID = "org.scalaz" %% "scalaz-http" withSources() - // val slf4s: ModuleID = "com.weiglewilczek.slf4s" %% "slf4s" withSources() -} -EOF - -cat > project/build/Repositories.scala < - - val localMaven = "Local Maven" at "file://"+Path.userHome+"/.m2/repository" - val localIvy = "Local Ivy" at "file://"+Path.userHome+"/.ivy2/local" - val sonatype = "Sonatype" at "https://oss.sonatype.org/content/groups/public" - val scalaToolsSnapshots = "Scala Tools Snapshots" at "http://scala-tools.org/repo-snapshots/" - val jboss = "JBoss Repo" at "http://repository.jboss.org/maven2" -} -EOF - -cat > project/build/${PROJECT_CLASS}.scala < super.localScala - case path => - log.info("Found scala.local: " + path) - List(defineScala("$SCALA_LOCAL_VERSION", new java.io.File(path))) - } -} -EOF - -mkdir -p project/plugins -cat > project/plugins/Plugins.scala < project/build.properties < src/main/scala/Main.scala < src/test/scala/${SPEC_CLASS}.scala < $FILE < $FILE <> $FILE + cp $BASE/src/template/Plugins.scala project/plugins +fi + +ln -s $FILE + +cat > .gitignore < + + /** Default "dynamic revision" to use with ivy. + * See [[http://www.jaya.free.fr/ivy/doc/ivyfile/dependency.html]]. + * Likely alternatives: latest.milestone, latest.release + */ + def dynamicRevision = "latest.integration" + + /** Repositories. Comment in or out to taste. + */ + val localMaven = "Local Maven" at "file://"+Path.userHome+"/.m2/repository" + val localIvy = "Local Ivy" at "file://"+Path.userHome+"/.ivy2/local" + val sonatype = "Sonatype" at "https://oss.sonatype.org/content/groups/public" + val scalaToolsSnapshots = "Scala Tools Snapshots" at "http://scala-tools.org/repo-snapshots/" + val jboss = "JBoss Repo" at "http://repository.jboss.org/maven2" + + protected implicit lazy val implicitTransform: ArtifactTransform = + ArtifactTransform(inScope("test"), withSources) + + /*** Libraries ***/ + val specs: ModuleID = "org.scala-tools.testing" %% "specs" + val scalacheck: ModuleID = "org.scala-tools.testing" %% "scalacheck" + + // val ant: ModuleID = "org.apache.ant" % "ant" + // val asmAll: ModuleID = "asm" % "asm-all" withSources() + // val commonsVFS: ModuleID = "org.apache.commons" % "commons-vfs-project" + // val easymock: ModuleID = "org.easymock" % "easymock" + // val guava: ModuleID = "com.google.guava" % "guava" + // val ivy: ModuleID = "org.apache.ivy" % "ivy" + // val jdt: ModuleID = "org.eclipse.jdt" % "core" notTransitive() + // val jetty: ModuleID = "org.mortbay.jetty" % "jetty" + // val jmock: ModuleID = "org.jmock" % "jmock" + // val jodaTime: ModuleID = "joda-time" % "joda-time" + // val liftJson: ModuleID = "net.liftweb" %% "lift-json" + // val maven: ModuleID = "org.apache.maven" % "maven-ant-tasks" + // val scalaARM: ModuleID = "com.github.jsuereth.scala-arm" %% "scala-arm" withSources() + // val scalaImproving: ModuleID = "org.improving" %% "scala-improving" + // val scalaSTM: ModuleID = "org.scala-tools" %% "scala-stm" + // val scalariform: ModuleID = "org.scalariform" %% "scalariform" + // val scalazCore: ModuleID = "org.scalaz" %% "scalaz-core" withSources() + // val scalazHttp: ModuleID = "org.scalaz" %% "scalaz-http" withSources() + // val slf4s: ModuleID = "com.weiglewilczek.slf4s" %% "slf4s" withSources() +} + +trait ModuleIdDynamifactory extends Dynamifactory { + self: DefaultProject => + + protected type DepId = GroupArtifactID + protected type DepOut = ModuleID + protected def finishDependency(in: GroupArtifactID, revision: String): ModuleID = in % revision + + protected implicit lazy val implicitRevision: ArtifactRevision = + ArtifactRevision(_ => dynamicRevision) + + protected def inScope(scope: String): DepFn = _ % scope + protected def withSources: DepFn = _.withSources() + protected def intransitive: DepFn = _.intransitive() + protected def withJavadoc: DepFn = _.withJavadoc + + protected def withRevision(newRevision: String): DepFn = (m: ModuleID) => { + ModuleID(m.organization, m.name, newRevision, m.configurations, m.isChanging, m.isTransitive, m.explicitArtifacts, m.extraAttributes) + } +} + +trait Dynamifactory { + protected type DepId + protected type DepOut + protected type DepFn = DepOut => DepOut + protected def dynamicRevision: String + protected def finishDependency(in: DepId, revision: String): DepOut + + case class ArtifactRevision(revisionFn: DepId => String) { + } + case class ArtifactTransform(fns: DepFn*) { + def apply(x: DepOut): DepOut = if (fns.isEmpty) x else fns.reduceLeft(_ andThen _)(x) + } + case class ArtifactConfig(rev: ArtifactRevision, transform: ArtifactTransform) { } + + protected implicit def autoassembleConfig(implicit rev: ArtifactRevision, transform: ArtifactTransform): ArtifactConfig = + ArtifactConfig(rev, transform) + + protected implicit def autoconfigureDependencies(in: DepId)(implicit config: ArtifactConfig): DepOut = { + val ArtifactConfig(ArtifactRevision(revisionFn), transform) = config + + transform(finishDependency(in, revisionFn(in))) + } +} diff --git a/src/template/Libraries.scala b/src/template/Libraries.scala new file mode 100644 index 000000000..dfd66a661 --- /dev/null +++ b/src/template/Libraries.scala @@ -0,0 +1,62 @@ +import sbt._ + +case class ArtifactRevision(revision: String) +case class ArtifactConfig(confs: String, fn: ModuleID => ModuleID) +object ArtifactConfig { + implicit def defaultArtifactConfig: ArtifactConfig = new ArtifactConfig("", identity[ModuleID]) + implicit def testArtifactConfig: ArtifactConfig = new ArtifactConfig("test", identity[ModuleID]) +} + +trait LowPriorityLibraries { + self: DefaultProject => + + // "latest.integration", "latest.milestone", "latest.release" + def defaultRevision = "latest.integration" + protected implicit def defaultArtifactRevision = new ArtifactRevision(defaultRevision) + // protected implicit def defaultArtifactConfig = new ArtifactConfig("", identity[ModuleID]) + + protected implicit def autoConfig + (artifact: GroupArtifactID) + (implicit rev: ArtifactRevision, config: ArtifactConfig): ModuleID = + { + val ArtifactConfig(confs, fn) = config + fn( + if (confs == "") artifact % rev.revision + else artifact % rev.revision % config.confs + ) + } +} + +trait TestLibraries extends LowPriorityLibraries { + self: DefaultProject => + + private implicit val testDepConfig = ArtifactConfig("test", _.withSources) + val specs: ModuleID = "org.scala-tools.testing" %% "specs" + val scalacheck: ModuleID = "org.scala-tools.testing" %% "scalacheck" +} + +trait Libraries extends Repositories with TestLibraries { + self: DefaultProject => + + import ArtifactConfig.defaultArtifactConfig + + // val ant: ModuleID = "org.apache.ant" % "ant" + // val asmAll: ModuleID = "asm" % "asm-all" withSources() + // val commonsVFS: ModuleID = "org.apache.commons" % "commons-vfs-project" + // val easymock: ModuleID = "org.easymock" % "easymock" + // val guava: ModuleID = "com.google.guava" % "guava" + // val ivy: ModuleID = "org.apache.ivy" % "ivy" + // val jdt: ModuleID = "org.eclipse.jdt" % "core" notTransitive() + // val jetty: ModuleID = "org.mortbay.jetty" % "jetty" + // val jmock: ModuleID = "org.jmock" % "jmock" + // val jodaTime: ModuleID = "joda-time" % "joda-time" + // val liftJson: ModuleID = "net.liftweb" %% "lift-json" + // val maven: ModuleID = "org.apache.maven" % "maven-ant-tasks" + // val scalaARM: ModuleID = "com.github.jsuereth.scala-arm" %% "scala-arm" withSources() + // val scalaImproving: ModuleID = "org.improving" %% "scala-improving" + // val scalaSTM: ModuleID = "org.scala-tools" %% "scala-stm" + // val scalariform: ModuleID = "org.scalariform" %% "scalariform" + // val scalazCore: ModuleID = "org.scalaz" %% "scalaz-core" withSources() + // val scalazHttp: ModuleID = "org.scalaz" %% "scalaz-http" withSources() + // val slf4s: ModuleID = "com.weiglewilczek.slf4s" %% "slf4s" withSources() +} diff --git a/src/template/Plugins.scala b/src/template/Plugins.scala new file mode 100644 index 000000000..ea05fabe5 --- /dev/null +++ b/src/template/Plugins.scala @@ -0,0 +1,7 @@ +import sbt._ + +class Plugins(info: ProjectInfo) extends PluginDefinition(info) { + // def aquteRepo = "aQute Maven Repository" at "http://www.aqute.biz/repo" + // lazy val aquteModuleConfig = ModuleConfiguration("biz.aQute", aquteRepo) + // val bnd4sbt = "com.weiglewilczek.bnd4sbt" % "bnd4sbt" % "latest.release" +} diff --git a/src/template/Repositories.scala b/src/template/Repositories.scala new file mode 100644 index 000000000..c7f988f33 --- /dev/null +++ b/src/template/Repositories.scala @@ -0,0 +1,23 @@ +import sbt._ + +trait Repositories extends DefaultProject { + // self: DefaultProject => + + val localMaven = "Local Maven" at "file://"+Path.userHome+"/.m2/repository" + val localIvy = "Local Ivy" at "file://"+Path.userHome+"/.ivy2/local" + val sonatype = "Sonatype" at "https://oss.sonatype.org/content/groups/public" + val scalaToolsSnapshots = "Scala Tools Snapshots" at "http://scala-tools.org/repo-snapshots/" + val jboss = "JBoss Repo" at "http://repository.jboss.org/maven2" + + // -Dscala.local=2.9.0.local=/scala/trunk/build/pack + override def localScala = System.getProperty("scala.local") match { + case null => super.localScala + case str => + val (name, path) = str indexOf '=' match { + case -1 => ("local", str) + case idx => (str take idx toString, str drop idx + 1 toString) + } + log.info("Found scala.local setting '" + name + "' at: " + path) + List(defineScala(name, new java.io.File(path))) + } +}