reap 9.3.5 → 9.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/CHANGES +10 -0
  2. data/MANIFEST +37 -21
  3. data/NOTES +13 -11
  4. data/bin/reap-announce +40 -2
  5. data/bin/reap-check-load +20 -2
  6. data/bin/reap-check-syntax +20 -2
  7. data/bin/reap-clean +24 -2
  8. data/bin/reap-clobber +17 -2
  9. data/bin/reap-doc +12 -2
  10. data/bin/reap-doc-rdoc +17 -2
  11. data/bin/reap-doc-ri +16 -2
  12. data/bin/reap-doc-spec +18 -0
  13. data/bin/reap-init +9 -0
  14. data/bin/reap-inspect +20 -2
  15. data/bin/reap-install +13 -2
  16. data/bin/reap-install-gem +14 -2
  17. data/bin/reap-log +15 -2
  18. data/bin/reap-log-changes +15 -2
  19. data/bin/reap-log-notes +20 -2
  20. data/bin/reap-make +16 -2
  21. data/bin/reap-make-clean +10 -2
  22. data/bin/reap-make-distclean +18 -2
  23. data/bin/reap-make-extconf +14 -2
  24. data/bin/reap-make-static +14 -2
  25. data/bin/reap-package +25 -2
  26. data/bin/reap-package-gem +14 -2
  27. data/bin/reap-package-tgz +14 -2
  28. data/bin/reap-package-zip +14 -2
  29. data/bin/reap-prepare +21 -2
  30. data/bin/reap-publish +25 -2
  31. data/bin/reap-release +22 -2
  32. data/bin/reap-rollout +32 -2
  33. data/bin/reap-scaffold +16 -2
  34. data/bin/reap-scm-branch +13 -2
  35. data/bin/reap-scm-tag +13 -2
  36. data/bin/reap-spec +14 -2
  37. data/bin/reap-stats +21 -2
  38. data/bin/reap-test +14 -2
  39. data/bin/reap-test-cross +23 -2
  40. data/bin/reap-test-load +17 -2
  41. data/bin/reap-test-solo +19 -2
  42. data/bin/reap-uninstall +14 -2
  43. data/bin/reap-uninstall-gem +17 -2
  44. data/bin/reap-version +10 -2
  45. data/lib/reap/announcement.rb +136 -0
  46. data/lib/reap/application.rb +3 -1
  47. data/lib/reap/default.yaml +12 -12
  48. data/lib/reap/defaults.rb +49 -0
  49. data/lib/reap/emailer.rb +189 -0
  50. data/lib/reap/extensions.rb +1 -2
  51. data/lib/reap/hosts.rb +4 -0
  52. data/lib/reap/hosts/host.rb +69 -0
  53. data/lib/reap/hosts/mailinglist.rb +83 -0
  54. data/lib/reap/{systems → hosts}/rubyforge.rb +72 -60
  55. data/lib/reap/hosts/rubytalk.rb +39 -0
  56. data/lib/reap/iobject.rb +5 -3
  57. data/lib/reap/metadata.rb +31 -4
  58. data/lib/reap/project.rb +101 -41
  59. data/lib/reap/project/announce.rb +50 -180
  60. data/lib/reap/project/check.rb +1 -1
  61. data/lib/reap/project/gem.rb +32 -68
  62. data/lib/reap/project/log.rb +12 -7
  63. data/lib/reap/project/make.rb +0 -1
  64. data/lib/reap/project/package.rb +228 -75
  65. data/lib/reap/project/rdoc.rb +9 -8
  66. data/lib/reap/project/release.rb +52 -6
  67. data/lib/reap/project/scm.rb +40 -25
  68. data/lib/reap/project/spec.rb +3 -3
  69. data/lib/reap/project/test.rb +1 -2
  70. data/lib/reap/project/version.rb +18 -4
  71. data/lib/reap/runmodes.rb +24 -0
  72. data/lib/reap/settings.rb +3 -14
  73. data/lib/reap/systems.rb +4 -0
  74. data/lib/reap/systems/git.rb +0 -0
  75. data/lib/reap/systems/hg.rb +0 -0
  76. data/lib/reap/systems/{subversion.rb → svn.rb} +47 -16
  77. data/lib/reap/systems/system.rb +53 -0
  78. data/lib/reap/tool.rb +38 -0
  79. data/lib/reap/utilities.rb +43 -86
  80. data/log/{Changelog.txt → changelog.rdoc} +56 -0
  81. data/log/fixme.rdoc +25 -0
  82. data/log/todo.rdoc +85 -0
  83. data/meta/project.yaml +13 -2
  84. data/meta/version +1 -0
  85. data/setup.rb +74 -64
  86. data/task/allshare.rb +109 -0
  87. data/task/clean +13 -0
  88. data/task/compile +28 -0
  89. data/task/configure +372 -0
  90. data/task/install +1481 -0
  91. data/test/case/test_init.rb +32 -0
  92. data/test/case/test_scaffold.rb +32 -0
  93. data/test/data/scaffold/meta/project.yaml +28 -0
  94. data/test/lib/case_testable.rb +23 -0
  95. metadata +64 -31
  96. data/bin/reap-spec-doc +0 -8
  97. data/demo/README +0 -15
  98. data/demo/lib/foo/foo.rb +0 -7
  99. data/demo/meta/VERSION +0 -1
  100. data/demo/meta/project.yaml +0 -21
  101. data/lib/reap/project/rubyforge.rb +0 -71
  102. data/lib/reap/project/svn.rb +0 -76
  103. data/log/Fixme.txt +0 -22
  104. data/log/Todo.txt +0 -84
  105. data/meta/VERSION +0 -1
