reap 9.3.5 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +10 -0
- data/MANIFEST +37 -21
- data/NOTES +13 -11
- data/bin/reap-announce +40 -2
- data/bin/reap-check-load +20 -2
- data/bin/reap-check-syntax +20 -2
- data/bin/reap-clean +24 -2
- data/bin/reap-clobber +17 -2
- data/bin/reap-doc +12 -2
- data/bin/reap-doc-rdoc +17 -2
- data/bin/reap-doc-ri +16 -2
- data/bin/reap-doc-spec +18 -0
- data/bin/reap-init +9 -0
- data/bin/reap-inspect +20 -2
- data/bin/reap-install +13 -2
- data/bin/reap-install-gem +14 -2
- data/bin/reap-log +15 -2
- data/bin/reap-log-changes +15 -2
- data/bin/reap-log-notes +20 -2
- data/bin/reap-make +16 -2
- data/bin/reap-make-clean +10 -2
- data/bin/reap-make-distclean +18 -2
- data/bin/reap-make-extconf +14 -2
- data/bin/reap-make-static +14 -2
- data/bin/reap-package +25 -2
- data/bin/reap-package-gem +14 -2
- data/bin/reap-package-tgz +14 -2
- data/bin/reap-package-zip +14 -2
- data/bin/reap-prepare +21 -2
- data/bin/reap-publish +25 -2
- data/bin/reap-release +22 -2
- data/bin/reap-rollout +32 -2
- data/bin/reap-scaffold +16 -2
- data/bin/reap-scm-branch +13 -2
- data/bin/reap-scm-tag +13 -2
- data/bin/reap-spec +14 -2
- data/bin/reap-stats +21 -2
- data/bin/reap-test +14 -2
- data/bin/reap-test-cross +23 -2
- data/bin/reap-test-load +17 -2
- data/bin/reap-test-solo +19 -2
- data/bin/reap-uninstall +14 -2
- data/bin/reap-uninstall-gem +17 -2
- data/bin/reap-version +10 -2
- data/lib/reap/announcement.rb +136 -0
- data/lib/reap/application.rb +3 -1
- data/lib/reap/default.yaml +12 -12
- data/lib/reap/defaults.rb +49 -0
- data/lib/reap/emailer.rb +189 -0
- data/lib/reap/extensions.rb +1 -2
- data/lib/reap/hosts.rb +4 -0
- data/lib/reap/hosts/host.rb +69 -0
- data/lib/reap/hosts/mailinglist.rb +83 -0
- data/lib/reap/{systems → hosts}/rubyforge.rb +72 -60
- data/lib/reap/hosts/rubytalk.rb +39 -0
- data/lib/reap/iobject.rb +5 -3
- data/lib/reap/metadata.rb +31 -4
- data/lib/reap/project.rb +101 -41
- data/lib/reap/project/announce.rb +50 -180
- data/lib/reap/project/check.rb +1 -1
- data/lib/reap/project/gem.rb +32 -68
- data/lib/reap/project/log.rb +12 -7
- data/lib/reap/project/make.rb +0 -1
- data/lib/reap/project/package.rb +228 -75
- data/lib/reap/project/rdoc.rb +9 -8
- data/lib/reap/project/release.rb +52 -6
- data/lib/reap/project/scm.rb +40 -25
- data/lib/reap/project/spec.rb +3 -3
- data/lib/reap/project/test.rb +1 -2
- data/lib/reap/project/version.rb +18 -4
- data/lib/reap/runmodes.rb +24 -0
- data/lib/reap/settings.rb +3 -14
- data/lib/reap/systems.rb +4 -0
- data/lib/reap/systems/git.rb +0 -0
- data/lib/reap/systems/hg.rb +0 -0
- data/lib/reap/systems/{subversion.rb → svn.rb} +47 -16
- data/lib/reap/systems/system.rb +53 -0
- data/lib/reap/tool.rb +38 -0
- data/lib/reap/utilities.rb +43 -86
- data/log/{Changelog.txt → changelog.rdoc} +56 -0
- data/log/fixme.rdoc +25 -0
- data/log/todo.rdoc +85 -0
- data/meta/project.yaml +13 -2
- data/meta/version +1 -0
- data/setup.rb +74 -64
- data/task/allshare.rb +109 -0
- data/task/clean +13 -0
- data/task/compile +28 -0
- data/task/configure +372 -0
- data/task/install +1481 -0
- data/test/case/test_init.rb +32 -0
- data/test/case/test_scaffold.rb +32 -0
- data/test/data/scaffold/meta/project.yaml +28 -0
- data/test/lib/case_testable.rb +23 -0
- metadata +64 -31
- data/bin/reap-spec-doc +0 -8
- data/demo/README +0 -15
- data/demo/lib/foo/foo.rb +0 -7
- data/demo/meta/VERSION +0 -1
- data/demo/meta/project.yaml +0 -21
- data/lib/reap/project/rubyforge.rb +0 -71
- data/lib/reap/project/svn.rb +0 -76
- data/log/Fixme.txt +0 -22
- data/log/Todo.txt +0 -84
- data/meta/VERSION +0 -1
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'reap/hosts/mailinglist'
|
2
|
+
require 'reap/emailer'
|
3
|
+
|
4
|
+
module Reap
|
5
|
+
module Hosts
|
6
|
+
|
7
|
+
# = Rubytalk
|
8
|
+
#
|
9
|
+
# This is a Maklinglist host. It simply statically sets
|
10
|
+
# the ruby-talk@ruby-lang.org email address and passes
|
11
|
+
# on to it's superclass.
|
12
|
+
|
13
|
+
class RubyTalk < Mailinglist
|
14
|
+
|
15
|
+
register('ruby-talk', 'ruby-talk@ruby-lang.org')
|
16
|
+
|
17
|
+
EMAIL_ADDRESS = 'ruby-talk@ruby-lang.org'
|
18
|
+
|
19
|
+
# This sets the mailto address and passes on to the
|
20
|
+
# super class.
|
21
|
+
#
|
22
|
+
# See Mailinglist#announce.
|
23
|
+
|
24
|
+
def announce(options)
|
25
|
+
options = options.rekey(&:to_s)
|
26
|
+
options['mailto'] = EMAIL_ADDRESS
|
27
|
+
super(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def announce_confirm?(options={})
|
31
|
+
options = options.rekey(&:to_s)
|
32
|
+
options['mailto'] = EMAIL_ADDRESS
|
33
|
+
super(options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/reap/iobject.rb
CHANGED
@@ -22,12 +22,14 @@
|
|
22
22
|
# along with Ratch. If not, see <http://www.gnu.org/licenses/>.
|
23
23
|
|
24
24
|
require 'yaml'
|
25
|
-
require 'facets
|
26
|
-
|
25
|
+
require 'facets' #/hash/rekey
|
27
26
|
|
28
27
|
module Reap
|
29
28
|
|
29
|
+
# = InfoObject
|
30
30
|
#
|
31
|
+
# This a base class used by Metadata. It provides a more versitle
|
32
|
+
# means of defining a data-oriented class.
|
31
33
|
|
32
34
|
class InfoObject
|
33
35
|
|
@@ -107,7 +109,7 @@ module Reap
|
|
107
109
|
instance_data.update(data.rekey(:to_s))
|
108
110
|
|
109
111
|
data.each do |k,v|
|
110
|
-
send("#{k}=", v)
|
112
|
+
send("#{k}=", v) if respond_to?("#{k}=")
|
111
113
|
end
|
112
114
|
|
113
115
|
# TODO Could add yield(self) via:
|
data/lib/reap/metadata.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
# along with Ratch. If not, see <http://www.gnu.org/licenses/>.
|
23
23
|
|
24
24
|
require 'facets/dir/multiglob'
|
25
|
+
require 'facets/platform'
|
25
26
|
require 'reap/iobject'
|
26
27
|
|
27
28
|
module Reap
|
@@ -90,6 +91,9 @@ class Project
|
|
90
91
|
|
91
92
|
def initialize(location, data={})
|
92
93
|
@location = location
|
94
|
+
|
95
|
+
@autodoc = true
|
96
|
+
|
93
97
|
super(data)
|
94
98
|
end
|
95
99
|
|
@@ -128,7 +132,7 @@ class Project
|
|
128
132
|
attr_accessor :description, :synopsis
|
129
133
|
|
130
134
|
# "Unix" name of this project.
|
131
|
-
attr_accessor :project, :name
|
135
|
+
attr_accessor :project, :name, :unixname
|
132
136
|
|
133
137
|
# Overrides Project#name.
|
134
138
|
# TODO: Fit release name into name or package_name (?)
|
@@ -211,6 +215,12 @@ class Project
|
|
211
215
|
end
|
212
216
|
|
213
217
|
|
218
|
+
# URI of host providers.
|
219
|
+
attr_accessor :hosts do
|
220
|
+
@hosts || {'rubyforge'=>{}, 'rubytalk'=>{} }
|
221
|
+
end
|
222
|
+
|
223
|
+
|
214
224
|
# Version
|
215
225
|
#------------------------------------------------------------------------
|
216
226
|
|
@@ -437,6 +447,15 @@ class Project
|
|
437
447
|
|
438
448
|
attr_accessor :platform
|
439
449
|
|
450
|
+
def platform=(pl)
|
451
|
+
case pl.to_s.downcase
|
452
|
+
when 'current'
|
453
|
+
@platform = Platform.local.to_s
|
454
|
+
else
|
455
|
+
@platform = pl
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
440
459
|
# Architecture(s) this package can be run on: any, i386, i686, ppc, etc.
|
441
460
|
# This is strictly informational and is inteded to indicate the possiblities,
|
442
461
|
# not the particular platform this package runs on.
|
@@ -451,7 +470,13 @@ class Project
|
|
451
470
|
# Packages that are intended to compile on install may need this. It is a list
|
452
471
|
# of "extension scripts" which generate Makefiles for use in compilation.
|
453
472
|
attr_accessor :extensions do
|
454
|
-
|
473
|
+
@extensions ||= (
|
474
|
+
exts = []
|
475
|
+
Dir.chdir(location) do
|
476
|
+
exts = Dir.glob('ext/**/extconf.rb')
|
477
|
+
end
|
478
|
+
exts.flatten.compact
|
479
|
+
)
|
455
480
|
end
|
456
481
|
|
457
482
|
#
|
@@ -460,9 +485,11 @@ class Project
|
|
460
485
|
#end
|
461
486
|
|
462
487
|
# Generate documentation on installation?
|
463
|
-
attr_accessor :
|
488
|
+
attr_accessor :autodoc, :has_rdoc
|
489
|
+
|
490
|
+
# Files to be documented.
|
491
|
+
attr_accessor :document
|
464
492
|
|
465
|
-
#
|
466
493
|
#attr_accessor :package_directory, :package_store do
|
467
494
|
# @package_directory || 'pkg'
|
468
495
|
#end
|
data/lib/reap/project.rb
CHANGED
@@ -2,6 +2,7 @@ module Reap
|
|
2
2
|
require 'yaml'
|
3
3
|
require 'rbconfig'
|
4
4
|
require 'reap/utilities'
|
5
|
+
require 'reap/hosts'
|
5
6
|
|
6
7
|
# = Project
|
7
8
|
#
|
@@ -12,6 +13,8 @@ module Reap
|
|
12
13
|
class Project
|
13
14
|
require 'reap/metadata'
|
14
15
|
require 'reap/settings'
|
16
|
+
require 'reap/defaults'
|
17
|
+
require 'reap/runmodes'
|
15
18
|
|
16
19
|
# Load up the tools
|
17
20
|
require "reap/project/announce.rb"
|
@@ -30,7 +33,6 @@ module Reap
|
|
30
33
|
require "reap/project/spec.rb"
|
31
34
|
require "reap/project/stats.rb"
|
32
35
|
require "reap/project/scm.rb"
|
33
|
-
require "reap/project/svn.rb"
|
34
36
|
require "reap/project/test.rb"
|
35
37
|
require "reap/project/version.rb"
|
36
38
|
|
@@ -40,15 +42,15 @@ module Reap
|
|
40
42
|
|
41
43
|
def initialize(options=nil)
|
42
44
|
@options = options || {}
|
43
|
-
begin
|
44
|
-
@location = locate
|
45
|
-
raise LoadError, "no .reap configuration file" unless @location
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
@location = locate
|
47
|
+
|
48
|
+
raise LoadError, "no .reap configuration file" unless @location
|
49
|
+
|
50
|
+
@metadata = Metadata.read(location)
|
51
|
+
@settings = Settings.read(location, @metadata)
|
52
|
+
@defaults = Defaults.new(@metadata)
|
53
|
+
@runmodes = RunModes.new(options)
|
52
54
|
end
|
53
55
|
|
54
56
|
# Location of project.
|
@@ -59,30 +61,35 @@ module Reap
|
|
59
61
|
|
60
62
|
def metadata ; @metadata ; end
|
61
63
|
|
62
|
-
#
|
64
|
+
# Task defaults.
|
65
|
+
|
66
|
+
def defaults ; @defaults ; end
|
67
|
+
|
68
|
+
# Task user settings.
|
63
69
|
|
64
70
|
def settings ; @settings ; end
|
65
71
|
|
66
|
-
|
72
|
+
# Run modes.
|
67
73
|
|
68
|
-
|
74
|
+
def runmodes ; @runmodes ; end
|
69
75
|
|
70
76
|
# Common options.
|
71
77
|
|
72
78
|
def options ; @options ; end
|
79
|
+
|
73
80
|
#alias_method :init_options, :options # TODO: Improve me! (see stamp.rb)
|
74
81
|
|
75
|
-
def dryrun? ;
|
76
|
-
def trace? ;
|
77
|
-
def force? ;
|
78
|
-
def verbose? ;
|
79
|
-
def debug? ;
|
82
|
+
def dryrun? ; runmodes.dryrun? ; end
|
83
|
+
def trace? ; runmodes.trace? ; end
|
84
|
+
def force? ; runmodes.force? ; end
|
85
|
+
def verbose? ; runmodes.verbose? ; end
|
86
|
+
def debug? ; runmodes.debug? ; end
|
80
87
|
|
81
|
-
def dryrun=(x) ;
|
82
|
-
def trace=(x) ;
|
83
|
-
def force=(x) ;
|
84
|
-
def verbose=(x) ;
|
85
|
-
def debug=(x) ;
|
88
|
+
def dryrun=(x) ; runmodes.dryrun = x ; end
|
89
|
+
def trace=(x) ; runmodes.trace = x ; end
|
90
|
+
def force=(x) ; runmodes.force = x ; end
|
91
|
+
def verbose=(x) ; runmodes.verbose = x ; end
|
92
|
+
def debug=(x) ; runmodes.debug = x ; end
|
86
93
|
|
87
94
|
alias_method :noharm?, :dryrun?
|
88
95
|
alias_method :noharm=, :dryrun=
|
@@ -90,14 +97,22 @@ module Reap
|
|
90
97
|
# Invoke a tool.
|
91
98
|
|
92
99
|
def invoke(command, *args)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
100
|
+
begin
|
101
|
+
#display_location
|
102
|
+
meth = method(command)
|
103
|
+
chdir_to_project do
|
104
|
+
case meth.arity
|
105
|
+
when 0
|
106
|
+
meth.call
|
107
|
+
else
|
108
|
+
meth.call(*args)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
rescue LoadError => e
|
112
|
+
if trace?
|
113
|
+
raise e
|
99
114
|
else
|
100
|
-
|
115
|
+
abort e.message.capitalize + '.'
|
101
116
|
end
|
102
117
|
end
|
103
118
|
end
|
@@ -137,10 +152,27 @@ module Reap
|
|
137
152
|
args = options['arguments']
|
138
153
|
if args
|
139
154
|
args.each do |field|
|
140
|
-
|
155
|
+
case field
|
156
|
+
when 'defaults'
|
157
|
+
y defaults
|
158
|
+
when 'settings'
|
159
|
+
y settings
|
160
|
+
when 'metadata'
|
161
|
+
y metadata
|
162
|
+
else
|
163
|
+
puts metadata.send(field)
|
164
|
+
end
|
141
165
|
end
|
142
166
|
else
|
143
|
-
|
167
|
+
puts
|
168
|
+
puts "#{metadata.title} #{metadata.version}"
|
169
|
+
puts metadata.brief
|
170
|
+
puts metadata.homepage
|
171
|
+
puts
|
172
|
+
puts metadata.description
|
173
|
+
puts
|
174
|
+
puts metadata.copyright
|
175
|
+
puts
|
144
176
|
end
|
145
177
|
end
|
146
178
|
|
@@ -172,23 +204,51 @@ module Reap
|
|
172
204
|
return loc
|
173
205
|
end
|
174
206
|
|
175
|
-
#
|
207
|
+
# Tasks use this to automatically combine commandline options,
|
208
|
+
# user settings, defualts.
|
176
209
|
|
177
210
|
def configure_options(options, *entries)
|
211
|
+
config = {}
|
212
|
+
|
213
|
+
entries.each do |entry|
|
214
|
+
config.update(defaults[entry] || {})
|
215
|
+
end
|
216
|
+
|
217
|
+
entries.each do |entry|
|
218
|
+
config.update(settings[entry] || {})
|
219
|
+
end
|
220
|
+
|
178
221
|
options = (options || {}).rekey(&:to_s)
|
179
|
-
|
180
|
-
|
222
|
+
config.update(options)
|
223
|
+
|
224
|
+
return config
|
225
|
+
end
|
226
|
+
|
227
|
+
# Access to selected hosts.
|
228
|
+
|
229
|
+
def hosts(select=nil)
|
230
|
+
@hosts ||= {}
|
231
|
+
select ||= metadata.hosts.keys
|
232
|
+
result = []
|
233
|
+
metadata.hosts.each do |key, options|
|
234
|
+
next unless select.include?(key)
|
235
|
+
host_class = options['type'] ? Hosts.registry[options['type']] : Hosts.registry[key]
|
236
|
+
next unless host_class
|
237
|
+
# cache hosts
|
238
|
+
@hosts[key] ||= host_class.from_project(self, options)
|
239
|
+
result |= [@hosts[key]]
|
181
240
|
end
|
241
|
+
return result
|
182
242
|
end
|
183
243
|
|
184
|
-
#
|
185
|
-
# This will split the option on ':' or ';'
|
186
|
-
# if it is a string, rather than an array.
|
187
|
-
# And it will make sure there are no nil elements.
|
244
|
+
# Access to project's scource control management system.
|
188
245
|
|
189
|
-
def
|
190
|
-
|
191
|
-
|
246
|
+
def scm
|
247
|
+
@scm ||= (
|
248
|
+
if system = Systems.current
|
249
|
+
system.from_project(self, {}) #TODO: metadata.scm is a hash?
|
250
|
+
end
|
251
|
+
)
|
192
252
|
end
|
193
253
|
|
194
254
|
end
|
@@ -1,205 +1,75 @@
|
|
1
|
+
require 'reap/announcement'
|
2
|
+
|
1
3
|
module Reap
|
2
4
|
|
3
5
|
class Project
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
|
7
|
+
# Generate and email a release announcement. The announcement
|
8
|
+
# text is read from ANNOUNCE{.txt} or another template file
|
9
|
+
# is specified, or if no template is given, the announcemnet
|
10
|
+
# is automatically built from project metadata, ant the
|
11
|
+
# CHANGES and NOTES files.
|
12
|
+
#
|
13
|
+
# Templates support metadata substitutions using $name$ syntax.
|
14
|
+
# Also, it will subsititue the first line matching /please see notes/i
|
10
15
|
# for the notelog. And /please see change/i for the changelog.
|
11
|
-
#
|
16
|
+
#
|
12
17
|
# The following settings apply:
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# domain Email server's domain name.
|
31
|
-
# account Email account name [email].
|
32
|
-
# login Login type: plain, cram_md5 or login.
|
33
|
-
# secure Uses TLS security, true or false?
|
34
|
-
#
|
35
|
-
# A template file can be specified that uses "$setting" as
|
36
|
-
# substitutes for poject information.
|
18
|
+
#
|
19
|
+
# template Announcement template file (ANNOUNCE.txt).
|
20
|
+
# to Email address(es) to send announcemnt.
|
21
|
+
#
|
22
|
+
# If <em>mailto</em> is set then these also apply:
|
23
|
+
#
|
24
|
+
# from Message FROM address [email].
|
25
|
+
# subject Subject of email message ([ANN] title verison).
|
26
|
+
# server Email server to route message.
|
27
|
+
# port Email server's port.
|
28
|
+
# domain Email server's domain name.
|
29
|
+
# account Email account name [email].
|
30
|
+
# login Login type: plain, cram_md5 or login.
|
31
|
+
# secure Uses TLS security, true or false?
|
32
|
+
#
|
33
|
+
# The announcement will be printed to standard out before sending
|
34
|
+
# so it can be verified.
|
37
35
|
|
38
36
|
def announce(options=nil)
|
39
|
-
options = configure_options(options, 'announce'
|
40
|
-
|
41
|
-
message = announce_message(options)
|
42
|
-
|
43
|
-
options = options.to_ostruct
|
44
|
-
|
45
|
-
mail_to = options.mail_to
|
46
|
-
mail_from = options.mail_from
|
47
|
-
subject = options.subject # Subject line (default is "ANN: project version").
|
48
|
-
server = options.server # Email server
|
49
|
-
port = options.port # Emails server port (default is usually correct).
|
50
|
-
account = options.account # Email account name (defaults to mail_from).
|
51
|
-
domain = options.domain # User domain (not sure why SMTP requires this?)
|
52
|
-
login = options.login # Login type (plain, login)
|
53
|
-
secure = options.secure # Use TLS/SSL true or false?
|
54
|
-
password = options.password || ENV['EMAIL_PASSWORD']
|
55
|
-
|
56
|
-
title = options.title || metadata.title
|
57
|
-
version = options.versoin || metadata.version
|
58
|
-
|
59
|
-
# defaults
|
60
|
-
subject ||= "%s, v%s release"
|
61
|
-
account ||= mail_from
|
62
|
-
|
63
|
-
subject = subject % [title, version]
|
37
|
+
options = configure_options(options, 'announce')
|
64
38
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
puts "\n#{message}\n\n"
|
70
|
-
if mail_to
|
71
|
-
ans = ask("Would you like to email this announcement?", "yN")
|
72
|
-
case ans.downcase
|
73
|
-
when 'y', 'yes'
|
74
|
-
email(message,
|
75
|
-
:to => mail_to,
|
76
|
-
:from => mail_from,
|
77
|
-
:subject => subject,
|
78
|
-
:server => server,
|
79
|
-
:port => port,
|
80
|
-
:domain => domain,
|
81
|
-
:account => account,
|
82
|
-
:login => login,
|
83
|
-
:secure => secure,
|
84
|
-
:password => password
|
85
|
-
)
|
86
|
-
end
|
87
|
-
end
|
39
|
+
announcement = Announcement.new do |ann|
|
40
|
+
ann.cutoff = options['cutoff']
|
41
|
+
ann.template = options['template']
|
42
|
+
ann.metadata = metadata
|
88
43
|
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Make a release announcement. Generates and can email a release
|
92
|
-
# announcements. These are nicely formated message and can
|
93
|
-
# email the message to the specified address(es).
|
94
|
-
#
|
95
|
-
# The following settings apply:
|
96
|
-
#
|
97
|
-
# template Announcement file/template.
|
98
|
-
# cutoff Max number of lines of changelog to show.
|
99
|
-
#
|
100
|
-
# A template file can be specified that uses "$setting" as
|
101
|
-
# substitutes for poject information.
|
102
|
-
|
103
|
-
def announce_message(options={})
|
104
|
-
config = settings['announce'] || {}
|
105
|
-
options = config.merge(options).to_ostruct
|
106
44
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
#config['mail_to'] = nil if keys['mail_to'].empty?
|
111
|
-
|
112
|
-
# Build message
|
113
|
-
|
114
|
-
# template
|
115
|
-
template = Dir.glob(options.template.to_s, File::FNM_CASEFOLD).first
|
116
|
-
|
117
|
-
if template
|
118
|
-
readme = File.read(template)
|
119
|
-
readme = unfold_paragraphs(readme)
|
45
|
+
if dryrun?
|
46
|
+
puts "\n#{announcement.message}\n\n" if verbose?
|
120
47
|
else
|
121
|
-
|
122
|
-
readme << "= #{metadata.title} v#{metadata.version}\n\n"
|
123
|
-
readme << " #{metadata.homepage}\n\n"
|
124
|
-
readme << "#{metadata.description}\n\n"
|
125
|
-
readme << "Please see the NOTES file.\n\n"
|
126
|
-
readme << "== CHANGES\n\n"
|
127
|
-
readme << "Please see the CHANGES file.\n"
|
48
|
+
puts "\n#{announcement.message}\n\n"
|
128
49
|
end
|
129
50
|
|
130
|
-
|
131
|
-
|
132
|
-
changelog = file ? File.read(file).strip : ''
|
133
|
-
#changelog = unfold_paragraphs(changelog)
|
134
|
-
changelog = changelog.split("\n")[0..cutoff].join("\n")
|
135
|
-
|
136
|
-
# noteslog
|
137
|
-
file = Dir.glob('note{s,log}{,.txt}', File::FNM_CASEFOLD)[0]
|
138
|
-
notelog = file ? File.read(file).strip : ''
|
139
|
-
notelog = unfold_paragraphs(notelog)
|
140
|
-
|
141
|
-
# Strip tiny version zero.
|
142
|
-
#if keys['version'] =~ /[.].*?[.]/
|
143
|
-
# keys['version'] = keys['version'].chomp('.0')
|
144
|
-
#end
|
145
|
-
|
146
|
-
# Make announcement message
|
147
|
-
message = readme.dup
|
51
|
+
options['message'] = announcement.message
|
52
|
+
options['version'] = metadata.version
|
148
53
|
|
149
|
-
|
150
|
-
|
151
|
-
|
54
|
+
options['title'] ||= metadata.title
|
55
|
+
options['subject'] ||= "%s, v%s release"
|
56
|
+
options['subject'] = options['subject'] % [ options['title'], metadata.version ]
|
152
57
|
|
153
|
-
|
58
|
+
actions = []
|
59
|
+
select = options['hosts']
|
154
60
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
value = metadata.send(name.downcase)
|
160
|
-
message.gsub!("$#{name}$", value.to_s.strip)
|
161
|
-
else
|
162
|
-
puts "Warning: Unknown project field -- #{name}."
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
message.gsub!(/(^|[ ])[$].*?(?=[ ]|$)/,'') # remove unused vars
|
167
|
-
message.gsub!(/\n\s*\n\s*\n/m,"\n\n") # remove any triple blank lines
|
168
|
-
message.rstrip!
|
169
|
-
|
170
|
-
return message
|
171
|
-
end
|
172
|
-
|
173
|
-
def unfold_paragraphs(string)
|
174
|
-
blank = false
|
175
|
-
text = ''
|
176
|
-
string.split(/\n/).each do |line|
|
177
|
-
if /\S/ !~ line
|
178
|
-
text << "\n\n"
|
179
|
-
blank = true
|
180
|
-
else
|
181
|
-
if /^(\s+|[*])/ =~ line
|
182
|
-
text << (line.rstrip + "\n")
|
183
|
-
else
|
184
|
-
text << (line.rstrip + " ")
|
61
|
+
hosts(select).each do |host|
|
62
|
+
if host.respond_to?(:announce)
|
63
|
+
if host.announce_confirm?(options)
|
64
|
+
actions << lambda{ host.announce(options) }
|
185
65
|
end
|
186
|
-
blank = false
|
187
66
|
end
|
188
67
|
end
|
189
|
-
|
68
|
+
|
69
|
+
actions.each{ |a| a.call }
|
190
70
|
end
|
191
71
|
|
192
72
|
end
|
193
73
|
|
194
74
|
end
|
195
75
|
|
196
|
-
# keys = {}
|
197
|
-
# keys['from'] = info.email
|
198
|
-
# keys.update info.gather('mail')
|
199
|
-
# keys.update info.gather('announce')
|
200
|
-
# keys.update info.select(
|
201
|
-
# :project, :version, :title, :subtitle, :description,
|
202
|
-
# :homepage, :download, :slogan
|
203
|
-
# )
|
204
|
-
# keys.update override if override
|
205
|
-
|