4 notes
“An SBT plugin for dangerously fast development turnaround in Scala”

spray/sbt-revolver - GitHub



1 note

This post was reblogged from a soft sea.



5 notes
“SBT imports all the members of plugin classes into scope of a project using a wildcard import. This means all the plugins you use could have conflicting names that step on each other. Combined with potentially conflicting key names, plugins need to be very careful with how they define things.”

SBT and Plugin design



2 notes

Local external projects in sbt

One of the best features added in sbt 0.10 is the ability to depend on external projects. This is similar to the way you might have published a local snapshot with sbt 0.7, except vastly better. You don’t have to manually publish, update, or even compile anything when the library source changes.

Say that project Appy depends on unfiltered-netty-server. You want to test Appy against the current master branch, or perhaps you have your own fork and want to test changes before sending a pull request. All you have to do is add a file like this as project/build.scala

import sbt._
object Appy extends Build
{
  lazy val root =
    Project("", file(".")) dependsOn(unfiltered)
  lazy val unfiltered =
    ProjectRef(uri("../unfiltered"), "unfiltered-netty-server")
}

This assumes that Unfiltered is cloned into a directory “unfiltered” that is adjacent to Appy’s base directory. If you’re using the usual build.sbt to define Appy’s build, it is still effect; the only change you need to make is to remove the library from libraryDependencies.

The second parameter of ProjectRef is a subproject name. If you are depending on a library that does not use subprojects, you can leave that off.

Because sbt is so smart, you can even specify a git URI in the ProjectRef. But most of the time I prefer to use a local project ref, so I know exactly what code I’m depending on and can easily switch branches and test changes without committing them. And if you’ve already got the project cloned and built locally, sbt won’t have to do all that work again.

Did I mention this is really good for pull requests?

Update from Michael Bayne in the comments

I use a similar approach but have Build.scala autodetect whether or not to use an SBT dependency or a traditional artifact dependency based on whether a symlink to the project in question exists in the dependee’s directory:

class Local (locals :(String, String, ModuleID)*) {
  def addDeps (p :Project) = (locals collect {
    case (id, subp, dep) if (file(id).exists) => symproj(file(id), subp)
  }).foldLeft(p) { _ dependsOn _ }
  def libDeps = locals collect {
    case (id, subp, dep) if (!file(id).exists) => dep
  }
  private def symproj (dir :File, subproj :String = null) =
    if (subproj == null) RootProject(dir) else ProjectRef(dir, subproj)
}

object FooBuild extends Build {
  val locals = new Local(
    ("barproj", null,    "com.foo" % "barproj" % "1.0-SNAPSHOT"),
    ("bazproj", "subproj", "com.foo" % "bazproj-subproj" % "1.0-SNAPSHOT")
  )

  lazy val foo = locals.addDeps(Project(
    "foo", file("."), settings = Defaults.defaultSettings ++ Seq(
      // ...      libraryDependencies ++= locals.libDeps ++ Seq(
        // ...        "junit" % "junit" % "4.+" % "test",
        "com.novocode" % "junit-interface" % "0.7" % "test->default"
      )
    )
  )
}

Future plugin?



14 notes

“In sbt, the syntax part, including tab completion, is specified with parser combinators.”

harrah/xsbt Commands - GitHub



8 notes



4 notes



3 notes

Page 1 of 3

}