@@ -0,0 +1,49 @@
1
+ module Reap
2
+
3
+ class Project
4
+
5
+ # = Project Settings Defaults
6
+ #
7
+ # Provides an inteface to default values for Settings.
8
+ # The default values are loaded from a .yaml file.
9
+
10
+ class Defaults < Hash
11
+
12
+ DEFAULT_FILE = File.join(File.dirname(__FILE__), 'default.yaml')
13
+
14
+ attr :metadata
15
+
16
+ # FIXME: when using the settings, I think nil should be considered a none entry and
17
+ # so false would be required to actually mean "off". This means assigning each key value par one a time?
18
+
19
+ def initialize(metadata)
20
+ super()
21
+ @metadata = metadata
22
+ defaults = File.read(DEFAULT_FILE)
23
+ defaults = instance_eval("<<-XXXXXXXXXXXXX\n#{defaults}\nXXXXXXXXXXXXX")
24
+ defaults = YAML::load(defaults)
25
+ #settings = defaults.dup
26
+ #data.each do |key, value|
27
+ # settings[key] ||= {}
28
+ # settings[key].update(value) if value
29
+ #end
30
+ update(defaults)
31
+ end
32
+
33
+ # open hash
34
+
35
+ def method_missing(s, *a)
36
+ if s =~ /=$/
37
+ self[s] = a[0]
38
+ elsif a.empty?
39
+ self[s]
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,189 @@
1
+ require 'facets/openhash'
2
+
3
+ module Reap
4
+
5
+ # Emailer class makes it easy send out an email.
6
+ #
7
+ # Settings:
8
+ #
9
+ # subject Subject of email message.
10
+ # from Message FROM address [email].
11
+ # to Email address to send announcemnt.
12
+ # server Email server to route message.
13
+ # port Email server's port.
14
+ # port_secure Email server's port.
15
+ # domain Email server's domain name.
16
+ # account Email account name if needed.
17
+ # password Password for login..
18
+ # login Login type: plain, cram_md5 or login [plain].
19
+ # secure Uses TLS security, true or false? [false]
20
+ # message Mesage to send -or-
21
+ # file File that contains message.
22
+ #
23
+ class Emailer
24
+
25
+ class << self
26
+ # Used for caching password between usages.
27
+ attr_accessor :password
28
+ end
29
+
30
+ attr_accessor :server
31
+ attr_accessor :port
32
+ attr_accessor :account
33
+ attr_accessor :passwd
34
+ attr_accessor :login
35
+ attr_accessor :secure
36
+ attr_accessor :domain
37
+ attr_accessor :from
38
+ attr_accessor :mailto
39
+ attr_accessor :subject
40
+ attr_accessor :message
41
+
42
+ #
43
+
44
+ def self.load_with_environment(options, defaults={})
45
+ options = options.rekey
46
+ defaults = defaults.rekey
47
+ environ = environment_options
48
+
49
+ options[:server] ||= environ[:server]
50
+ options[:from] ||= environ[:from]
51
+ options[:account] ||= environ[:account]
52
+ options[:password] ||= environ[:password]
53
+ options[:port] ||= environ[:port]
54
+ options[:domain] ||= environ[:domain]
55
+ options[:login] ||= environ[:login]
56
+ options[:secure] ||= environ[:secure]
57
+
58
+ options[:server] ||= defaults[:server]
59
+ options[:from] ||= defaults[:from]
60
+ options[:account] ||= defaults[:account] || defaults[:from]
61
+ options[:port] ||= defaults[:port].to_i
62
+ options[:domain] ||= defaults[:domain]
63
+ options[:login] ||= defaults[:login]
64
+ options[:secure] ||= defaults[:secure].to_b
65
+
66
+ new(options)
67
+ end
68
+
69
+ def self.environment_options
70
+ options = {}
71
+
72
+ options[:server] ||= ENV['EMAIL_SERVER']
73
+ options[:from] ||= ENV['EMAIL_FROM']
74
+ options[:account] ||= ENV['EMAIL_ACCOUNT'] || options[:from]
75
+ options[:password] ||= ENV['EMAIL_PASSWORD']
76
+ options[:port] ||= ENV['EMAIL_PORT'].to_i
77
+ options[:domain] ||= ENV['EMAIL_DOMAIN']
78
+ options[:login] ||= ENV['EMAIL_LOGIN']
79
+ options[:secure] ||= ENV['EMAIL_SECURE'].to_b
80
+
81
+ options
82
+ end
83
+
84
+ #
85
+
86
+ def initialize(options)
87
+ options = options.to_ostruct
88
+
89
+ @server = options.server
90
+ @account = options.account || options.from
91
+ @passwd = options.password || self.class.password
92
+ @login = options.login
93
+ @secure = options.secure
94
+ @domain = options.domain || options.server
95
+
96
+ @from = options.from
97
+ @subject = options.subject
98
+ @mailto = options.mailto || options.to
99
+ @message = options.message
100
+
101
+ if options.port
102
+ @port = options.port
103
+ else
104
+ @port = secure ? 465 : 25
105
+ end
106
+
107
+ @account ||= @from
108
+
109
+ @login ||= :plain
110
+ @login = @login.to_sym
111
+
112
+ # save the password for later use
113
+ self.class.password = @password
114
+ end
115
+
116
+ #
117
+
118
+ def email(options={})
119
+ options.rekey
120
+
121
+ message = options[:message] || message()
122
+ subject = options[:subject] || subject()
123
+ from = options[:from] || from()
124
+ mailto = options[:mailto] || options[:to] || mailto()
125
+
126
+ raise ArgumentError, "missing email field -- server" unless server
127
+ raise ArgumentError, "missing email field -- account" unless account
128
+
129
+ raise ArgumentError, "missing email field -- from" unless from
130
+ raise ArgumentError, "missing email field -- mailto" unless mailto
131
+ raise ArgumentError, "missing email field -- subject" unless subject
132
+
133
+ passwd ||= password("#{account} password:")
134
+
135
+ mailto = [mailto].flatten.compact
136
+
137
+ msg = ""
138
+ msg << "From: #{from}\n"
139
+ msg << "To: #{mailto.join(';')}\n"
140
+ msg << "Subject: #{subject}\n"
141
+ msg << ""
142
+ msg << message
143
+
144
+ if secure
145
+ Net::SMTP.send(:include, Net::SMTP::TLS)
146
+ Net::SMTP.enable_tls #if secure #if Net::SMTP.respond_to?(:enable_tls) and secure
147
+ end
148
+
149
+ begin
150
+ Net::SMTP.start(server, port, domain, account, passwd, login, secure) do |smtp|
151
+ smtp.send_message(msg, from, mailto)
152
+ end
153
+ puts "Email sent successfully to #{mailto.join(';')}."
154
+ true
155
+ rescue Exception => e
156
+ if $DEBUG
157
+ raise e
158
+ else
159
+ abort "Email delivery failed with #{e}"
160
+ end
161
+ end
162
+ end
163
+
164
+ # Ask for a password.
165
+ #
166
+ # FIXME: Does not hide password.
167
+
168
+ def password(msg=nil)
169
+ msg ||= "Enter Password: "
170
+ inp = ''
171
+
172
+ $stdout << msg
173
+
174
+ inp = STDIN.gets.chomp
175
+
176
+ #begin
177
+ # system "stty -echo"
178
+ # inp = gets.chomp
179
+ #ensure
180
+ # system "stty echo"
181
+ #end
182
+
183
+ return inp
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
@@ -1,5 +1,4 @@
1
- require 'facets/dir/multiglob'
2
- require 'facets/file/write'
1
+ require 'facets'
3
2
 
