rake prepare gem

Discussion in 'Ruby' started by Roeland Moors, Aug 25, 2004.

  1. I'm using rake to create a gem, but I have some questions.

    Before creating a gem in Rake i would like to copy some files to
    a different directory and then create the package.

    I tried something like this:

    task :gem => [:prepare_gem]

    task :prepare_gem do
    # do stuff here
    gem_task.gem_spec.files = files.to_a
    end

    But the problem is that the prepare_gem is executed AFTER the gem
    task. Is this normal?

    --
    Roeland
     
    Roeland Moors, Aug 25, 2004
    #1
    1. Advertising

  2. Roeland Moors

    Jim Weirich Guest

    Roeland Moors said:
    > I'm using rake to create a gem, but I have some questions.


    Great!

    > Before creating a gem in Rake i would like to copy some files to
    > a different directory and then create the package.
    >
    > I tried something like this:
    >
    > task :gem => [:prepare_gem]
    >
    > task :prepare_gem do
    > # do stuff here
    > gem_task.gem_spec.files = files.to_a
    > end
    >
    > But the problem is that the prepare_gem is executed AFTER the gem
    > task. Is this normal?


    Actually, yes. First the explain why, and then the fix ...

    Rake invokes a task, it will first invoke all the dependencies (aka
    prerequisites) of that task before it executes the actions (the do/end
    block) of that task. So you are guaranteed that the actions of a task
    will execute only after the actions of all its all dependencies are
    executed. You have no guarantee that the dependencies will be executed in
    any particular order.

    When debugging problems like this, the -P option on rake is your friend.
    Here is the output for your rakefile (non-relevant portions elided).

    rake gem
    pkg/demo-0.0.0.gem
    prepare_gem
    rake pkg/demo-0.0.0.gem
    pkg
    a
    b
    rake prepare_gem

    (NOTE: I created a package named 'demo' with version 0.0.0 and it depends
    on two files named 'a' and 'b'. I don't know what you were using.)

    We can see that the :gem task depends upon the "pkg/demo-0.0.0.gem" file
    task which is where the gem file is actually created. Since :gem depends
    on "pkg/demo-0.0.0.gem", the gem file will be built before the :gem
    actions are executed. Also the actions of :prepare_gem will be executed
    before :gem's actions. But since :prepare_gem and "pkg/demo-0.0.0.gem"
    are sibling dependents of :gem, their order is not specified, hence the
    gem is built before the :prepare_gem actions are performed.

    The Fix
    -------

    You need to specify that :prepare_gem is a dependency of
    "pkg/demo-0.0.0.gem" instead of :gem. To to this, add the following line
    to your Rakefile ...

    file "pkg/demo-0.0.0.gem" => [:prepare_gem]

    Now, the proper dependencies are declared and prepare_gem is guaranteed to
    execute before the gem file is built.

    The answer to almost any problem with Rake dependencies is to correctly
    declare the real dependencies in the project.

    An aside: It is tempting to just move the "task :gem => [:prepare_gem]"
    task before the creation of the gem package task. This makes sure that
    :prepare_gem comes first in the list of dependencies for :gem. And this
    works because all other things being equal, rake will execute
    dependencies in the order discovered. However, this is very fragile.
    Other dependencies can easily override the "in order rule".

    --
    -- Jim Weirich http://onestepback.org
    -----------------------------------------------------------------
    "Beware of bugs in the above code; I have only proved it correct,
    not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
     
    Jim Weirich, Aug 25, 2004
    #2
    1. Advertising

  3. On Thu, Aug 26, 2004 at 12:53:29AM +0900, Jim Weirich wrote:
    >
    > Roeland Moors said:
    > > I'm using rake to create a gem, but I have some questions.

    >
    > Great!
    >
    > > Before creating a gem in Rake i would like to copy some files to
    > > a different directory and then create the package.
    > >
    > > I tried something like this:
    > >
    > > task :gem => [:prepare_gem]
    > >
    > > task :prepare_gem do
    > > # do stuff here
    > > gem_task.gem_spec.files = files.to_a
    > > end
    > >
    > > But the problem is that the prepare_gem is executed AFTER the gem
    > > task. Is this normal?

    >
    > Actually, yes. First the explain why, and then the fix ...
    > [snip]


    Thanks a lot for the detailed information.

    --
    Roeland
     
    Roeland Moors, Aug 25, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joe Van Dyk
    Replies:
    2
    Views:
    117
    Damphyr
    Jan 31, 2006
  2. Austin 7873
    Replies:
    5
    Views:
    214
    Eric Hodel
    Jan 27, 2007
  3. peppermonkey
    Replies:
    1
    Views:
    268
    Gregory Brown
    Feb 10, 2007
  4. Adam Anderson
    Replies:
    1
    Views:
    147
    Adam Anderson
    Sep 19, 2007
  5. James Mead
    Replies:
    0
    Views:
    159
    James Mead
    Jan 15, 2008
Loading...

Share This Page