[ANN] Rake 0.5.0 Release

Discussion in 'Ruby' started by Jim Weirich, Mar 25, 2005.

  1. Jim Weirich

    Jim Weirich Guest

    = Rake 0.5.0 Released

    It has been a long time in coming, but we finally have a new version
    of Rake available.

    == Changes

    * Fixed bug where missing intermediate file dependencies could cause
    an abort with --trace or --dry-run. (Brian Chandler)

    * Recursive rules are now supported (Tilman Sauerbeck).

    * Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck).

    * Added warning option for the Test Task (requested by Eric Hodel).

    * The jamis rdoc template is only used if it exists.

    * Added fix for Ruby 1.8.2 test/unit and rails problem.

    * Added contributed rake man file. (Jani Monoses)

    * Fixed documentation that was lacking the Rake module name (Tilman
    Sauerbeck).

    == What is Rake

    Rake is a build tool similar to the make program in many ways. But
    instead of cryptic make recipes, Rake uses standard Ruby code to
    declare tasks and dependencies. You have the full power of a modern
    scripting language built right into your build tool.

    == Availability

    The easiest way to get and install rake is via RubyGems ...

    gem install rake (you may need root/admin privileges)

    Otherwise, you can get it from the more traditional places:

    Home Page:: http://rake.rubyforge.org/
    Download:: http://rubyforge.org/project/showfiles.php?group_id=50

    == Thanks

    Lots of people provided input to this release. Thanks to Tilman
    Sauerbeck for numerous patches, documentation fixes and suggestions.
    And for also pushing me to get this release out. Also, thanks to
    Brian Chandler for the finding and fixing --trace/dry-run fix. That
    was an obscure bug. Also to Eric Hodel for some good suggestions.

    -- Jim Weirich


    --
    -- 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, Mar 25, 2005
    #1
    1. Advertising

  2. Jim Weirich

    Phlip Guest

    Jim Weirich wrote:

    > = Rake 0.5.0 Released
    >
    > It has been a long time in coming, but we finally have a new version
    > of Rake available.


    Did you improve the introductory documentation?

    I tried to use Rake once, and I could not get it to execute a command if a
    file had changed. That could just be me.

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
    Phlip, Mar 25, 2005
    #2
    1. Advertising

  3. Jim Weirich

    Jim Weirich Guest

    On Friday 25 March 2005 06:34 pm, Phlip wrote:

    Hi Phlip!

    > Jim Weirich wrote:
    > > It has been a long time in coming, but we finally have a new version
    > > of Rake available.

    >
    > Did you improve the introductory documentation?


    Only minor tweaks to the docs this time around.

    > I tried to use Rake once, and I could not get it to execute a command if a
    > file had changed. That could just be me.


    Hmmm ... where did you have problems? I'm always looking for ways to improve
    rake, including the documentation.

    --
    -- 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, Mar 25, 2005
    #3
  4. Jim Weirich wrote:

    > = Rake 0.5.0 Released
    >
    > It has been a long time in coming, but we finally have a new version
    > of Rake available.


    Thanks a lot for this wonderful tool.

    I have code in my Rakefile for uploading releases to RubyForge so that
    they will correctly appear under the project's file release page.
    (E.g. http://rubyforge.org/frs/?group_id=559)

    I've however not factored this out into a separate task. Would you still
    be interested in this?
    Florian Gross, Mar 25, 2005
    #4
  5. Jim Weirich

    Ryan Davis Guest

    On Mar 25, 2005, at 3:49 PM, Florian Gross wrote:

    > I have code in my Rakefile for uploading releases to RubyForge so that
    > they will correctly appear under the project's file release page.
    > (E.g. http://rubyforge.org/frs/?group_id=559)
    >
    > I've however not factored this out into a separate task. Would you
    > still be interested in this?


    I am!!! I was just gonna write this soon.

    GIMME! :)
    Ryan Davis, Mar 26, 2005
    #5
  6. Ryan Davis wrote:

    > On Mar 25, 2005, at 3:49 PM, Florian Gross wrote:
    >
    >> I have code in my Rakefile for uploading releases to RubyForge so that
    >> they will correctly appear under the project's file release page.
    >> (E.g. http://rubyforge.org/frs/?group_id=559)
    >>
    >> I've however not factored this out into a separate task. Would you
    >> still be interested in this?

    >
    > I am!!! I was just gonna write this soon.
    >
    > GIMME! :)


    I've attached the whole file (used for ruby-breakpoint, BTW) as that
    particular task depends on the presence of a few constants and other
    data. You'll probably want to refactor that a bit so that it works in
    your Rakefile as well, but the basic logic should still apply.

    The task that does the RubyForge file publishing is :publish_files.

    If you're going to refactor this into a general task it would be
    wonderful if you could contribute it to Jim, by the way.

    require 'rake'
    require 'find'

    readme = File.read("README")
    Release = (readme[/^= (.+) README$/, 1] || "unknown").tr(" ", "-")
    Name = Release[/\D+/].sub(/\-+$/, "") || "unknown"
    Version = Release[/[\d.]+/] || "unknown"

    author_string = readme[/== Author\s+(.+)/, 1] || "unknown, "
    AuthorName, AuthorMail = author_string.split(", ")
    RubyVersion = readme[/== Requirements.+?\* Ruby (.+?)$/m, 1] || "0.0.0"

    Description = (readme[/README\s+(.+?)\n\n/m, 1] || "unknown").gsub(/\s+/, " ")
    Summary = Description[/^.+?\./] || "unknown"

    DocFiles = %w(README NEWS TODO COPYING GPL)
    RDocFiles = DocFiles - %w(GPL)
    RDocOpts = ["--inline-source", "--line-numbers",
    "--title", Name
    ]
    AdditionalFiles = DocFiles + %w(setup.rb)
    VersionFile = MainFile = File.join("lib", Name.sub("ruby-", "") + ".rb")

    RubyForgeProject = Name
    RubyForgeUser = "flgr"
    Homepage = "http://#{RubyForgeProject}.rubyforge.org/"


    task :none


    if File.exist?("test") then
    task :default => [:unit_test]

    desc "Run all the unit tests"
    task :unit_test do
    ruby "test/tc_all.rb"
    end

    desc "Run the unit tests and create a coverage report"
    task :coverage => ["test/coverage"]
    directory "test/coverage"
    file "test/coverage" => ["lib", "test"] do
    sh "rcov.bat test/tc_all.rb -o test/coverage"
    end
    else
    task :unit_test do
    end

    task :test do
    end

    task :coverage do
    end
    end

    unless File.exist?("bin") then
    task :bin do
    end
    end


    desc "Publish a new release."
    task :publish => ["upload", "publish_files"]


    desc "Upload everything to the web."
    task :upload => ["upload_doc", "upload_pages", "upload_release"]

    desc "Upload the documentation to the web."
    task :upload_doc => ["doc"] do
    if RubyForgeProject then
    path = "/var/www/gforge-projects/#{RubyForgeProject}"
    sh "pscp -scp -r -C -q doc #{RubyForgeUser}@rubyforge.org:#{path}"
    end
    end

    desc "Upload the release to the web."
    task :upload_release => "release/#{Release}" do
    if RubyForgeProject then
    path = "/var/www/gforge-projects/#{RubyForgeProject}/release/#{Release}/"
    sh "pscp -scp -r -C -q release/#{Release}/ #{RubyForgeUser}@rubyforge.org:#{path}"
    end
    end

    desc "Upload the web pages to the web."
    task :upload_pages => ["web"] do
    if RubyForgeProject then
    path = "/var/www/gforge-projects/#{RubyForgeProject}"
    sh "pscp -scp -r -C -q web/* #{RubyForgeUser}@rubyforge.org:#{path}"
    end
    end

    desc "Publish the release files to RubyForge."
    task :publish_files => [:release] do
    files = ["md5sum", "gem", "tgz", "zip"].map { |ext| "release/#{Release}.#{ext}" }

    if RubyForgeProject then
    require 'net/http'
    require 'open-uri'

    changes = ""
    if File.exist?("NEWS") then
    changes_re = /^== \s+ #{Regexp.quote(Name)} \s+ #{Regexp.quote(Version)} \s*
    (.+?) (?:==|\Z)/mx
    changes = File.read("NEWS")[changes_re, 1] || ""
    end

    project_uri = "http://rubyforge.org/projects/#{RubyForgeProject}/"
    project_data = open(project_uri) { |data| data.read }
    group_id = project_data[/[?&]group_id=(\d+)/, 1]
    raise "Couldn't get group id" unless group_id

    # This echos password to shell which is a bit sucky
    print "#{RubyForgeUser}@rubyforge.org's password: "
    password = STDIN.gets.chomp

    login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
    data = [
    "login=1",
    "form_loginname=#{RubyForgeUser}",
    "form_pw=#{password}"
    ].join("&")
    http.post("/account/login.php", data)
    end

    cookie = login_response["set-cookie"]
    raise "Login failed" unless cookie
    headers = { "Cookie" => cookie }

    release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
    release_data = open(release_uri, headers) { |data| data.read }
    package_id = release_data[/[?&]package_id=(\d+)/, 1]
    raise "Couldn't get package id" unless package_id

    first_file = true
    release_id = ""

    files.each do |filename|
    basename = File.basename(filename)
    file_ext = File.extname(filename)
    file_data = File.open(filename, "rb") { |file| file.read }

    puts "Releasing #{basename}..."

    release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
    release_date = Time.now.strftime("%Y-%m-%d %H:%M")
    type_map = {
    ".zip" => "3000",
    ".tgz" => "3110",
    ".gz" => "3110",
    ".gem" => "1400",
    ".md5sum" => "8100"
    }; type_map.default = "9999"
    type = type_map[file_ext]
    boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"

    query_hash = if first_file then
    {
    "group_id" => group_id,
    "package_id" => package_id,
    "release_name" => Release,
    "release_date" => release_date,
    "type_id" => type,
    "processor_id" => "8000", # Any
    "release_notes" => "",
    "release_changes" => changes,
    "preformatted" => "1",
    "submit" => "1"
    }
    else
    {
    "group_id" => group_id,
    "release_id" => release_id,
    "package_id" => package_id,
    "step2" => "1",
    "type_id" => type,
    "processor_id" => "8000", # Any
    "submit" => "Add This File"
    }
    end

    query = "?" + query_hash.map do |(name, value)|
    [name, URI.encode(value)].join("=")
    end.join("&")

    data = [
    "--" + boundary,
    "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
    "Content-Type: application/octet-stream",
    "Content-Transfer-Encoding: binary",
    "", file_data, ""
    ].join("\x0D\x0A")

    release_headers = headers.merge(
    "Content-Type" => "multipart/form-data; boundary=#{boundary}"
    )

    target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
    http.post(target + query, data, release_headers)
    end

    if first_file then
    release_id = release_response.body[/release_id=(\d+)/, 1]
    raise("Couldn't get release id") unless release_id
    end

    first_file = false
    end
    end
    end


    desc "Make release for #{Release} (adjust in README)"
    task :release => ["clean", "coverage", "signatures"]


    desc "Delete generated data"
    task :clean do
    rm_r "test/coverage" if File.exist?("test/coverage")
    rm_r "doc" if File.exist?("doc")
    rm(Dir.glob("release/#{Release}.*"))
    end


    desc "Generate the documentation"
    task "doc" do
    args = RDocOpts.join(" ")
    sh "rdoc.bat #{args} #{RDocFiles.join(" ")} lib"
    end

    task :signatures => "release/#{Release}.md5sum"
    directory "release"
    file "release/#{Release}.md5sum" => ["release/#{Release}.zip",
    "release/#{Release}.tgz", "gem"] do
    target = "#{Release}.md5sum"
    rm target if File.exist?(target)
    Dir.chdir("release") do
    files = Dir.glob("#{Release}.*")
    sh "md5sum #{files.join(" ")} > #{target}"
    sh "unix2dos #{target}"
    end
    end


    directory "release"
    file "release/#{Release}.zip" => ["release/#{Release}"] do
    target = "release/#{Release}.zip"
    rm target if File.exist?(target)
    Dir.chdir("release") do
    sh "zip -9 -r #{Release}.zip #{Release}"
    end
    end

    directory "release"
    file "release/#{Release}.tgz" => ["release/#{Release}"] do
    target = "release/#{Release}.tgz"
    rm target if File.exist?(target)
    Dir.chdir("release") do
    sh "tar -czvf #{Release}.tgz #{Release}"
    end
    end


    task :gem => ["release/#{Release}.gem"]
    directory "release"
    file "release/#{Release}.gem" => ["release/#{Release}"] do
    target = "release/#{Release}.gem"
    rm target if File.exist?(target)
    Dir.chdir("release/#{Release}") do
    require "rubygems"
    require "rubygems/builder"

    spec = Gem::Specification.new do |s|
    s.name = Name
    s.version = Version
    s.platform = Gem::platform::RUBY
    s.required_ruby_version = RubyVersion
    s.summary = Summary
    s.description = Description

    s.files = Dir.glob("**/*")
    s.require_path = "lib"
    s.autorequire = File.basename(MainFile)
    s.executables += Dir.entries("bin").find_all { |f| File.file? "bin/#{f}" }
    s.test_file = "test/tc_all.rb" if File.exist?("test")
    s.has_rdoc = true
    s.extra_rdoc_files = RDocFiles
    s.rdoc_options = RDocOpts

    s.author = AuthorName
    s.email = AuthorMail
    s.homepage = Homepage if Homepage
    s.rubyforge_project = RubyForgeProject if RubyForgeProject
    end

    Gem::Builder.new(spec).build
    end

    mv "release/#{Release}/#{Release}.gem", "release/#{Release}.gem"
    end


    directory "release/#{Release}"
    file "release/#{Release}" => ["lib", "bin", "test", "doc"] do
    target = "release/#{Release}"
    rm_r target if File.exist?(target)
    mkdir target

    ["lib", "bin", "test", "doc"].each do |dir|
    Find.find(dir) do |path|
    if File.directory?(path) then
    if File.split(path).last.downcase == ".svn" then
    Find.prune
    else
    mkdir File.join(target, path)
    end
    else
    cp path, File.join(target, path)
    end
    end
    end

    # Adjust Version
    main_file = File.join(target, VersionFile)
    data = File.read(main_file)
    File.open(main_file, "w") do |file|
    new_data = data.sub("Version = current_version", "Version = #{Version.inspect}")
    file.write(new_data)
    end

    AdditionalFiles.each do |file|
    cp file, File.join(target, file)
    end

    # Convert bin/ files to unix line format
    Dir[File.join(target, "bin", "*")].each do |file|
    sh "dos2unix #{file}"
    end

    # Generate Manifest
    File.open(File.join(target, "Manifest"), "w") do |file|
    files = Dir.chdir(target) { Dir.glob("**/*") }
    file.write(files.join("\n"))
    end
    end
    Florian Gross, Mar 26, 2005
    #6
  7. Jim Weirich

    Phlip Guest

    Jim Weirich wrote:

    > > I tried to use Rake once, and I could not get it to execute a command if

    a
    > > file had changed. That could just be me.

    >
    > Hmmm ... where did you have problems? I'm always looking for ways to

    improve
    > rake, including the documentation.


    Here:

    'file.exe' => ['file.cpp', 'file.h']
    `cc file.cpp`

    Run the cc line if .cpp or .h changed.

    All documentation everywhere has this problem. The author takes something
    for granted and the reader misses it.

    I went with this:

    if make('file.exe', ['file.cpp', 'file.h']) then
    `cc file.cpp`
    end

    make() just reports true if any of its right arguments have a greater file
    mod time than its first argument. The problem with that technique is it uses
    no elaborate blocks or => marks, or Rake.

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
    Phlip, Mar 26, 2005
    #7
  8. Jim Weirich

    Jim Weirich Guest

    On Saturday 26 March 2005 01:14 am, Phlip wrote:
    > Jim Weirich wrote:
    > > Hmmm ... where did you have problems?

    >
    > Here:
    > 'file.exe' => ['file.cpp', 'file.h']
    > `cc file.cpp`
    >
    > Run the cc line if .cpp or .h changed.
    > I went with this:
    >
    > if make('file.exe', ['file.cpp', 'file.h']) then
    > `cc file.cpp`
    > end
    > make() just reports true if any of its right arguments have a greater file
    > mod time than its first argument. The problem with that technique is it
    > uses no elaborate blocks or => marks, or Rake.


    If that's all you need, go for it. The original version of Rake was under 100
    lines of code, so obviously plain old Ruby is very close to solving the
    problem without using Rake.

    But, your simple example can be rendered in Rake as ...

    file "file.exe" => ['file.cpp', 'file.h'] do
    sh %{cc file.cpp -o file.exe}
    end

    --
    -- 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, Mar 26, 2005
    #8
  9. Jim Weirich

    Lyle Johnson Guest

    On Sat, 26 Mar 2005 12:19:50 +0900, Florian Gross <> wrote:

    > I've attached the whole file (used for ruby-breakpoint, BTW) as that
    > particular task depends on the presence of a few constants and other
    > data. You'll probably want to refactor that a bit so that it works in
    > your Rakefile as well, but the basic logic should still apply.


    Oh my. First of all, congratulations to Florian for figuring out how
    to maneuver through all of the HTML forms to automate this task. ;)

    Having said that, though, this seems to highlight the fact that we
    could really use some kind of simple (and more direct) API for making
    file releases at RubyForge. Here is one support request that addresses
    the problem:

    http://rubyforge.org/tracker/index.php?func=detail&aid=531&group_id=5&atid=104

    and there may be others.
    Lyle Johnson, Mar 26, 2005
    #9
  10. Jim Weirich

    Phlip Guest

    Phlip, Mar 27, 2005
    #10
  11. Jim Weirich

    Jim Weirich Guest

    On Sunday 27 March 2005 10:24 am, Phlip wrote:
    > Jim Weirich wrote:
    > > But, your simple example can be rendered in Rake as ...
    > >
    > > file "file.exe" => ['file.cpp', 'file.h'] do
    > > sh %{cc file.cpp -o file.exe}
    > > end

    >
    > Is that the complete Rakefile?


    Complete enough to build the file.exe upon request (e.g. "rake file.exe" from
    the command line). If you wish to make file.exe the default target (so that
    a plain "rake" one the command line will work), you can add the following
    line ...

    task :default => ["file.exe"]

    --
    -- 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, Mar 27, 2005
    #11
  12. Jim Weirich

    Guest

    Re: Rake 0.5.0 Release

    Jim Weirich wrote:

    > > > file "file.exe" => ['file.cpp', 'file.h'] do
    > > > sh %{cc file.cpp -o file.exe}
    > > > end

    > >
    > > Is that the complete Rakefile?

    >
    > Complete enough to build the file.exe upon request (e.g. "rake

    file.exe" from
    > the command line). If you wish to make file.exe the default target

    (so that
    > a plain "rake" one the command line will work), you can add the

    following
    > line ...
    >
    > task :default => ["file.exe"]


    You need someone as brain-damaged as me to help you improve the manual.
    I couldn't make that connection from reading the intro, and the stuff
    for 'task' and 'file'.

    The next time I need my make() function I will instead use Rake, to
    force it to grow on me.

    --
    Phlip
    , Mar 28, 2005
    #12
    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. Jim Weirich

    [ANN] Rake 0.5.3 Release

    Jim Weirich, Apr 9, 2005, in forum: Ruby
    Replies:
    4
    Views:
    125
  2. Joe Van Dyk
    Replies:
    2
    Views:
    95
    Damphyr
    Jan 31, 2006
  3. peppermonkey
    Replies:
    1
    Views:
    228
    Gregory Brown
    Feb 10, 2007
  4. Adam Anderson
    Replies:
    1
    Views:
    122
    Adam Anderson
    Sep 19, 2007
  5. James Mead
    Replies:
    0
    Views:
    137
    James Mead
    Jan 15, 2008
Loading...

Share This Page