reap 9.3.5 → 9.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|