Skip to content

Commit

Permalink
Merge pull request #4 from jsuereth/master
Browse files Browse the repository at this point in the history
Step #1: Make the template project a plugin that other can use
  • Loading branch information
paulp committed Sep 14, 2011
2 parents 7ffbf53 + 8836f37 commit 7e759c1
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 122 deletions.
23 changes: 23 additions & 0 deletions README.md
Expand Up @@ -7,6 +7,7 @@ project directory, the runner will figure out the versions of sbt
and scala required by the project and download them if necessary.

There's also a template project sbt coming together, but it's unfinished.
See below for how to pull the template project in as a plugin.
However the runner is quite useful already.

Here's a sample use of the runner: it creates a new project using a
Expand Down Expand Up @@ -97,3 +98,25 @@ Current -help output:

In the case of duplicated or conflicting options, the order above
shows precedence: JAVA_OPTS lowest, command line options highest.


## Template project

To gain access to the awesome, simply add the following <project>/project/plugins/project/Build.scala file:

import sbt._
object PluginDef extends Build {
override def projects = Seq(root)
lazy val root = Project("plugins", file(".")) dependsOn(extras)
lazy val extras = uri("git://github.com/jsuereth/sbt-extras")
}

Now to continue the amazement, simply extend the TemplateBuild trait in your project. For example, in your
<project>/project/Build.scala file add:

import sbt._
import template.TemplateBuild

object MyAwesomeBuild extends TemplateBuild {}

The Template build isn't quite finished. There will most likely be a build.sbt DSL variant that does not require a project scala file.
8 changes: 8 additions & 0 deletions build.sbt
@@ -0,0 +1,8 @@
sbtPlugin := true

name := "sbt-extras-plugin"

organization := "org.improving"

version <<= (sbtVersion)("0.1.0-%s".format(_))

119 changes: 0 additions & 119 deletions project/Build.scala

This file was deleted.

120 changes: 117 additions & 3 deletions src/main/scala/Main.scala
@@ -1,7 +1,121 @@
package template

object Main {
def main(args: Array[String]): Unit = {
println("Skeleton main, reporting for duty on " + util.Properties.versionString)
import sbt._
import Keys._
import Load.{ BuildStructure, StructureIndex }
import scala.collection.{ mutable, immutable }

object SbtExtrasPlugin extends Plugin {}

trait SbtCreateConfig {
def name: String
def organization: String
def version: String
def scalaVersion: String
}
object SbtCreateConfig {
private def prop(propName: String, alt: String) = System.getProperty(propName) match {
case null => alt
case value => value
}
implicit def defaultProjectConfig = new SbtCreateConfig {
def name = prop("sbt-create.name", "project-name-here")
def organization = prop("sbt-create.organization", "your.organization.here")
def version = prop("sbt-create.version", "0.1-SNAPSHOT")
def scalaVersion = prop("sbt.scala.version", "2.9.0-1")
}
}

class TemplateBuild(implicit sbtCreateConfig: SbtCreateConfig) extends Build {
// BuildStructure contains:
// units: Map[URI, LoadedBuildUnit]
// root: URI
// settings: Seq[Setting[_]]
// data: Settings[Scope]
// index: StructureIndex
// streams: Streams
// delegates: Scope => Seq[Scope]
// scopeLocal: ScopeLocal

private val cachedExtraction = new collection.mutable.HashMap[State, WState]
private implicit def stateWrapper(state: State): WState =
cachedExtraction.getOrElseUpdate(state, new WState(state))
private implicit def revealStructure(state: State): BuildStructure =
stateWrapper(state).structure
private implicit def revealStructureIndex(state: State): StructureIndex =
revealStructure(state).index
private implicit def revealSession(state: State): SessionSettings =
stateWrapper(state).session

private class WState(state: State) {
val extracted = Project extract state

def projectId = extracted.currentProject.id
def structure = extracted.structure
def session = extracted.session
def currentRef = extracted.currentRef
def rootProject = structure.rootProject
def allProjects = structure.allProjects

def index = structure.index
def taskToKey = index.taskToKey
def keyMap = index.keyMap // Map[String, AttributeKey[_]]
def keyIndex = index.keyIndex
def currentKeys = keyIndex keys Some(currentRef) map index.keyMap
def sortedKeys = currentKeys.toSeq sortBy (_.label)
}

private class Tap[T](target: T) {
def show(): Unit = target match {
case xs: TraversableOnce[_] => xs foreach println
case _ => println(target)
}
def tap[U](f: T => U): T = {
f(target)
target
}
}
private implicit def createTapper[T](target: T): Tap[T] = new Tap(target)

def currentBranch = ("git status -sb".lines_! headOption) getOrElse "-" stripPrefix "## "

val buildShellPrompt = {
(state: State) => "%s:%s> ".format(
state.projectId,
currentBranch
)
}

lazy val testSettings = Seq(
libraryDependencies ++= Seq(
"org.scala-tools.testing" % "specs_2.9.0-1" % "1.6.8" % "test"
),
libraryDependencies <+= (scalaVersion)(v => "org.scala-lang" % "scala-compiler" % v)
)

lazy val buildSettings = Seq(
resolvers += ScalaToolsSnapshots,
organization := sbtCreateConfig.organization,
version := sbtCreateConfig.version,
scalaVersion := sbtCreateConfig.scalaVersion,
// retrieveManaged := true,
shellPrompt := buildShellPrompt
// logLevel := Level.Debug,
)

lazy val templateConfig = Project(
id = sbtCreateConfig.name,
base = file("."),
aggregate = Nil,
dependencies = Nil,
delegates = Nil,
settings = Defaults.defaultSettings ++ buildSettings ++ testSettings ++ Seq(
commands += helpNames
)
)

// A sample command definition.
def helpNames = Command.command("help-names") { (state: State) =>
state tap (_.sortedKeys map (_.label) show)
}
}

0 comments on commit 7e759c1

Please sign in to comment.