4
3
  require 'reap/extensions/array'
5
4
  require 'reap/extensions/hash'
@@ -0,0 +1,4 @@
1
+ require 'reap/hosts/mailinglist'
2
+ require 'reap/hosts/rubyforge'
3
+ require 'reap/hosts/rubytalk'
4
+
@@ -0,0 +1,69 @@
1
+ require 'reap/tool'
2
+
3
+ module Reap
4
+ module Hosts
5
+
6
+ def self.registry
7
+ @registry ||= {}
8
+ end
9
+
10
+ # = Host
11
+ #
12
+ # Base class for Hosts.
13
+
14
+ class Host < Tool
15
+
16
+ def self.registry
17
+ Hosts.registry
18
+ end
19
+
20
+ def self.register(*uris)
21
+ uris.each do |uri|
22
+ registry[uri] = self
23
+ end
24
+ end
25
+
26
+ def self.inherited(base)
27
+ scm = base.basename.downcase
28
+ registry[scm] = base
29
+ end
30
+
31
+ def self.factory(name)
32
+ registry[name]
33
+ end
34
+
35
+ # Generic announce confirmation.
36
+
37
+ def announce_confirm?(options={})
38
+ return true if force?
39
+ ans = ask("Announce to #{self.class.basename.downcase}?", "yN")
40
+ case ans.downcase
41
+ when 'y', 'yes'
42
+ true
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ # Generic announce confirmation.
49
+
50
+ def release_confirm?(options={})
51
+ return true if force?
52
+ ans = ask("Release to #{self.class.basename.downcase}?", "yN")
53
+ case ans.downcase
54
+ when 'y', 'yes'
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+
61
+ def inspect
62
+ "<#{self.class}>"
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
69
+
@@ -0,0 +1,83 @@
1
+ require 'reap/hosts/host'
2
+ require 'reap/emailer'
3
+
4
+ module Reap
5
+ module Hosts
6
+
7
+ # = Mailinglist
8
+ #
9
+ # Gerneic Mailing list "host". Mailinglist hosts
10
+ # support the @announce@ task.
11
+
12
+ class Mailinglist < Host
13
+
14
+ register('mailinglist')
15
+
16
+ # Email message. Options are:
17
+ #
18
+ # message Message to send.
19
+ # mailto Email address to whom to mail.
20
+ # from Email address from whom.
21
+ # subject Subject line (default is "ANN: project version").
22
+ # server Email server
23
+ # port Emails server port (default is usually correct).
24
+ # account Email account name (defaults to from).
25
+ # domain User domain (not sure why SMTP requires this?)
26
+ # login Login type (plain, login)
27
+ # secure Use TLS/SSL true or false?
28
+
29
+ def announce(options)
30
+ options = announce_options(options)
31
+
32
+ subject = options[:subject]
33
+ mailto = options[:mailto] || options[:to]
34
+ to = [mailto].flatten.join(", ")
35
+
36
+ if dryrun?
37
+ puts "email '#{subject}' to #{to}"
38
+ else
39
+ emailer = Emailer.new(options)
40
+ emailer.email
41
+ end
42
+ end
43
+
44
+ # Confirm announcement
45
+
46
+ def announce_confirm?(options)
47
+ options = announce_options(options)
48
+
49
+ if mailto = options[:mailto] || options[:to]
50
+ return true if force?
51
+ to = [mailto].flatten.join(", ")
52
+ ans = ask("Announce to #{to}?", "yN")
53
+ case ans.downcase
54
+ when 'y', 'yes'
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+ end
61
+
62
+ #
63
+
64
+ def announce_options(options)
65
+ options = options.rekey
66
+ environ = Emailer.environment_options
67
+ defaults = project.defaults['email'].rekey
68
+
69
+ result = {}
70
+ result.update(defaults)
71
+ result.update(environ)
72
+ result.update(options)
73
+
74
+ result[:subject] = (result[:subject] % [metadata.unixname, metadata.version])
75
+
76
+ result
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+
@@ -6,28 +6,35 @@ require 'ostruct'
6
6
  require 'httpclient'
