From matthieu.riou at gmail.com Tue May 1 10:46:37 2007
From: matthieu.riou at gmail.com (Matthieu Riou)
Date: Tue, 1 May 2007 07:46:37 -0700
Subject: [Raven-devel] rake-less prototype
In-Reply-To:
References:
Message-ID:
Hi Matthew,
I've been musing about this more declarative approach for a few days. I
think you might want to take a look at Buildr (http://buildr.rubyforge.org).
I've been mildly involved in it as it's been designed by one of my coworkers
(Assaf Arkin) and have been using it a bit at work. To get a feeling of how
a build script looks like, there's an extensive example here:
http://svn.apache.org/repos/asf/incubator/ode/trunk/Rakefile
The approach is definitely more declarative than what Raven has been so far.
I've been thinking of Raven as the Ant version of a Rake-based build system
for Java as Buildr is closer to Maven (without the issues).
Let me know what you think.
Cheers,
Matthieu
On 4/27/07, Matthew Foemmel wrote:
>
> Hi all,
>
> I came up with a little hack the other day, and I'd like to get
> people's feedback on it. I've been growing a bit frustrated trying to
> get build channels and multi-project stuff all working cleanly with
> Rake (which has required a fair bit of monkey-patching) so out of
> curiousity I decided to see what I could come up with given a "clean
> slate" i.e. without using any Rake code. I'm not suggesting Raven
> should switch to this model, but I kind of like the way it turned
> out, and would be interested in hearing if anyone thinks there are
> ideas here worth pursuing. I've attached a file with some sample code
> - it doesn't rely on any existing code (it doesn't do much, in fact)
> so you should be able to just download and run it with vanilla ruby.
>
> Here's an example of what a build script looks like with the prototype:
>
> MainCompile = Javac.new {
> @classpath << "foo.jar"
> }
>
> TestCompile = Javac.new(MainCompile, JUnit::Classpath) {
> @srcdir = "target/test/java"
> }
>
> Test = JUnit::Run.new(TestCompile)
>
> The main differences between the prototype and the current raven2
> code are:
>
> * Unlike Rake, there is no conceptual difference between a task
> *instance* and a task *class* - you can call "new" on any task to
> create an extension of that task
> * Tasks are objects that the build script must keep track of (usually
> by storing them in constants e.g. "MainCompile" above) unlike Rake
> where they are kept in a hashtable and looked up by name
> * The @ symbol can be used to define build attributes (I've been
> calling these build "channels" before, but given the new syntax i
> think "attribute" is more appropriate)
>
> Build attributes are handled as follows:
>
> * A task can extend any other task (by calling "new" on it) in which
> case build attributes are automatically passed from the child to the
> parent
> * A task can depend on other tasks, in which case the build
> attributes for the latter are merged together and passed into the
> former (the same way that Raven works now)
>
> Here's a quick walkthough:
>
>
> === Creating Tasks ===
>
> The obligatory hello world script looks like this:
>
> Hello = Task.new {
> log_info "Hello, World!"
> }
>
> Here we're just creating a new Task object with a single log
> statement. Calling "build Hello" would print out "Hello, World!"
> obviously.
>
>
> === Extending Tasks ===
>
> Now, let's say we wanted to make this task more generic, so that you
> could optionally pass in the name of the person we want to greet. We
> could do this like so:
>
> Hello = Task.new {
> @name ||= "World"
> log_info "Hello, #{@name}!"
> }
>
> In this case, calling "build Hello" would do the same thing as in the
> previous example (since we set the default value for "@name" to be
> "World" in the Hello task). However, we can now also define a task to
> greet "Homer":
>
> GreetHomer = Hello.new {
> @name = "Homer"
> }
>
> Here we're extending the Hello task, by calling "new" on it and
> passing in a block. (Hello isn't a class, it just happens to have a
> method called "new"). So calling "new" on the Task class returns a
> new Task object, on which you can call "new" again, and so on. So
> from the user's point of view there's no real difference between a
> task class and a task instance. They're all just tasks.
>
> When the GreetHomer task is executed, its block is run (where we set
> the value of @name to be "Homer") then its parent block is run (where
> we print out the greeting). The build attribute "@name" is
> automatically passed from the child to the parent through a bit of
> metaprogramming magic. In a sense this is like inheritance, except we
> don't need to specify which method we're overloading, and we don't
> need to explicitly call "super".
>
>
> === Dependencies ===
>
> Dependencies can be declared by passing other tasks as arguments to
> the "new" method. For example, let's say we wanted to set up our
> classpath, then call Javac:
>
> Classpath = Task.new { @classpath = ["foo.jar"] }
>
> Compile = Javac.new(Classpath)
>
> Build attributes are passed up the same way they are currently in
> Raven (i.e. the @classpath attribute defined in MainClasspath will be
> visible in MainCompile).
>
> Note that I had to scrap the "=>" notation that rake uses to
> declaring dependencies, since the name of the task is no longer
> passed into the task constructor.
>
>
> === Anonymous Tasks ===
>
> Sometimes you want to group tasks together, but don't necessarily
> want to define a separate top-level task w/associated dependencies
> for each one. The "call" command lets you run tasks from within other
> tasks. For example, say we want to compile some files and copy some
> resources over in a single build target:
>
> Compile = Task.new {
> call Javac.new {
> @srcdir = "src/main/java"
> @destdir = "target/main"
> }
> call Copy.new {
> @srcdir = "src/main/resources";
> @destdir = "target/main"
> @include = "**/*.properties"
> }
> }
>
>
> === Modules ===
>
> The use of capitalize names for tasks may seems strange, but I've
> done that so that they can be treated as module constants, and
> therefore be referred to from other modules. This takes the place of
> Rake namespaces. For example:
>
> module Jdk
> Javac = Task.new {
> ...
> }
> Jar = Task.new {
> ...
> }
> Javadoc = Task.new {
> ...
> }
> end
>
> module MyApp
>
> # Here we use the fully qualified name
> MainCompile = Jdk::Javac {
> ...
> }
>
> # Here we include the module and use the short name
> include Jdk
> TestCompile = Jdk::Javac(MainCompile) {
> ...
> }
>
> end
>
>
> === Gems ===
>
> The nice thing about using modules instead of Rake namespaces is that
> we can now bundle up sets of tasks (and their associated files) and
> distribute them as gems. For example, we could wrap all the JDK tasks
> up in a gem and use it like this:
>
> require_gem 'jdk'
>
> MainCompile = Jdk::Javac {
> @srcdir = "mysrc"
> }
>
> For tools like JUnit (or XDoclet, or Antlr, etc) we might want to
> provide two tasks: one to set up the classpath, and one for the
> actual tool itself. This would be fairly easy:
>
> module JUnit
> Classpath = Task.new {
> @classpath = "junit.jar"
> }
>
> Run = Task.new {
> # execute the junit tests
> ...
> }
> end
>
> Then if you wanted to use JUnit from your build script you could do
> something like this:
>
> require_gem 'junit'
>
> CompileTests = Javac.new(JUnit::Classpath) {
> ...
> }
>
> RunTests = JUnit::Run.new {
> ...
> }
>
>
> === Code ===
>
> I've attached some sample code showing how this might work - let me
> know what you think...
>
>
>
> Cheers,
> Foemmel
> _______________________________________________
> Raven-devel mailing list
> Raven-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/raven-devel
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070501/95a8ad4f/attachment-0001.html
From nobody at rubyforge.org Sat May 12 16:11:30 2007
From: nobody at rubyforge.org (nobody at rubyforge.org)
Date: Sat, 12 May 2007 16:11:30 -0400 (EDT)
Subject: [Raven-devel] [192] branches/v1.x/lib/raven: Fixing a few path
issues (/ vs \)
Message-ID: <20070512201131.0B5145240ADB@rubyforge.org>
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070512/c575350e/attachment.html
From nobody at rubyforge.org Sat May 12 17:27:30 2007
From: nobody at rubyforge.org (nobody at rubyforge.org)
Date: Sat, 12 May 2007 17:27:30 -0400 (EDT)
Subject: [Raven-devel] [193] branches/v1.x/lib/raven: Updating for latest
gem versions
Message-ID: <20070512212730.E5B475240AC5@rubyforge.org>
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070512/8be4df5a/attachment.html
From nobody at rubyforge.org Sun May 13 00:16:23 2007
From: nobody at rubyforge.org (nobody at rubyforge.org)
Date: Sun, 13 May 2007 00:16:23 -0400 (EDT)
Subject: [Raven-devel] [194] branches/v1.x/lib/raven: Fixed a few glitches
for windows, support for different rubygems versions.
Message-ID: <20070513041623.4231F5240B44@rubyforge.org>
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070513/0facaf24/attachment.html
From nobody at rubyforge.org Sun May 13 00:20:45 2007
From: nobody at rubyforge.org (nobody at rubyforge.org)
Date: Sun, 13 May 2007 00:20:45 -0400 (EDT)
Subject: [Raven-devel] [195] branches/v1.x/rakefile: Increasing minor
version number for minor release.
Message-ID: <20070513042045.2B4035240B44@rubyforge.org>
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070513/e5f78ebd/attachment.html
From nobody at rubyforge.org Sun May 13 00:28:15 2007
From: nobody at rubyforge.org (nobody at rubyforge.org)
Date: Sun, 13 May 2007 00:28:15 -0400 (EDT)
Subject: [Raven-devel] [196] branches/v1.x/site: Updating latest release
number on site.
Message-ID: <20070513042815.A931B5240B48@rubyforge.org>
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/raven-devel/attachments/20070513/6472d4e3/attachment-0001.html