lib/reap/task/release.rb in reap-4.3.2 vs lib/reap/task/release.rb in reap-4.3.3
- old
+ new
@@ -1,16 +1,19 @@
-require 'reap/task'
-
require "enumerator"
-require "http-access2"
+require 'reap/task'
+require "reap/vendor/http-access2"
+# ___ _ _____ _
+# | _ \___| |___ __ _ ___ ___ |_ _|_ _ __| |__
+# | / -_) / -_) _` (_-</ -_) | |/ _` (_-< / /
+# |_|_\___|_\___\__,_/__/\___| |_|\__,_/__/_\_\
#
-# Release Task
-#
-# This Rake task releases files to RubyForge and other GForge instaces
+# = Release Task
+#
+# This 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
@@ -61,67 +64,139 @@
# xf.execute
# end
class Reap::Release < Reap::Task
+ section_required true
+
task_desc "Release distribution files."
- section_required true
+ task_help %{
- 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
+ reap release
+ Release distribution to Rubyforge, or other
+ GForge based service.
+
+ host URL of host service
+ username Username of host service
+ project Project name at host
+ package Package name
+ groupid Group id number
+ architecture Architecture (Any, i386, PPC, etc.)
+ release Release name
+ private Private release?
+ changelog Change log file
+ notelog Release notes file
+ dir Distribution directory
+ exclude Distribution types to exclude
+
+ }
+
+ task_attr :rel
+
+ #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']
+ #rel.version ||= master.date
- @host ||= 'rubyforge.org'
- @username ||= master['rubyforge']['username']
- @password ||= master['rubyforge']['password']
+ rel.host ||= 'rubyforge.org'
+ rel.host.chomp!('/')
- @package ||= master['rubyforge']['package']
- @packageid ||= master['rubyforge']['packageid']
- @groupid ||= master['rubyforge']['groupid']
- @private ||= false
- @processor ||= 'Any'
+ rel.username ||= master.rubyforge.username
+ #rel.password ||= master.rubyforge.password
- #@files ||= section['files']
- @name ||= master['version'] || master['date']
- @date ||= master['date'] || Time::now.strftime('%Y-%m-%d %H:%M')
+ rel.project ||= master.rubyforge.project || master.name
+ rel.package ||= master.rubyforge.package
+ #rel.packageid ||= master.rubyforge.packageid
+ rel.groupid ||= master.rubyforge.groupid
+ rel.private ||= false
+ rel.processor ||= 'Any'
- @cookiejar ||= File::join(File::expand_path("~"), ".rubyforge.cookie_jar")
+ rel.date ||= Time::now.strftime('%Y-%m-%d %H:%M')
+
+ rel.exclude ||= []
+ rel.exclude << 'tar.gz' if rel.exclude.include?( 'tgz' )
+ rel.exclude << 'tgz' if rel.exclude.include?( 'tar.gz' )
+ rel.exclude << 'tar.bz2' if rel.exclude.include?( 'tbz' )
+ rel.exclude << 'tbz' if rel.exclude.include?( 'tar.bz2' )
+
+ rel.cookie_jar ||= File::join(File::expand_path("~"), ".rubyforge.cookie_jar")
+
+ # Do not inherit
+ rel.dir = section.dir || master.project.dir
+ rel.release = section.release || master.version || rel.date
end
- # run task
+ # Run release task.
def run
- abort "missing field -- package" unless @package
- abort "missing field -- packageid" unless @packageid
- abort "missing field -- groupid" unless @groupid
+
+ abort "missing field -- package" unless rel.package
+ #abort "missing field -- packageid" unless rel.packageid
+ abort "missing field -- groupid" unless rel.groupid
# add more...
- case @host
- when 'rubyforge', 'rubyforge.org'
- else
- puts %{Unrecognized release host '#{@host}'. Skipped.}
- skip = true
- end
+# case rel.host
+# when 'rubyforge', 'rubyforge.org'
+# else
+# puts %{Unrecognized release host '#{rel.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
+ puts "Reap is preparing release ..."
+
+ rtypes = [ 'tgz', 'tbz', 'tar.gz', 'tar.bz2', 'deb', 'gem', 'ebuild' ]
+ rtypes -= rel.exclude
+ rtypes = rtypes.collect { |rt| Regexp.escape( rt ) }
+ re_rtypes = Regexp.new( '[.](' << rtypes.join('|') << ')$' )
+
+ dir = File.join( rel.dir, "#{rel.name}-#{rel.version}" )
+ files = Dir.entries(dir).select { |f|
+ f =~ re_rtypes or f == 'PKGBUILD'
+ }
+ files = files.collect { |f| File.join( rel.dir, f ) }
+
+ if files.empty?
+ puts "No files to release at #{dir}."
+ exit -1
+ end
+
+ # ask for password
+ print "Password for #{rel.username}: "
+ until passwd = $stdin.gets.strip ; sleep 1 ; end
+ @password = passwd
+
+ login {
+
+ unless package?
+exit 0
+ create_package
+ end
+
+ if release?
+exit 0
+ files.each do |f|
+ remove_file( f ) if file?( f )
+ add_file( f )
+ end
+ else
+exit 0
+ add_release( files.unshift )
+ files.each { |f| add_file( f ) }
+ end
+
+ }
+
end
+private
+
FILETYPES = {
".deb" => 1000,
".rpm" => 2000,
".zip" => 3000,
".bz2" => 3100,
@@ -158,64 +233,121 @@
"Sparc" => 4000,
"UltraSparc" => 5000,
"Other" => 9999,
}
-
# login
- def login
+ def login( &block )
+ # login
page = "/account/login.php"
method = "post_content"
form = {
- "return_to" => "",
- "form_loginname" => @username,
- "form_pw" => @password,
- "login" => "Login"
+ "return_to" => "",
+ "form_loginname" => rel.username,
+ "form_pw" => @password,
+ "login" => "Login"
}
http_transaction( page, method, form )
+
+ # do whatever
+ block.call
+
+ # logout
+ page = "/account/logout.php"
+ method = "" #"post_content"
+ form = {}
+ http_transaction( page, method, form )
end
- # create a new package ( should be another task )
+ # Package exists?
+ def package?
+ page = "/frs/"
+ method = "post_content"
+ form = {
+ "group_id" => rel.groupid
+ }
+ scrape = http_transaction( page, method, form )
+
+ restr = ''
+ restr << Regexp.escape( rel.package )
+ restr << '\s*'
+ restr << Regexp.escape( %{<a href="/frs/monitor.php?filemodule_id=} )
+ restr << '(\d+)'
+ restr << Regexp.escape( %{&group_id=#{rel.groupid}} )
+ re = Regexp.new( restr )
+
+ md = re.match( scrape )
+ if md
+ rel.packageid = md[1]
+ end
+ end
+
+ # Create a new package.
+
def create_package
page = "/frs/admin/index.php"
method = "post_content"
form = {
- "group_id" => @groupid,
- "package_name" => @package,
+ "group_id" => rel.groupid,
+ "package_name" => rel.package,
"func" => "add_package",
- "is_public" => (@private ? 0 : 1),
- "submit" => "Create This Package",
+ "is_public" => (rel.private ? 0 : 1),
+ "submit" => "Create This Package"
}
http_transaction( page, method, form )
end
- # add a new release
+ # Release exits?
+ def release?
+ page = "/frs/admin/showreleases.php"
+ method = "post_content"
+ form = {
+ "package_id" => rel.packageid,
+ "group_id" => rel.groupid
+ }
+ scrape = http_transaction( page, method, form )
+
+ restr = ''
+ restr << Regexp.escape( %{"editrelease.php?group_id=#{rel.groupid}} )
+ restr << Regexp.escape( %{&package_id=#{rel.packageid}} )
+ restr << Regexp.escape( %{&release_id=} )
+ restr << '(\d+)'
+ restr << Regexp.escape( %{">#{rel.release}} )
+ re = Regexp.new( restr )
+
+ md = re.match( scrape )
+ if md
+ rel.releaseid = md[1]
+ end
+ end
+
+ # Add a new release.
+
def add_release( userfile )
page = "/frs/admin/qrs.php"
method = "post_content"
- type_id = @type || userfile[%r|\.[^\./]+$|]
+ type_id = rel.type || userfile[%r|\.[^\./]+$|]
type_id = FILETYPES[type_id]
+ proc_id = PROCESSORS[rel.processor]
- proc_id = PROCESSORS[@processor]
-
# how to use these?
- notes = @notes ? @notes : ( @notelog ? open(@notelog) : nil )
- changes = @changes ? @changes : ( @changelog ? open(@changelog) : nil )
+ notes = rel.notes ? rel.notes : ( rel.notelog ? open(rel.notelog) : nil )
+ changes = rel.changes ? rel.changes : ( rel.changelog ? open(rel.changelog) : nil )
- userfile = open(userfile)
+ userfile = open(rel.userfile)
preformatted = '1'
form = {
- "group_id" => @groupid,
- "package_id" => @packageid,
- "release_name" => @name,
- "release_date" => @date,
+ "group_id" => rel.groupid,
+ "package_id" => rel.packageid,
+ "release_name" => rel.name,
+ "release_date" => rel.date,
"type_id" => type_id,
"processor_id" => proc_id,
"preformatted" => preformatted,
"userfile" => userfile,
"submit" => "Release File"
@@ -225,38 +357,107 @@
extheader = { 'content-type'=>"multipart/form-data; boundary=___#{ boundary }___" }
http_transaction( page, method, form, extheader )
end
- # add file to release
+ # Does file exist?
+ # Note this is a little bit fragile.
+ # If two releases have the same exact file name in them
+ # there could be a problem --that's probably not likely,
+ # maybe even impossible, but as of yet, I can't yet rule it out.
+
+ def file?( file )
+ page = "/frs/"
+ method = "post_content"
+ form = {
+ "group_id" => rel.groupid
+ }
+ scrape = http_transaction( page, method, form )
+
+ restr = ''
+ restr << Regexp.escape( rel.package )
+ restr << '\s*'
+ restr << Regexp.escape( %{<a href="/frs/download.php/} )
+ restr << '(\d+)'
+ restr << Regexp.escape( %{/#{file}} )
+ re = Regexp.new( restr )
+
+ md = re.match( scrape )
+ if md
+ rel.fileid = md[1]
+ end
+ end
+
+ # Remove file from release.
+
+ def remove_file( file )
+ page="/frs/admin/editrelease.php"
+ method = "post_content"
+ form = {
+ "group_id" => rel.groupid,
+ "package_id" => rel.packageid,
+ "release_id" => rel.releaseid,
+ "file_id" => rel.fileid,
+ "step3" => "Delete File",
+ "im_sure" => '1',
+ "submit" => "Delete File "
+ }
+
+ http_transaction( page, method, form )
+ end
+
+ # Add file to release.
+
def add_file( userfile )
+ page = '/frs/admin/editrelease.php'
+ method = "post_content"
- # to do
+ type_id = rel.type || userfile[%r|\.[^\./]+$|]
+ type_id = FILETYPES[type_id]
+ proc_id = PROCESSORS[rel.processor]
+ userfile = open( userfile )
+
+ form = {
+ "group_id" => rel.groupid,
+ "package_id" => rel.packageid,
+ "release_id" => rel.releaseid,
+ "step2" => '1',
+ "userfile" => userfile,
+ "type_id" => type_id,
+ "processor_id" => proc_id,
+ "submit" => "Add This File"
+ }
+
+ http_transaction( page, method, form ) #, extheader )
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
+ client.set_cookie_store( rel.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 = page =~ %r/http/ ? page : "http://#{ rel.host }/#{ page }"
page
end
- response = client.send "#{ method }", "#{ config['uri'] }/#{ page }", form, extheader
+ page.sub!(/^\//, '')
+ uri = "http://#{ rel.host }/#{ page }"
+ response = client.send method, uri, form, extheader
client.save_cookie_store
+ return response
end
+end
# fixes http-access2 bug
BEGIN {
- require "http-access2"
+ require "reap/vendor/http-access2"
module WebAgent::CookieUtils
def domain_match(host, domain)
case domain
when /\d+\.\d+\.\d+\.\d+/
return (host == domain)
@@ -269,5 +470,6 @@
return (host == domain)
end
end
end
}
+