Q: How can a Rake task know the caller's directory?

Discussion in 'Ruby' started by James Britt, Jan 15, 2007.

  1. James Britt

    James Britt Guest

    I'm increasingly using rake files for common system tasks. Since Rake
    will search up a directory tree until it finds a Rakefile, I can have
    one in my home directory and call tasks from anyplace below that.

    But tasks that need to know something about the current directory have
    me stymied. Calling Dir.pwd in a task reflects the directory of the
    Rakefile.

    Is there a rake method that returns the path of where the Rakefile
    search began?


    E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    /home/james, with task :whereami, and I call

    $ rake whereami

    what does :whereami have to do to return '/home/james/foo/bar' ?

    Thanks!

    --
    James Britt
     
    James Britt, Jan 15, 2007
    #1
    1. Advertising

  2. James Britt wrote:
    > I'm increasingly using rake files for common system tasks. Since Rake
    > will search up a directory tree until it finds a Rakefile, I can have
    > one in my home directory and call tasks from anyplace below that.
    >
    > But tasks that need to know something about the current directory have
    > me stymied. Calling Dir.pwd in a task reflects the directory of the
    > Rakefile.
    >
    > Is there a rake method that returns the path of where the Rakefile
    > search began?
    >
    >
    > E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    > /home/james, with task :whereami, and I call
    >
    > $ rake whereami
    >
    > what does :whereami have to do to return '/home/james/foo/bar' ?


    No idea. One possible solution is to put a "stub" rakefile in the dir,
    and the stub requires the main rakefile. Then (IIRC) the pwd during the
    rake tasks will be that of the stub. But maybe you don't want to scatter
    stubs all over the place.

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Jan 15, 2007
    #2
    1. Advertising

  3. James Britt

    Mike Harris Guest

    James Britt wrote:

    > I'm increasingly using rake files for common system tasks. Since Rake
    > will search up a directory tree until it finds a Rakefile, I can have
    > one in my home directory and call tasks from anyplace below that.
    >
    > But tasks that need to know something about the current directory have
    > me stymied. Calling Dir.pwd in a task reflects the directory of the
    > Rakefile.
    >
    > Is there a rake method that returns the path of where the Rakefile
    > search began?
    >
    >
    > E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    > /home/james, with task :whereami, and I call
    >
    > $ rake whereami
    >
    > what does :whereami have to do to return '/home/james/foo/bar' ?
    >
    > Thanks!
    >

    Modify rake to log the initial working directory before doing anything
    else. You could do this by putting the line to log the dir in the file
    bin/rake. Take advantage of ruby's openness.

    Alternatively, you could put a file in a dir on your PATH (let's say
    rake2) to log the dir and then delegate to rake, and just call rake2
    instead of rake from the command line.
     
    Mike Harris, Jan 15, 2007
    #3
  4. James Britt

    James Britt Guest

    Mike Harris wrote:
    > James Britt wrote:
    >
    >> E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    >> /home/james, with task :whereami, and I call
    >>
    >> $ rake whereami
    >>
    >> what does :whereami have to do to return '/home/james/foo/bar' ?
    >>
    >> Thanks!
    >>

    > Modify rake to log the initial working directory before doing anything
    > else. You could do this by putting the line to log the dir in the file
    > bin/rake. Take advantage of ruby's openness.


    I've hacked ruby apps in this manner before, but they are prone to "gem
    update <name_of_gem>" stomping.

    So any mods to rake itself have to happen via by a plugin that will
    survive library updates.

    >
    > Alternatively, you could put a file in a dir on your PATH (let's say
    > rake2) to log the dir and then delegate to rake, and just call rake2
    > instead of rake from the command line.
    >


    Too hackish, even for me. I'd rather see about a cleaner way for any
    arbitrary rake task to know the initial calling directory.

    --
    James Britt

    "I have the uncomfortable feeling that others are making a religion
    out of it, as if the conceptual problems of programming could be
    solved by a single trick, by a simple form of coding discipline!"
    - Edsger Dijkstra
     
    James Britt, Jan 15, 2007
    #4
  5. James Britt

    James Britt Guest

    Joel VanderWerf wrote:
    >
    > No idea. One possible solution is to put a "stub" rakefile in the dir,
    > and the stub requires the main rakefile. Then (IIRC) the pwd during the
    > rake tasks will be that of the stub. But maybe you don't want to scatter
    > stubs all over the place.


    Right, that's the whole point. For example, I have a Rake task that
    will do an svn commit. I've also aliased rake to r , so I can do this
    to commit code:

    $ r com This is my log message

    and the :com task knows how to grab the message, do the commit, and run
    a few other things (like svn status to alert if I missed adding any new
    files).

    Very handy, except as at stands, the invoked rake file thinks everything
    happens relative where it lives, so I have to create a Rakefile
    everyplace I want to use a location-Dependant task.


    (Someone else mentioned using a "rake2" delegate; since I'm already
    using 'r' as my rake invocation, maybe having a real r.rb that stores
    the calling directory in ENV might work. That rake tasks that need the
    caller dir can look for the value in ENV; these tasks could then assume
    a default dir if this environment variable is empty.)

    --
    James Britt

    "I have the uncomfortable feeling that others are making a religion
    out of it, as if the conceptual problems of programming could be
    solved by a single trick, by a simple form of coding discipline!"
    - Edsger Dijkstra
     
    James Britt, Jan 15, 2007
    #5
  6. James Britt

    James Britt Guest

    Mike Harris wrote:

    > Alternatively, you could put a file in a dir on your PATH (let's say
    > rake2) to log the dir and then delegate to rake, and just call rake2
    > instead of rake from the command line.
    >


    I've tried that out, and it works quite well.

    I had already aliased 'r' to 'rake' to save tying those extra three
    characters. I now have a real script 'r' (well, "r.rb", which is now
    the new r alias):


    #!/usr/local/bin/ruby
    ENV['cwd'] = Dir.pwd
    puts `rake #{ARGV.join( ' ')}`

    Tasks that need the caller's working directory now use

    ENV['cwd'] || Dir.pwd



    Thanks!


    --
    James Britt

    "Take eloquence and wring its neck."
    - Paul Verlaine
     
    James Britt, Jan 16, 2007
    #6
  7. James Britt

    Trans Guest

    James Britt wrote:
    > Joel VanderWerf wrote:
    > >
    > > No idea. One possible solution is to put a "stub" rakefile in the dir,
    > > and the stub requires the main rakefile. Then (IIRC) the pwd during the
    > > rake tasks will be that of the stub. But maybe you don't want to scatter
    > > stubs all over the place.

    >
    > Right, that's the whole point. For example, I have a Rake task that
    > will do an svn commit. I've also aliased rake to r , so I can do this
    > to commit code:
    >
    > $ r com This is my log message


    how are you accessing "This is my log message" in your task?

    t.
     
    Trans, Jan 16, 2007
    #7
  8. James Britt

    James Britt Guest

    Trans wrote:
    > James Britt wrote:
    >> Joel VanderWerf wrote:
    >>> No idea. One possible solution is to put a "stub" rakefile in the dir,
    >>> and the stub requires the main rakefile. Then (IIRC) the pwd during the
    >>> rake tasks will be that of the stub. But maybe you don't want to scatter
    >>> stubs all over the place.

    >> Right, that's the whole point. For example, I have a Rake task that
    >> will do an svn commit. I've also aliased rake to r , so I can do this
    >> to commit code:
    >>
    >> $ r com This is my log message

    >
    > how are you accessing "This is my log message" in your task?


    ARGV.shift # remove the task name
    ARGV.join( ' ') # Get everything else on the command line

    Sadly, rake still thinks that there are more tasks on the command line;
    even calling ARGV.clear doesn't help.

    (I looked for the command to flush the Rake task call queue, but
    couldn't find it, so I live with the error it raises at the end. :( )



    --
    James Britt

    http://www.ruby-doc.org - Ruby Help & Documentation
    http://www.artima.com/rubycs/ - The Journal By & For Rubyists
    http://www.rubystuff.com - The Ruby Store for Ruby Stuff
     
    James Britt, Jan 16, 2007
    #8
  9. James Britt

    Jim Weirich Guest

    James Britt wrote:
    > I'm increasingly using rake files for common system tasks. Since Rake
    > will search up a directory tree until it finds a Rakefile, I can have
    > one in my home directory and call tasks from anyplace below that.
    >
    > But tasks that need to know something about the current directory have
    > me stymied. Calling Dir.pwd in a task reflects the directory of the
    > Rakefile.
    >
    > Is there a rake method that returns the path of where the Rakefile
    > search began?
    >
    >
    > E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    > /home/james, with task :whereami, and I call
    >
    > $ rake whereami
    >
    > what does :whereami have to do to return '/home/james/foo/bar' ?
    >
    > Thanks!


    task :whereami do
    puts Rake.original_dir
    end


    -- Jim Weirich

    --
    Posted via http://www.ruby-forum.com/.
     
    Jim Weirich, Jan 16, 2007
    #9
  10. James Britt

    Jim Weirich Guest

    James Britt wrote:
    > Trans wrote:
    >>> $ r com This is my log message

    >>
    >> how are you accessing "This is my log message" in your task?

    >
    > ARGV.shift # remove the task name
    > ARGV.join( ' ') # Get everything else on the command line
    >
    > Sadly, rake still thinks that there are more tasks on the command line;
    > even calling ARGV.clear doesn't help.
    >
    > (I looked for the command to flush the Rake task call queue, but
    > couldn't find it, so I live with the error it raises at the end. :( )


    You could do:

    rake com MSG="This is my log message"

    Inside of your Rakefile, ENV['MSG'] will contain your log message.

    Sadly, more typing that what you have, but it works with rake instead of
    against it.

    -- Jim Weirich

    --
    Posted via http://www.ruby-forum.com/.
     
    Jim Weirich, Jan 16, 2007
    #10
  11. James Britt

    Trans Guest

    Jim Weirich wrote:
    > James Britt wrote:
    > > Trans wrote:
    > >>> $ r com This is my log message
    > >>
    > >> how are you accessing "This is my log message" in your task?

    > >
    > > ARGV.shift # remove the task name
    > > ARGV.join( ' ') # Get everything else on the command line
    > >
    > > Sadly, rake still thinks that there are more tasks on the command line;
    > > even calling ARGV.clear doesn't help.
    > >
    > > (I looked for the command to flush the Rake task call queue, but
    > > couldn't find it, so I live with the error it raises at the end. :( )

    >
    > You could do:
    >
    > rake com MSG="This is my log message"
    >
    > Inside of your Rakefile, ENV['MSG'] will contain your log message.
    >
    > Sadly, more typing that what you have, but it works with rake instead of
    > against it.


    why did you choose to use environment vars here. isn't that sort of
    like using globals? also, these don't work in my case becuase i can't
    differentiate the env vars set by rake from the "real" env vars.

    t.
     
    Trans, Jan 16, 2007
    #11
  12. James Britt

    Mike Harris Guest


    >
    > task :whereami do
    > puts Rake.original_dir
    > end
    >
    >
    > -- Jim Weirich


    Checkmate, Mr. Weirich. I looked in run/load_rakefile, but neglected to
    look in initialize (or the changelog). Thanks.

    --
    Posted via http://www.ruby-forum.com/.
     
    Mike Harris, Jan 16, 2007
    #12
  13. James Britt

    James Britt Guest

    Jim Weirich wrote:

    > You could do:
    >
    > rake com MSG="This is my log message"
    >
    > Inside of your Rakefile, ENV['MSG'] will contain your log message.
    >


    Right, but too much effort for the user. Leaves too much room for James
    to forget a quote or mistype the var name.


    > Sadly, more typing that what you have, but it works with rake instead of
    > against it.


    But isn't there a way to tell Rake to ignore any additional tasks it
    thinks are queued up?

    When I run

    $rake com This is my message

    it works fine, but at the very end rake complains that it doesn't know
    anything about task 'This'.


    Thanks,

    --
    James Britt
     
    James Britt, Jan 16, 2007
    #13
  14. James Britt

    James Britt Guest

    Jim Weirich wrote:
    !
    >
    > task :whereami do
    > puts Rake.original_dir
    > end



    Perfect. Thanks!


    James
     
    James Britt, Jan 16, 2007
    #14
  15. James Britt

    Jim Weirich Guest

    Trans wrote:
    > why did you choose to use environment vars here. isn't that sort of
    > like using globals? also, these don't work in my case becuase i can't
    > differentiate the env vars set by rake from the "real" env vars.


    The fact they look like environment variables is delibrate. This allows
    you to pass information to Rake via environment variables or by command
    line and Rake doesn't care. You can put a default value in your
    environment and then easily override it on the command line. It is also
    the way that the original make program worked.

    -- Jim Weirich

    --
    Posted via http://www.ruby-forum.com/.
     
    Jim Weirich, Jan 16, 2007
    #15
  16. James Britt

    Jim Weirich Guest

    Mike Harris wrote:
    > Checkmate, Mr. Weirich. I looked in run/load_rakefile, but neglected to
    > look in initialize (or the changelog). Thanks.


    You can thank Jim Freeze for suggesting this feature.

    -- Jim Weirich

    --
    Posted via http://www.ruby-forum.com/.
     
    Jim Weirich, Jan 16, 2007
    #16
  17. On Jan 15, 2007, at 9:57 PM, Trans wrote:

    >
    > Jim Weirich wrote:
    >> James Britt wrote:
    >>> Trans wrote:
    >>>>> $ r com This is my log message
    >>>>
    >>>> how are you accessing "This is my log message" in your task?
    >>>
    >>> ARGV.shift # remove the task name
    >>> ARGV.join( ' ') # Get everything else on the command line
    >>>
    >>> Sadly, rake still thinks that there are more tasks on the command
    >>> line;
    >>> even calling ARGV.clear doesn't help.
    >>>
    >>> (I looked for the command to flush the Rake task call queue, but
    >>> couldn't find it, so I live with the error it raises at the end. :
    >>> ( )

    >>
    >> You could do:
    >>
    >> rake com MSG="This is my log message"
    >>
    >> Inside of your Rakefile, ENV['MSG'] will contain your log message.
    >>
    >> Sadly, more typing that what you have, but it works with rake
    >> instead of
    >> against it.

    >
    > why did you choose to use environment vars here. isn't that sort of
    > like using globals? also, these don't work in my case becuase i can't
    > differentiate the env vars set by rake from the "real" env vars.


    Sure you can. Just introduce a little pragmatic namespacing:

    rake com RAKE_MSG="This is my log message"

    James Edward Gray II
     
    James Edward Gray II, Jan 16, 2007
    #17
  18. James Britt

    James Britt Guest

    Jim Weirich wrote:
    > James Britt wrote:
    >> I'm increasingly using rake files for common system tasks. Since Rake
    >> will search up a directory tree until it finds a Rakefile, I can have
    >> one in my home directory and call tasks from anyplace below that.
    >>
    >> But tasks that need to know something about the current directory have
    >> me stymied. Calling Dir.pwd in a task reflects the directory of the
    >> Rakefile.
    >>
    >> Is there a rake method that returns the path of where the Rakefile
    >> search began?
    >>
    >>
    >> E.g., if I'm in /home/james/foo/bar, and the nearest Rakefile is in
    >> /home/james, with task :whereami, and I call
    >>
    >> $ rake whereami
    >>
    >> what does :whereami have to do to return '/home/james/foo/bar' ?
    >>
    >> Thanks!

    >
    > task :whereami do
    > puts Rake.original_dir
    > end


    I had looked for such a method in ri and the Rake rdocs, but saw nothing
    that looked like what I wanted.

    $ ri Rake
    ------------------------------------------------------------ Class: Rake
    (no description...)
    ------------------------------------------------------------------------


    I could not find the originaL_dir method listed in the rdoc either,
    until I walked through the source code.

    Because of the way this method is defined it Rake, rdoc will not
    correctly process it as a class method on Rake itself:

    # in lib/rake.rb

    #
    class << self
    # Current Rake Application
    def application
    @application ||= Rake::Application.new
    end

    # Set the current Rake application object.
    def application=(app)
    @application = app
    end

    # Return the original directory where the Rake application was
    # started.
    def original_dir
    application.original_dir
    end

    end


    And in the rdoc for Rake::Application, the method is not listed in the
    list of methods because it gets rdoc'ed as an "attribute".

    One has to already know where to look, and what to look for, to find the
    behavior.


    --
    James Britt

    "I never dispute another person's delusions, just their facts."
    - Len Bullard
     
    James Britt, Jan 16, 2007
    #18
  19. James Britt

    Trans Guest

    James Edward Gray II wrote:

    > Sure you can. Just introduce a little pragmatic namespacing:
    >
    > rake com RAKE_MSG="This is my log message"


    Hmm... maybe. Think I'll just use a single env var and parse that I
    guess:

    rake com RAKEOPTS="This is my log message"

    in my case

    rake sign RAKEOPTS="--digest=sha256"

    personally, it would cooler if Rake took some of Ara's kung-fu and used
    someting like a - to separate task from options.

    T.
     
    Trans, Jan 16, 2007
    #19
    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. Brian Takita

    [Rake] Don't know how to build task

    Brian Takita, May 24, 2005, in forum: Ruby
    Replies:
    2
    Views:
    646
    Brian Takita
    May 24, 2005
  2. peppermonkey
    Replies:
    1
    Views:
    269
    Gregory Brown
    Feb 10, 2007
  3. Stéphane Wirtel
    Replies:
    3
    Views:
    414
    Stephane Wirtel
    Jun 15, 2007
  4. James Mead
    Replies:
    0
    Views:
    160
    James Mead
    Jan 15, 2008
  5. Mark
    Replies:
    2
    Views:
    420
Loading...

Share This Page