You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@buildr.apache.org by Sebastiano Pilla <pi...@progiweb.com> on 2010/12/07 17:30:44 UTC

Circular dependency with custom layout

I'm trying to use buildr in a multi-module ATG project, and the unit 
testing tool we use requires the test resources to end in the same 
directory as the test classes. I have defined a custom layout such as:

# define the layout for our projects
# src/main/java -> classes, src/test/java -> target/test-classes
# src/test/resources -> target/test-classes
StandardLayout = Layout.new
StandardLayout[:source, :main, :java] = 'src/main/java'
StandardLayout[:target, :main, :classes] = 'classes'
StandardLayout[:source, :main, :resources] = 'resources'
StandardLayout[:source, :test, :java] = 'src/test/java'
StandardLayout[:source, :test, :resources] = 'src/test/resources'
StandardLayout[:target, :test, :classes] = 'target/test-classes'
StandardLayout[:target, :test, :resources] = 'target/test-classes'

and I have assigned this layout to the project and subproject.

The problem is that when I run buildr I get the following circular 
dependency error:

D:\dev\progicommerce\src>%JRUBY_HOME%\bin\jruby -S buildr
(in D:/dev/progicommerce/src, development)
D:/dev/progicommerce/src/buildfile:4 warning: already initialized 
constant VERSION
D:/dev/progicommerce/src/buildfile:7 warning: already initialized 
constant VERSION
Building ProgiCommerce
Buildr aborted!
←[31mRuntimeError : Circular dependency detected: TOP => default => 
build => ProgiCommerce:build => ProgiCommerce:ATGDUST:build => 
ProgiCommerce:ATGDUST:test => ProgiCommerce:ATGDUST:test:compile => 
ProgiCommerce:ATGDUST:test:resources => 
D:/dev/progicommerce/src/ATGDUST/target/test-classes => 
ProgiCommerce:ATGDUST:test:compile←[0m

(See full trace by running task with --trace)

Is there a way to have my test resources end in target/test-classes 
along with the test classes?

Sebastiano

Re: Circular dependency with custom layout

Posted by Sebastiano Pilla <pi...@progiweb.com>.
Alex Boisvert wrote:
> On Tue, Dec 7, 2010 at 8:30 AM, Sebastiano Pilla<pi...@progiweb.com> 
> wrote:
>
>> I'm trying to use buildr in a multi-module ATG project, and the unit
>> testing tool we use requires the test resources to end in the same 
>> directory
>> as the test classes. I have defined a custom layout such as:
>>
>> # define the layout for our projects
>> # src/main/java -> classes, src/test/java -> target/test-classes
>> # src/test/resources -> target/test-classes
>> StandardLayout = Layout.new
>> StandardLayout[:source, :main, :java] = 'src/main/java'
>> StandardLayout[:target, :main, :classes] = 'classes'
>> StandardLayout[:source, :main, :resources] = 'resources'
>> StandardLayout[:source, :test, :java] = 'src/test/java'
>> StandardLayout[:source, :test, :resources] = 'src/test/resources'
>> StandardLayout[:target, :test, :classes] = 'target/test-classes'
>> StandardLayout[:target, :test, :resources] = 'target/test-classes'
>>
>> and I have assigned this layout to the project and subproject.
>>
>> The problem is that when I run buildr I get the following circular
>> dependency error:
>>
>> D:\dev\progicommerce\src>%JRUBY_HOME%\bin\jruby -S buildr
>> (in D:/dev/progicommerce/src, development)
>> D:/dev/progicommerce/src/buildfile:4 warning: already initialized 
>> constant
>> VERSION
>> D:/dev/progicommerce/src/buildfile:7 warning: already initialized 
>> constant
>> VERSION
>> Building ProgiCommerce
>> Buildr aborted!
>> ←[31mRuntimeError : Circular dependency detected: TOP => default => 
>> build
>> => ProgiCommerce:build => ProgiCommerce:ATGDUST:build =>
>> ProgiCommerce:ATGDUST:test => ProgiCommerce:ATGDUST:test:compile =>
>> ProgiCommerce:ATGDUST:test:resources =>
>> D:/dev/progicommerce/src/ATGDUST/target/test-classes =>
>> ProgiCommerce:ATGDUST:test:compile←[0m
>>
>> (See full trace by running task with --trace)
>>
>> Is there a way to have my test resources end in target/test-classes 
>> along
>> with the test classes?
>>
>
> Hi Sebastiano,
>
> It's not currently possible to map both (:target, :test, :resources) and
> (:target, :test, :classes) to the same physical directory due to the way
> resource copying/filtering is implemented. Resource dependencies end up
> being wired to the destination directory rather than the abstract task 
> (e.g.
> project:test:resources). I think that's a minor design flaw.
>
> You can work around this problem by adding the following to your project,
>
> task :copy_resources do
> Dir[_('target/test/resources/*')].each { |f| cp_r f,
> _('target/test-classes') }
> end
> test.enhance [:copy_resources]
>
> which copies over all test resources (after filtering) into
> target/test-classes before tests run.
>
> If you don't want to put this boilerplate in each of your project, you 
> can
> turn it into an
> Extension<http://buildr.apache.org/rdoc/classes/Buildr/Extension.html>
> such
> as,
>
> module ResourcesInTestClasses
> include Extension
>
> after_define do |project|
> task :copy_resources do
> Dir[project.path_to('target/test/resources/*')].each do |f|
> cp_r f, project.path_to('target/test-classes')
> end
> end
> project.test.enhance [:copy_resources]
> end
>
> class Buildr::Project
> include ResourcesInTestClasses
> end
> end
>
> and require this file at the top of your buildfile.
>
> Hope this helps,
> alex
>
I've tried your first solution and it worked perfectly, I will shortly 
implement the extension as it looks cleaner indeed. Now I have to deal 
with my unit tests failing, but that's another issue :-)

Thank you very much for your help.

Sebastiano


Re: Circular dependency with custom layout

Posted by Alex Boisvert <al...@gmail.com>.
On Tue, Dec 7, 2010 at 8:30 AM, Sebastiano Pilla <pi...@progiweb.com> wrote:

> I'm trying to use buildr in a multi-module ATG project, and the unit
> testing tool we use requires the test resources to end in the same directory
> as the test classes. I have defined a custom layout such as:
>
> # define the layout for our projects
> # src/main/java -> classes, src/test/java -> target/test-classes
> # src/test/resources -> target/test-classes
> StandardLayout = Layout.new
> StandardLayout[:source, :main, :java] = 'src/main/java'
> StandardLayout[:target, :main, :classes] = 'classes'
> StandardLayout[:source, :main, :resources] = 'resources'
> StandardLayout[:source, :test, :java] = 'src/test/java'
> StandardLayout[:source, :test, :resources] = 'src/test/resources'
> StandardLayout[:target, :test, :classes] = 'target/test-classes'
> StandardLayout[:target, :test, :resources] = 'target/test-classes'
>
> and I have assigned this layout to the project and subproject.
>
> The problem is that when I run buildr I get the following circular
> dependency error:
>
> D:\dev\progicommerce\src>%JRUBY_HOME%\bin\jruby -S buildr
> (in D:/dev/progicommerce/src, development)
> D:/dev/progicommerce/src/buildfile:4 warning: already initialized constant
> VERSION
> D:/dev/progicommerce/src/buildfile:7 warning: already initialized constant
> VERSION
> Building ProgiCommerce
> Buildr aborted!
> ←[31mRuntimeError : Circular dependency detected: TOP => default => build
> => ProgiCommerce:build => ProgiCommerce:ATGDUST:build =>
> ProgiCommerce:ATGDUST:test => ProgiCommerce:ATGDUST:test:compile =>
> ProgiCommerce:ATGDUST:test:resources =>
> D:/dev/progicommerce/src/ATGDUST/target/test-classes =>
> ProgiCommerce:ATGDUST:test:compile←[0m
>
> (See full trace by running task with --trace)
>
> Is there a way to have my test resources end in target/test-classes along
> with the test classes?
>

Hi Sebastiano,

It's not currently possible to map both (:target, :test, :resources) and
(:target, :test, :classes) to the same physical directory due to the way
resource copying/filtering is implemented.  Resource dependencies end up
being wired to the destination directory rather than the abstract task (e.g.
project:test:resources).  I think that's a minor design flaw.

You can work around this problem by adding the following to your project,

  task :copy_resources do
    Dir[_('target/test/resources/*')].each { |f| cp_r f,
_('target/test-classes') }
  end
  test.enhance [:copy_resources]

which copies over all test resources (after filtering) into
target/test-classes before tests run.

If you don't want to put this boilerplate in each of your project, you can
turn it into an
Extension<http://buildr.apache.org/rdoc/classes/Buildr/Extension.html>
such
as,

module ResourcesInTestClasses
  include Extension

  after_define do |project|
    task :copy_resources do
      Dir[project.path_to('target/test/resources/*')].each do |f|
        cp_r f, project.path_to('target/test-classes')
      end
    end
    project.test.enhance [:copy_resources]
  end

  class Buildr::Project
    include ResourcesInTestClasses
  end
end

and require this file at the top of your buildfile.

Hope this helps,
alex