nosewheelie

Technology, mountain biking, politics & music.

Path composition in Obi

without comments

Over the last few days I’ve been progressing steadily with Obi, my Scala-based build tool. I’m starting at the bottom level, building some low level primitives that can then be combined into higher level layers (examples at the end of this post).

Here’s the first simple example, it represents a path to a file on the filesystem.

import org.obi.io.file.FilePath._

// Create a FilePath
val p1 = filepath("/foo/bar.jar")
val p2 = path("/foo/bar.jar")

// Implicit conversion from String to FilePath
val p3: FilePath = "/foo/bar.jar"

// Implicit conversion from FilePath to String
val p4: String = path("/foo/bar.jar")
 

FilePaths can also be combined to form classpaths (I’m working on javac). Here’s some examples of the way you can create classpaths, each of the these will give the classpath string /foo/bar.jar:/foo/baz.jar (on a *nix box). All are syntactically valid Scala, syntax requests/suggestions are welcome, these are some that I came up with, that’ll probably change once it’s used inline in the compilation task.

import org.obi.attr.ClassPath._
import org.obi.io.file.FilePath._

val cp1 = classpath("/foo/bar.jar", "/foo/baz.jar")
val cp2 = classpath(List("/foo/bar.jar", "/foo/baz.jar"))
val cp3 = classpath < < "/foo/bar.jar" << "/foo/baz.jar"
val cp4 = classpath << List("/foo/bar.jar", "/foo/baz.jar")
val cp5 = "/foo/bar.jar" <<: classpath("/foo/baz.jar")
val cp6 = List("/foo/bar.jar", "/foo/baz.jar") <<: classpath
val cp7 = "/foo/bar.jar" << classpath << "/foo/baz.jar"
val cp8 = classpath("/foo/bar.jar") << classpath("/foo/baz.jar")
val cp9 = classpath("/foo/bar.jar") ::: classpath("/foo/baz.jar")
val cp10 = classpath("/foo/bar.jar") + classpath("/foo/baz.jar")
val cp11 = classpath("/foo/bar.jar") + "/foo/baz.jar"
val cp12 = "/foo/bar.jar" :: classpath("/foo/baz.jar")
val cps: String = classpath << "/foo/bar.jar" << "/foo/baz.jar"

With these kind of primitives, it'd be pretty easy to create abstractions such as "library" which would enable a feature such as Maven's dependency management using a syntax similar to buildr's. Here's a simple example of what's currently implemented, syntax can be cleaned up.

val log4j = path("log4j.jar")
val cglib = path("cglib.jar")
val commons_logging = path("commons-logging.jar") < <: log4j
val ehcache = commons_logging << "ehcache.jar"
val hibernate = ehcache + commons_logging + cglib

There's no way to "resolve" dependencies as yet (and won't be for a while) and you get duplicates in the path. But, this would open up things such as (I've no idea if this is valid syntax, I doubt it is):

val hibernate = library(
        dependencies |= ehcache + commons_logging + cglib,
        version "3.2.5.ga")

All in all I think the syntax is quite readable and flexible, it’s also strongly typed. Writing these kinds of DSLs has proved very easy using Scala, I’m quite impressed.

Written by Tom Adams

January 22nd, 2008 at 8:58 pm

Posted in Obi,Scala

Leave a Reply