7
7
  require 'tmpdir'
8
8
 
9
- require 'facets/hash/rekey'
9
+ require 'facets' #/hash/rekey'
10
10
  require 'facets/kernel/ask'
11
11
 
12
+ require 'reap/hosts/host'
13
+
12
14
  module Reap
15
+ module Hosts
13
16
 
17
+ # = Rubyforge
18
+ #
14
19
  # Interface with the RubyForge hosting service.
15
- # Currently supports functions:
20
+ # Supports the following tasks:
16
21
  #
17
- # * release - Upload release packages.
18
- # * publish - Upload website files.
19
- # * announce - Post news announcement.
20
- # * touch - Test connection.
22
+ # * release - Upload release packages.
23
+ # * announce - Post news announcement.
24
+ # * touch - Test connection.
25
+ #
26
+ # TODO: Handle publish tasks to upload website files (currently this is handled separately)
21
27
 
22
- class Rubyforge
28
+ class Rubyforge < Host
29
+ #include FileUtils
23
30
 
24
- include FileUtils
31
+ register('rubyforge', 'rubyforge.org')
25
32
 
26
33
  #HOME = ENV["HOME"] || ENV["HOMEPATH"] || File.expand_path("~")
27
34
 
35
+ DOMAIN = "rubyforge.org"
28
36
  COOKIEJAR = File::join(Dir.tmpdir, 'reap', 'cookie.dat')
