You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@buildr.apache.org by Assaf Arkin <ar...@intalio.com> on 2008/09/17 02:26:02 UTC

Replacing VERSION/REQUIRES with version/dependencies and using YAML files to pick versions of specific libraries

A common request we get is being able to easily set a version for a
particular library.  For example, using JMock 1.2 instead of 2.0.
Right now that involves some tricky messing with the VERSION and
REQUIRES constants, which sometimes works, sometimes doesn't and never
feels quite right.


I decided to try something different, and use the build.yml file to
specify versions for 3rd party libraries.  With the new code you'll be
able to have a YAML file that reads something like:

jmock: 2.0
junit: 4.5

This will tell JUnit to use version 4.5, and JMock to use 2.0.  The
same is true for Ant, TestNG, JBehave, ScaleTest/Check/Spec, etc.

For example, Ant now has a build.yml setting which specifies which
version of Ant to use (the default being 1.7.1).  You can edit
build.yml to pick a different version that will always be used when
running this build.

There's no official API, but by convention you can get the version
number from Ant.version (was: Ant::VERSION) and the list of
dependencies from Ant.dependencies (was: Ant::REQUIRES).  These
methods are there in case the truly motivated need to mess with them,
maybe pick a random version of JUnit on each build, or replace JMock
with JSerious.


The change itself involved messing with a few files, and somehow ended
yak shaving a slight reorg.  Scala stuff now lives in buildr/scala and
the Buildr::Scala namespace, Groovy in buildr/groovy and
Buildr::Groovy.  Yes, they're all JVM languages, but piling all the
JVM languages into the java path didn't really help in managing the
code.

Similar change to the spec directory, mimicking the lib hierarchy, so
spec/java is separate form spec/packaging or spec/scala.  We have a
lot of code, this change get it a bit under control while testing the
new code, one language at a time.


I'm putting this first on Github for everyone to review, check, comment:
http://github.com/assaf/buildr/commits/master

The official issue is 148 (configure JUnit from YAML file), also
related to 140 (get rid of const_defined?), 115/138 (broken
repositories.local = )

https://issues.apache.org/jira/browse/BUILDR-148
https://issues.apache.org/jira/browse/BUILDR-140
https://issues.apache.org/jira/browse/BUILDR-115
https://issues.apache.org/jira/browse/BUILDR-138

Assaf

Re: Replacing VERSION/REQUIRES with version/dependencies and using YAML files to pick versions of specific libraries

Posted by Assaf Arkin <ar...@intalio.com>.
On Tue, Sep 16, 2008 at 11:57 PM, Victor Hugo Borja <vi...@gmail.com> wrote:
> Assaf,
>
> On Tue, Sep 16, 2008 at 7:26 PM, Assaf Arkin <ar...@intalio.com> wrote:
>
>>
>> There's no official API, but by convention you can get the version
>> number from Ant.version (was: Ant::VERSION) and the list of
>> dependencies from Ant.dependencies (was: Ant::REQUIRES).  These
>> methods are there in case the truly motivated need to mess with them,
>> maybe pick a random version of JUnit on each build, or replace JMock
>> with JSerious.
>
>
> We will need to document on modules having a dependencies method, the key
> users can use in the yaml file. I like having
>   ant: 1.7
> but I'd also like something more qualified (and more rubyish..) like
>   Buildr::Ant::version: 1
> some modules may need different versions for the same artifact.
>
> How could we handle cases like setting a fixed JUnit/TestNG version for
> JtestR  to use.

JBehave handles it by taking the JUnit dependencies and adding its
own, so you have one setting to control JUnit (for everything) another
to control jbehave.

> Currently JtestR simply includes TestNG.dependencies, would this case
> require the user
> to override JtestR::dependencies ?
>
>
> http://github.com/vic/buildr/commit/663cf568d34f8ca1ded2bc93332864cf0805e60c#L0R187
>
>
> Another interesting case[1] is how to set the dependencies or versions
> per project. Say a project needs a particular JMock or XMLBeans version.

