require 'reap/task' require "enumerator" require "http-access2" # # Release Task # # This Rake task releases files to RubyForge and other GForge instaces # or SourceForge clones. In its most simple usage it looks like: # # project = MetaProject::Project::XForge::RubyForge.new('xforge') # # Create a new release of the xforge project on Rubyforge. # task :release => [:gem] do # Rake::XForge::Release.new(project) {} # end # # The previous example will use defaults where it can. It will prompt # you for your xForge user name and password before it uploads all # gems under the pkg folder and creates a RubyForge release. # # While defaults are nice, you may want a little more control. You can # specify additional attributes: # # * #user_name # * #password # * #changes_file # * #version # * #files # * #release_name # * #release_notes # * #release_changes # * #package_name # # Example: # project = MetaProject::Project::XForge::RubyForge.new('xforge') # task :release => [:gem] do # release_files = FileList[ 'pkg/*.gem', 'CHANGES' ] # # Rake::XForge::Release.new(project) do |xf| # # Never hardcode user name and password in the Rakefile! # xf.user_name = ENV['RUBYFORGE_USER'] # xf.password = ENV['RUBYFORGE_PASSWORD'] # xf.files = release_files.to_a # xf.release_name = "XForge 0.1" # end # # This can be invoked from the command line: # # rake release RUBYFORGE_USER=myuser \ # RUBYFORGE_PASSWORD=mypassword # # If you don't like blocks, you can do like this: # # project = MetaProject::Project::XForge::RubyForge.new('xforge') # task :release => [:gem] do # xf = Rake::XForge::Release.new(project) # ... # Set additional attributes # xf.execute # end class Reap::Release < Reap::Task task_desc "Release distribution files." section_required true attr_accessor :project, :version attr_accessor :host, :username, :password attr_accessor :package, :packageid, :groupid, :private, :processor attr_accessor :name, :changes, :notes, :changelog, :notelog attr_accessor :cookiejar def init @project ||= master['rubyforge']['project'] || master['name'] @version ||= master['version'] || master['date'] @host ||= 'rubyforge.org' @username ||= master['rubyforge']['username'] @password ||= master['rubyforge']['password'] @package ||= master['rubyforge']['package'] @packageid ||= master['rubyforge']['packageid'] @groupid ||= master['rubyforge']['groupid'] @private ||= false @processor ||= 'Any' #@files ||= section['files'] @name ||= master['version'] || master['date'] @date ||= master['date'] || Time::now.strftime('%Y-%m-%d %H:%M') @cookiejar ||= File::join(File::expand_path("~"), ".rubyforge.cookie_jar") end # run task def run abort "missing field -- package" unless @package abort "missing field -- packageid" unless @packageid abort "missing field -- groupid" unless @groupid # add more... case @host when 'rubyforge', 'rubyforge.org' else puts %{Unrecognized release host '#{@host}'. Skipped.} skip = true end unless skip puts "Reap is preparing release ..." @password = get_password login #create_package (doesn't fit) add_release( @file.unshift ) @files.each { |f| add_file( f ) } add_release end end FILETYPES = { ".deb" => 1000, ".rpm" => 2000, ".zip" => 3000, ".bz2" => 3100, ".gz" => 3110, ".src.zip" => 5000, ".src.bz2" => 5010, ".src.gz" => 5020, ".src.rpm" => 5100, ".src" => 5900, ".jpg" => 8000, ".txt" => 8100, ".text" => 8100, ".htm" => 8200, ".html" => 8200, ".pdf" => 8300, ".oth" => 9999, ".ebuild" => 1300, ".exe" => 1100, ".dmg" => 1200, ".tar.gz" => 5000, ".tgz" => 5000, ".gem" => 1400, ".pgp" => 8150, ".sig" => 8150, } PROCESSORS = { "i386" => 1000, "IA64" => 6000, "Alpha" => 7000, "Any" => 8000, "PPC" => 2000, "MIPS" => 3000, "Sparc" => 4000, "UltraSparc" => 5000, "Other" => 9999, } # login def login page = "/account/login.php" method = "post_content" form = { "return_to" => "", "form_loginname" => @username, "form_pw" => @password, "login" => "Login" } http_transaction( page, method, form ) end # create a new package ( should be another task ) def create_package page = "/frs/admin/index.php" method = "post_content" form = { "group_id" => @groupid, "package_name" => @package, "func" => "add_package", "is_public" => (@private ? 0 : 1), "submit" => "Create This Package", } http_transaction( page, method, form ) end # add a new release def add_release( userfile ) page = "/frs/admin/qrs.php" method = "post_content" type_id = @type || userfile[%r|\.[^\./]+$|] type_id = FILETYPES[type_id] proc_id = PROCESSORS[@processor] # how to use these? notes = @notes ? @notes : ( @notelog ? open(@notelog) : nil ) changes = @changes ? @changes : ( @changelog ? open(@changelog) : nil ) userfile = open(userfile) preformatted = '1' form = { "group_id" => @groupid, "package_id" => @packageid, "release_name" => @name, "release_date" => @date, "type_id" => type_id, "processor_id" => proc_id, "preformatted" => preformatted, "userfile" => userfile, "submit" => "Release File" } boundary = Array::new(8){ "%2.2d" % rand(42) }.join('__') extheader = { 'content-type'=>"multipart/form-data; boundary=___#{ boundary }___" } http_transaction( page, method, form, extheader ) end # add file to release def add_file( userfile ) # to do end # http transaction def http_transaction( page, method, form, extheader={} ) client = HTTPAccess2::Client::new ENV['HTTP_PROXY'] client.debug_dev = STDERR if ENV['DEBUG'] client.set_cookie_store cookie_jar # fixes http-access2 bug client.redirect_uri_callback = lambda do |res| page = res.header['location'].first page = page =~ %r/http/ ? page : "#{ config['uri'] }/#{ page }" page end response = client.send "#{ method }", "#{ config['uri'] }/#{ page }", form, extheader client.save_cookie_store end # fixes http-access2 bug BEGIN { require "http-access2" module WebAgent::CookieUtils def domain_match(host, domain) case domain when /\d+\.\d+\.\d+\.\d+/ return (host == domain) when '.' return true when /^\./ #return tail_match?(domain, host) return tail_match?(host, domain) else return (host == domain) end end end }