29
-
30
- REPORT = /<h\d><span style="color:red">(.*?)<\/span><\/h\d>/
37
+ REPORT = /<h\d><span style="color:red">(.*?)<\/span><\/h\d>/
31
38
 
32
39
  # URI = http:// + domain name
33
40
  # TODO Deal with https, and possible other protocols too.
@@ -37,53 +44,42 @@ module Reap
37
44
  # for use even if they arn't used.
38
45
  attr :username
39
46
  attr :password
47
+ attr :domain
40
48
 
41
- # Domain name of host. Must be overriden by adapter.
42
- def domain
43
- raise "Missing Domain"
44
- end
45
-
46
- # New RubyForge tasks.
47
- def initialize(options)
48
- options = options.dup.rekey
49
+ # New RubyForge object.
50
+ #
51
+ def initialize(project, options={})
52
+ options = options.rekey
49
53
 
50
- @dryrun = options[:dryrun]
51
- @trace = options[:trace]
54
+ super(project, options)
52
55
 
53
- #@domain = options[:domain] || default_domain
54
- @uri = URI.parse("http://" + domain)
56
+ @domain = options[:domain] || DOMAIN
57
+ @uri = URI.parse("http://" + domain)
55
58
 
56
59
  @username = options[:username] || ENV['RUBYFORGE_USERNAME']
57
- @password = options[:password]
60
+ @password = options[:password] || ENV['RUBYFORGE_PASSWORD']
61
+ @unixname = options[:project] || project.metadata.unixname
62
+ @version = project.metadata.version
58
63
 