You use XMLBeans via the compile_xml_beans method, so it's just a
matter of adding an optional argument which tells it which version of
XMLBeans to use and calculating the dependencies from that.  I don't
think it will be a big change to make if someone asks for it.

Likewise, for test frameworks we can have an instance-level method you
can use, which by default picks its value from the class-level method,
which takes it from build.yml/constant.

>
>
> I'm putting this first on Github for everyone to review, check, comment:
>> http://github.com/assaf/buildr/commits/master
>
>
> Great, I really like these reorg changes.
>
> I've rebased my JtestR branch to use your changes, and
> changed it not to use REQUIRES constant.
>
>
>> The official issue is 148 (configure JUnit from YAML file), also
>> related to 140 (get rid of const_defined?), 115/138 (broken
>> repositories.local = )
>>
>> https://issues.apache.org/jira/browse/BUILDR-148
>> https://issues.apache.org/jira/browse/BUILDR-140
>> https://issues.apache.org/jira/browse/BUILDR-115
>> https://issues.apache.org/jira/browse/BUILDR-138
>>
>> [1] https://issues.apache.org/jira/browse/BUILDR-4
>
> --
> vic
>
> Quaerendo invenietis.
>

Re: Replacing VERSION/REQUIRES with version/dependencies and using YAML files to pick versions of specific libraries

Posted by Assaf Arkin <ar...@intalio.com>.
On Wed, Sep 17, 2008 at 12:44 AM, Victor Hugo Borja <vi...@gmail.com> wrote:
> On Wed, Sep 17, 2008 at 1:57 AM, Victor Hugo Borja <vi...@gmail.com>wrote:
>
>> [...] I'd also like something more qualified (and more rubyish..) like
>>    Buildr::Ant::version: 1
>>
>
> What do you think about this:
>
> To let the user specify JUnit::dependencies without having to override the
> method:
>
> A build.yml having something like..
>
>  Buildr::JUnit::dependencies:
>    - junit:junit:jar:4.4
>    - jserious:jserious:jar:1.0
>    - jserious:jserious-tools:jar:1.0
>
> And on Buildr::JUnit @buildr/java/tests.rb:185
>
>      def dependencies
>        @dependencies ||= Buildr.settings.build[name+'::dependencies'] ||
>            ["junit:junit:jar:#{version}"]+ JMock.dependencies
>      end

There were several requests to change the version of JUnit, my e-mail
archive has one request for JMock, and I remember one for TestNG
(can't find it, though).  So multiple requests by people who could use
the one-line setting feature to solve their problem.

Changing JMock to JSerious is an exercise we should leave for the
truly motivated. It's not a commonly requested feature, actually
nobody presented a use case for it.  Because it's hypothetical, I
don't mind if it requires a bit of open class gymnastics to solve.

test.using(:junit) includes the JUnit/JMock libraries by default.
Because they're included by default, the only way to switch to a
different version is by turning some switch that the framework uses,
in this case a setting in buildr.yml.  On the other hand, if you want
to include JSerious because you like it better, you can do that by
calling test.with, that's the more generic and common solution,

I want to avoid solving a problem that doesn't exist, even if we do
have a very elegant solution in the ready.


The main selling point of Buildr is that it's Ruby.  It's very easy to
make ad hoc changes, one-of features, with a few lines of code we can
share on the mailing list or the wiki.  Because it's DIY, we don't
have to anticipate and address every possible use case, especially
when some use cases have an audience of one, or audience of none.

Instead, we can just wait for enough people to point out the problem,
once we have a pattern we can extract the minimal solution that will
work for all of them.  Until then, Buildr is very self-service in
nature, take advantage of that.

Every feature we add has a cost.  A one-line change doesn't look like
much, but when you factor everything, it can be horribly expensive.
Besides the code, you have test cases.  You need to document it, the
more documentation we have, the harder it is for people to
find/remember which feature to use, so they spend more time being less
productive with Buildr.  We care about backward compatibility, that
makes changes much more complex as you need to support old usage along
with new one (*).  And, when you have to apply the same thing
consistently, multiply that cost several times over.

So the solution, even if it looks deceivingly simple, has to justify
itself by the number of people who actually feel the pain and don't
have an existing recourse.  It raises the bar for accepting new
features, but in the long term it helps us deliver more and better
features.

Most important, it keeps Buildr from turning enterprisey too quickly.

Assaf


(*) Half the code involved in these changes was written to retain
backwards compatibility, more than half the time spent figuring out
how to support the new methods and the deprecated constants, and turns
out it only partially works.

>
> --
> vic
>
> Quaerendo invenietis.
>

Re: Replacing VERSION/REQUIRES with version/dependencies and using YAML files to pick versions of specific libraries

Posted by Victor Hugo Borja <vi...@gmail.com>.
On Wed, Sep 17, 2008 at 1:57 AM, Victor Hugo Borja <vi...@gmail.com>wrote:

> [...] I'd also like something more qualified (and more rubyish..) like
>    Buildr::Ant::version: 1
>

What do you think about this:

To let the user specify JUnit::dependencies without having to override the
method:

A build.yml having something like..

  Buildr::JUnit::dependencies:
    - junit:junit:jar:4.4
    - jserious:jserious:jar:1.0
    - jserious:jserious-tools:jar:1.0

And on Buildr::JUnit @buildr/java/tests.rb:185

      def dependencies
        @dependencies ||= Buildr.settings.build[name+'::dependencies'] ||
            ["junit:junit:jar:#{version}"]+ JMock.dependencies
      end

-- 
vic

Quaerendo invenietis.

Re: Replacing VERSION/REQUIRES with version/dependencies and using YAML files to pick versions of specific libraries

Posted by Victor Hugo Borja <vi...@gmail.com>.
Assaf,

On Tue, Sep 16, 2008 at 7:26 PM, Assaf Arkin <ar...@intalio.com> wrote:

>
> There's no official API, but by convention you can get the version
> number from Ant.version (was: Ant::VERSION) and the list of
> dependencies from Ant.dependencies (was: Ant::REQUIRES).  These
> methods are there in case the truly motivated need to mess with them,
> maybe pick a random version of JUnit on each build, or replace JMock
> with JSerious.


We will need to document on modules having a dependencies method, the key
users can use in the yaml file. I like having
   ant: 1.7
but I'd also like something more qualified (and more rubyish..) like
   Buildr::Ant::version: 1
some modules may need different versions for the same artifact.

How could we handle cases like setting a fixed JUnit/TestNG version for
JtestR  to use.
Currently JtestR simply includes TestNG.dependencies, would this case
require the user
to override JtestR::dependencies ?


http://github.com/vic/buildr/commit/663cf568d34f8ca1ded2bc93332864cf0805e60c#L0R187


Another interesting case[1] is how to set the dependencies or versions
per project. Say a project needs a particular JMock or XMLBeans version.


I'm putting this first on Github for everyone to review, check, comment:
> http://github.com/assaf/buildr/commits/master


Great, I really like these reorg changes.

I've rebased my JtestR branch to use your changes, and
changed it not to use REQUIRES constant.


> The official issue is 148 (configure JUnit from YAML file), also
> related to 140 (get rid of const_defined?), 115/138 (broken
> repositories.local = )
>
> https://issues.apache.org/jira/browse/BUILDR-148
> https://issues.apache.org/jira/browse/BUILDR-140
> https://issues.apache.org/jira/browse/BUILDR-115
> https://issues.apache.org/jira/browse/BUILDR-138
>
> [1] https://issues.apache.org/jira/browse/BUILDR-4

-- 
vic

Quaerendo invenietis.