59
- mkdir_p(File.dirname(COOKIEJAR))
60
- @cookie_jar = COOKIEJAR
61
-
62
- @project = options[:project]
63
- @group_id = options[:group_id] || options[:groupid]
64
+ @group_id = options[:group] || options[:group_id] || options[:groupid]
64
65
 
65
66
  @package_ids = {}
66
67
  @release_ids = {}
67
- @file_ids = {}
68
+ @file_ids = {}
68
69
 
69
- load_project
70
- end
70
+ project.mkdir_p(File.dirname(COOKIEJAR))
71
71
 
72
- def dryrun?
73
- @dryrun
72
+ #load_project
74
73
  end
75
74
 
76
- def trace?
77
- @trace
75
+ #
76
+
77
+ def cookie_jar
78
+ COOKIEJAR
78
79
  end
79
80
 
80
81
  public
81
82
 
82
- #
83
- def domain
84
- "rubyforge.org"
85
- end
86
-
87
83
  # Website location on server.
88
84
  def siteroot
89
85
  "/var/www/gforge-projects"
@@ -95,8 +91,11 @@ module Reap
95
91
  %w{ touch release publish post }
96
92
  end
97
93
 
94
+ # Project unixname.
95
+ attr_accessor :unixname
96
+
98
97
  # Project name.
99
- attr_accessor :project
98
+ attr_accessor :version
100
99
 
101
100
  # Project's group id number.
102
101
  attr_accessor :group_id
@@ -107,6 +106,8 @@ module Reap
107
106
  # Login to website.
108
107
 
109
108
  def login # :yield:
109
+ load_project_cached
110
+
110
111
  page = @uri + "/account/login.php"
111
112
  page.scheme = 'https'
112
113
  page = URI.parse(page.to_s) # set SSL port correctly
@@ -119,12 +120,14 @@ module Reap
119
120
  }
120
121
  html = http_post(page, form)
121
122
 
122
- unless html[/Personal Page/]
123
+ if not html[/Personal Page/]
123
124
  puts "Login failed."
124
125
  re1 = Regexp.escape(%{<h2 style="color:red">})
125
126
  re2 = Regexp.escape(%{</h2>})
126
127
  html[/#{re1}(.*?)#{re2}/]
127
128
  raise $1
129
+ else
130
+ @printed_project_name ||= (puts "Project: #{unixname}"; true)
128
131
  end
129
132
 
130
133
  if block_given?
@@ -164,7 +167,7 @@ module Reap
164
167
  # files package files to release.
165
168
  # exclude Package formats to exclude from files.
166
169
  # (from those created by pack)
167
- # project Project name on host.
170
+ # unixname Project name on host.
168
171
  # package Package to which this release belongs (defaults to project)
169
172
  # release Release name (default is version number)
170
173
  # version Version of release
@@ -190,9 +193,9 @@ module Reap
190
193
  changelog = options[:changelog]
191
194
  notelog = options[:notelog]
192
195
 
193
- project = options[:project] || @project
194
- package = options[:package] || project
195
- release = options[:release] || version
196
+ unixname = options[:unixname] || unixname()
197
+ package = options[:package] || unixname()
198
+ release = options[:release] || version()
196
199
  name = options[:name] || package
197
200
  files = options[:file] || []
198
201
  date = options[:date] || Time::now.strftime('%Y-%m-%d %H:%M')
@@ -201,8 +204,7 @@ module Reap
201
204
 
202
205
  is_public = options[:is_public].nil? ? true : options[:is_public]
203
206
 
204
- raise ArgumentError, "missing group_id" unless group_id
205
- raise ArgumentError, "missing project" unless project
207
+ raise ArgumentError, "missing unixname" unless unixname
206
208
  raise ArgumentError, "missing package" unless package
207
209
  raise ArgumentError, "missing release" unless release
208
210
 
@@ -232,6 +234,8 @@ module Reap
232
234
 
233
235
  login do
234
236
 
237
+ raise ArgumentError, "missing group_id" unless group_id
238
+
235
239
  unless package_id = package?(package)
236
240
  if dryrun?
237
241
  puts "Package '#{package}' does not exist."
@@ -311,7 +315,7 @@ module Reap
311
315
  # options = options.rekey
312
316
  #
313
317
  # #domain = options[:domain] || DOMAIN
314
- # root = File.join(siteroot, project)
318
+ # root = File.join(siteroot, unixname)
315
319
  # root = File.join(root, options[:root]) if options[:root]
316
320
  #
317
321
  # options.update(
@@ -324,7 +328,7 @@ module Reap
324
328
 
325
329
  # Submit a news item.
326
330
 
327
- def post(options)
331
+ def announce(options)
328
332
  options = options.rekey
329
333
 
330
334
  if file = options[:file]
@@ -338,8 +342,7 @@ module Reap
338
342
  end
339
343
 
340
344
  if dryrun?
341
- puts "\nSUBJECT: #{subject}"
342
- puts "\n#{message}\n\n"
345
+ puts "announce-rubyforge: #{subject}"
343
346
  else
344
347
  post_news(subject, message)
345
348
  puts "News item posted!"
@@ -353,8 +356,8 @@ module Reap
353
356
 
354
357
  def http_post(page, form, extheader={})
355
358
  client = HTTPClient::new ENV["HTTP_PROXY"]
356
- client.debug_dev = STDERR if ENV["ICLI_DEBUG"] || ENV["DEBUG"] || $DEBUG
357
- client.set_cookie_store(@cookie_jar)
359
+ client.debug_dev = STDERR if ENV["REAP_DEBUG"] || $DEBUG
360
+ client.set_cookie_store(cookie_jar)
358
361
  client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
359
362
 
360
363
  # HACK to fix http-client redirect bug/feature
@@ -382,12 +385,16 @@ module Reap
382
385
  return response
383
386
  end
384
387
 
388
+ #
389
+
390
+ def load_project_cached
391
+ @load_project_cache ||= load_project
392
+ end
393
+
385
394
  # Loads information for project: group_id, package_ids and release_ids.
386
395
 
387
396
  def load_project
388
- puts "Project: #{project}"
389
-
390
- html = URI.parse("http://#{domain}/projects/#{project}/index.html").read
397
+ html = URI.parse("http://#{domain}/projects/#{unixname}/index.html").read
391
398
 
392
399
  group_id = html[/(frs|tracker)\/\?group_id=\d+/][/\d+/].to_i
393
400
  @group_id = group_id
@@ -445,7 +452,7 @@ module Reap
445
452
  restr = ''
446
453
  restr << Regexp.escape( package_name )
447
454
  restr << '\s*'
448
- restr << Regexp.escape( %{<a href="/frs/monitor.php?filemodule_id=} )
455
+ restr << Regexp.escape( '<a href="/frs/monitor.php?filemodule_id=' )
449
456
  restr << '(\d+)'
450
457
  restr << Regexp.escape( %{&group_id=#{group_id}} )
451
458
  re = Regexp.new( restr )
@@ -606,7 +613,7 @@ module Reap
606
613
  restr = ''
607
614
  #restr << Regexp.escape( package )
608
615
  #restr << '\s*'
609
- restr << Regexp.escape( %{<a href="/frs/download.php/} )
616
+ restr << Regexp.escape( '<a href="/frs/download.php/' )
610
617
  restr << '(\d+)'
611
618
  restr << Regexp.escape( %{/#{file}} )
612
619
  re = Regexp.new(restr)
@@ -672,6 +679,8 @@ module Reap
672
679
  def post_news(subject, body)
673
680
  page = "/news/submit.php"
674
681
 
682
+ subject % [unixname, version]
683
+
675
684
  form = {
676
685
  "group_id" => group_id,
677
686
  "post_changes" => "y",
@@ -680,7 +689,9 @@ module Reap
680
689
  "submit" => "Submit"
681
690
  }
682
691
 
683
- http_post(page, form)
692
+ login do
693
+ http_post(page, form)
694
+ end
684
695
  end
685
696
 
686
697
  # Constant for file types accepted by Rubyforge
@@ -745,4 +756,5 @@ module Reap
745
756
  end
746
757
 
747
758
  end
759
+ end
748
760