bones 2.0.3 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/Manifest.txt +20 -25
- data/README.txt +114 -83
- data/Rakefile +7 -6
- data/data/Rakefile.erb +7 -1
- data/data/bin/NAME.erb +1 -1
- data/data/lib/NAME.rb.erb +4 -11
- data/data/spec/NAME_spec.rb.erb +0 -1
- data/data/spec/spec_helper.rb.erb +0 -1
- data/lib/bones.rb +21 -8
- data/lib/bones/annotation_extractor.rb +1 -2
- data/lib/bones/debug.rb +0 -1
- data/lib/bones/main.rb +183 -109
- data/lib/bones/smtp_tls.rb +0 -1
- data/{data → lib/bones}/tasks/ann.rake +0 -1
- data/{data → lib/bones}/tasks/bones.rake +0 -1
- data/lib/bones/tasks/gem.rake +192 -0
- data/{data → lib/bones}/tasks/git.rake +0 -1
- data/{data → lib/bones}/tasks/manifest.rake +3 -4
- data/{data → lib/bones}/tasks/notes.rake +0 -1
- data/{data → lib/bones}/tasks/post_load.rake +2 -2
- data/{data → lib/bones}/tasks/rdoc.rake +0 -1
- data/{data → lib/bones}/tasks/rubyforge.rake +2 -4
- data/{data → lib/bones}/tasks/setup.rb +14 -3
- data/{data → lib/bones}/tasks/spec.rake +1 -2
- data/{data → lib/bones}/tasks/svn.rake +0 -1
- data/{data → lib/bones}/tasks/test.rake +3 -1
- data/spec/bones/main_spec.rb +157 -0
- data/spec/bones_spec.rb +18 -0
- data/spec/data/data/README.txt +0 -0
- data/spec/data/data/Rakefile +0 -0
- data/spec/data/foo/README.txt +0 -0
- data/spec/data/foo/Rakefile +0 -0
- data/spec/spec_helper.rb +22 -0
- data/tasks/ann.rake +0 -1
- data/tasks/bones.rake +0 -1
- data/tasks/gem.rake +98 -32
- data/tasks/git.rake +0 -1
- data/tasks/manifest.rake +3 -4
- data/tasks/notes.rake +0 -1
- data/tasks/post_load.rake +2 -2
- data/tasks/rdoc.rake +0 -1
- data/tasks/rubyforge.rake +2 -4
- data/tasks/setup.rb +14 -3
- data/tasks/spec.rake +1 -2
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +3 -1
- metadata +40 -17
- data/data/tasks/gem.rake +0 -126
data/data/spec/NAME_spec.rb.erb
CHANGED
data/lib/bones.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
# $Id$
|
2
1
|
|
3
2
|
module Bones
|
4
3
|
|
5
4
|
# :stopdoc:
|
6
|
-
VERSION = '2.0
|
5
|
+
VERSION = '2.1.0'
|
7
6
|
PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
8
7
|
WIN32 = %r/win32/ =~ RUBY_PLATFORM
|
9
8
|
DEV_NULL = WIN32 ? 'NUL:' : '/dev/null'
|
@@ -14,7 +13,7 @@ module Bones
|
|
14
13
|
# <tt>File.join</tt>.
|
15
14
|
#
|
16
15
|
def self.path( *args )
|
17
|
-
args.empty? ? PATH : File.join(PATH,
|
16
|
+
args.empty? ? PATH : File.join(PATH, args.flatten)
|
18
17
|
end
|
19
18
|
|
20
19
|
# call-seq:
|
@@ -28,20 +27,34 @@ module Bones
|
|
28
27
|
def self.require_all_libs_relative_to( fname, dir = nil )
|
29
28
|
dir ||= File.basename(fname, '.*')
|
30
29
|
search_me = File.expand_path(
|
31
|
-
File.join(File.dirname(fname), dir, '
|
30
|
+
File.join(File.dirname(fname), dir, '*.rb'))
|
32
31
|
|
33
32
|
Dir.glob(search_me).sort.each {|rb| require rb}
|
34
33
|
end
|
35
34
|
|
35
|
+
#
|
36
|
+
#
|
37
|
+
def self.setup
|
38
|
+
local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
|
39
|
+
|
40
|
+
if test(?e, local_setup)
|
41
|
+
load local_setup
|
42
|
+
return
|
43
|
+
end
|
44
|
+
|
45
|
+
bones_setup = ::Bones.path %w[lib bones tasks setup.rb]
|
46
|
+
load bones_setup
|
47
|
+
|
48
|
+
rakefiles = Dir.glob(File.join(Dir.pwd, %w[tasks *.rake])).sort
|
49
|
+
import(*rakefiles)
|
50
|
+
end
|
51
|
+
|
36
52
|
# TODO: fix file lists for Test::Unit and RSpec
|
37
53
|
# these guys are just grabbing whatever is there and not pulling
|
38
54
|
# the filenames from the manifest
|
39
55
|
|
40
|
-
# TODO: create some tasks to generate e-mails / announcements
|
41
|
-
|
42
56
|
end # module Bones
|
43
57
|
|
44
|
-
|
45
|
-
Bones.require_all_libs_relative_to __FILE__
|
58
|
+
Bones.require_all_libs_relative_to(__FILE__)
|
46
59
|
|
47
60
|
# EOF
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# $Id$
|
2
1
|
|
3
2
|
begin
|
4
3
|
require 'facets/ansicode'
|
@@ -85,7 +84,7 @@ class AnnotationExtractor
|
|
85
84
|
|
86
85
|
text = m[2]
|
87
86
|
if text =~ @id_rgxp
|
88
|
-
text.gsub!(@id_rgxp) {|str|
|
87
|
+
text.gsub!(@id_rgxp) {|str| ANSICode.green(str)} if HAVE_COLOR
|
89
88
|
list << Annotation.new(lineno, m[1], text)
|
90
89
|
end
|
91
90
|
list
|
data/lib/bones/debug.rb
CHANGED
data/lib/bones/main.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# $Id$
|
2
1
|
|
3
2
|
require 'fileutils'
|
4
3
|
require 'optparse'
|
@@ -7,102 +6,161 @@ require 'erb'
|
|
7
6
|
module Bones
|
8
7
|
class Main
|
9
8
|
|
10
|
-
|
11
|
-
attr_accessor :name, :data, :verbose, :output_dir
|
9
|
+
attr_reader :options
|
12
10
|
|
13
11
|
# Create a new instance of Main, and run the +bones+ application given
|
14
12
|
# the command line _args_.
|
15
13
|
#
|
16
14
|
def self.run( args )
|
17
15
|
bones = self.new
|
18
|
-
bones.parse
|
16
|
+
bones.parse(args)
|
17
|
+
bones.run
|
18
|
+
end
|
19
|
+
|
20
|
+
# Create a new main instance using _io_ for standard output and _err_ for
|
21
|
+
# error messages.
|
22
|
+
#
|
23
|
+
def initialize( io = STDOUT, err = STDERR )
|
24
|
+
@io = io
|
25
|
+
@err = err
|
26
|
+
@options = {
|
27
|
+
:skeleton_dir => File.join(mrbones_dir, 'data'),
|
28
|
+
:with_tasks => false,
|
29
|
+
:verbose => false,
|
30
|
+
:name => nil,
|
31
|
+
:output_dir => nil,
|
32
|
+
:action => nil
|
33
|
+
}
|
34
|
+
@options[:skeleton_dir] = ::Bones.path('data') unless test(?d, skeleton_dir)
|
35
|
+
end
|
36
|
+
|
37
|
+
# The output directory where files will be written.
|
38
|
+
#
|
39
|
+
def output_dir
|
40
|
+
options[:output_dir]
|
41
|
+
end
|
19
42
|
|
20
|
-
|
21
|
-
|
43
|
+
# The directory where the project skeleton is located.
|
44
|
+
#
|
45
|
+
def skeleton_dir
|
46
|
+
options[:skeleton_dir]
|
47
|
+
end
|
48
|
+
|
49
|
+
# The project name from the command line.
|
50
|
+
#
|
51
|
+
def name
|
52
|
+
options[:name]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the project name but converted to be usable as a Ruby class
|
56
|
+
# name.
|
57
|
+
#
|
58
|
+
def classname
|
59
|
+
name.tr('-','_').split('_').map {|x| x.capitalize}.join
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns +true+ if we are updating an already existing project. Returns
|
63
|
+
# +false+ if we are creating a new project.
|
64
|
+
#
|
65
|
+
def update?
|
66
|
+
test(?e, output_dir) and with_tasks?
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns +true+ if we are going to copy the Mr Bones tasks into the
|
70
|
+
# destination directory. Normally this will return +false+.
|
71
|
+
#
|
72
|
+
def with_tasks?
|
73
|
+
options[:with_tasks]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns +true+ if the user has requested verbose messages.
|
77
|
+
#
|
78
|
+
def verbose?
|
79
|
+
options[:verbose]
|
22
80
|
end
|
23
81
|
|
24
82
|
# Parse the command line arguments and store the values for later use by
|
25
83
|
# the +create+ and +update+ methods.
|
26
84
|
#
|
27
85
|
def parse( args )
|
28
|
-
self.data = File.join(mrbones_dir, 'data')
|
29
|
-
self.data = ::Bones.path('data') unless test(?d, data)
|
30
|
-
self.update = false
|
31
|
-
self.verbose = false
|
32
|
-
|
33
86
|
opts = OptionParser.new
|
34
87
|
opts.banner << ' project_name'
|
35
88
|
|
36
89
|
opts.separator ''
|
37
|
-
opts.on('-
|
38
|
-
|
39
|
-
|
40
|
-
'enable verbose output') {self.verbose = true}
|
90
|
+
opts.on('-v', '--verbose', 'enable verbose output') {
|
91
|
+
options[:verbose] = true
|
92
|
+
}
|
41
93
|
opts.on('-d', '--directory DIRECTORY', String,
|
42
|
-
'project directory to create',
|
43
|
-
|
94
|
+
'project directory to create', '(defaults to project_name)') {|dir|
|
95
|
+
options[:output_dir] = dir
|
96
|
+
}
|
44
97
|
opts.on('-s', '--skeleton NAME', String,
|
45
|
-
'project skeleton to use') do |
|
46
|
-
path = File.join(mrbones_dir,
|
98
|
+
'project skeleton to use') do |skeleton_name|
|
99
|
+
path = File.join(mrbones_dir, skeleton_name)
|
47
100
|
if test(?d, path)
|
48
|
-
|
49
|
-
elsif test(?d,
|
50
|
-
|
101
|
+
options[:skeleton_dir] = path
|
102
|
+
elsif test(?d, skeleton_name)
|
103
|
+
options[:skeleton_dir] = skeleton_name
|
51
104
|
else
|
52
|
-
|
105
|
+
@io.puts " unknown skeleton '#{skeleton_name}'"
|
53
106
|
exit
|
54
107
|
end
|
55
108
|
end
|
109
|
+
opts.on('--with-tasks', 'copy rake tasks to the project folder') {
|
110
|
+
options[:with_tasks] = true
|
111
|
+
}
|
56
112
|
|
57
113
|
opts.separator ''
|
58
|
-
opts.on('--freeze', 'freeze the project skeleton') {
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
114
|
+
opts.on('--freeze', 'freeze the project skeleton') {
|
115
|
+
options[:action] = :freeze
|
116
|
+
}
|
117
|
+
opts.on('--unfreeze', 'use the standard project skeleton') {
|
118
|
+
options[:action] = :unfreeze
|
119
|
+
}
|
120
|
+
opts.on('-i', '--info', 'report on the project skeleton being used') {
|
121
|
+
options[:action] = :info
|
122
|
+
}
|
67
123
|
|
68
124
|
opts.separator ''
|
69
125
|
opts.separator 'common options:'
|
70
|
-
|
71
|
-
|
72
|
-
STDOUT.puts opts
|
126
|
+
opts.on_tail( '-h', '--help', 'show this message' ) {
|
127
|
+
@io.puts opts
|
73
128
|
exit
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
STDOUT.puts "Mr Bones #{::Bones::VERSION}"
|
129
|
+
}
|
130
|
+
opts.on_tail( '--version', 'show version' ) {
|
131
|
+
@io.puts "Mr Bones #{::Bones::VERSION}"
|
78
132
|
exit
|
79
|
-
|
133
|
+
}
|
80
134
|
|
81
135
|
# parse the command line arguments
|
82
136
|
opts.parse! args
|
83
|
-
|
137
|
+
options[:name] = args.empty? ? nil : args.join('_')
|
84
138
|
|
85
|
-
if name.nil?
|
86
|
-
|
139
|
+
if options[:action].nil? and name.nil?
|
140
|
+
@io.puts opts
|
87
141
|
::Kernel.abort
|
88
142
|
end
|
89
143
|
|
90
|
-
|
144
|
+
options[:output_dir] = name if output_dir.nil?
|
91
145
|
nil
|
92
146
|
end
|
93
147
|
|
94
|
-
#
|
95
|
-
# +false+ if we are creating a new project.
|
96
|
-
#
|
97
|
-
def update?
|
98
|
-
@update
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns the project name but converted to be usable as a Ruby class
|
102
|
-
# name.
|
148
|
+
# Run the main application.
|
103
149
|
#
|
104
|
-
def
|
105
|
-
|
150
|
+
def run
|
151
|
+
case options[:action]
|
152
|
+
when :freeze
|
153
|
+
freeze
|
154
|
+
when :unfreeze
|
155
|
+
unfreeze
|
156
|
+
when :info
|
157
|
+
@io.puts "the project skeleton will be copied from"
|
158
|
+
@io.write " "
|
159
|
+
@io.puts skeleton_dir
|
160
|
+
else
|
161
|
+
if update? then update
|
162
|
+
else create end
|
163
|
+
end
|
106
164
|
end
|
107
165
|
|
108
166
|
# Create a new project from the bones/data project template.
|
@@ -113,17 +171,18 @@ class Main
|
|
113
171
|
|
114
172
|
begin
|
115
173
|
files_to_copy.each {|fn| cp fn}
|
174
|
+
copy_tasks(File.join(output_dir, 'tasks')) if with_tasks?
|
116
175
|
|
117
176
|
pwd = File.expand_path(FileUtils.pwd)
|
118
177
|
msg = "created '#{name}'"
|
119
178
|
msg << " in directory '#{output_dir}'" if name != output_dir
|
120
|
-
|
179
|
+
@io.puts msg
|
121
180
|
|
122
181
|
if test(?f, File.join(output_dir, 'Rakefile'))
|
123
182
|
begin
|
124
183
|
FileUtils.cd output_dir
|
125
184
|
system "rake manifest:create 2>&1 > #{::Bones::DEV_NULL}"
|
126
|
-
|
185
|
+
@io.puts "now you need to fix these files"
|
127
186
|
system "rake notes"
|
128
187
|
ensure
|
129
188
|
FileUtils.cd pwd
|
@@ -144,7 +203,7 @@ class Main
|
|
144
203
|
abort "'#{output_dir}' does not exist" unless test ?e, output_dir
|
145
204
|
|
146
205
|
task_dir = File.join(output_dir, 'tasks')
|
147
|
-
|
206
|
+
FileUtils.mkdir_p(task_dir) unless test(?d, task_dir)
|
148
207
|
|
149
208
|
archive_dir = File.join(task_dir, 'archive')
|
150
209
|
FileUtils.rm_rf archive_dir
|
@@ -155,14 +214,11 @@ class Main
|
|
155
214
|
FileUtils.cp fn, archive_dir
|
156
215
|
end
|
157
216
|
|
158
|
-
|
159
|
-
next unless %r/^tasks\// =~ fn
|
160
|
-
cp fn
|
161
|
-
end
|
217
|
+
copy_tasks(task_dir)
|
162
218
|
|
163
219
|
msg = "updated tasks for '#{name}'"
|
164
220
|
msg << " in directory '#{output_dir}'" if name != output_dir
|
165
|
-
|
221
|
+
@io.puts msg
|
166
222
|
end
|
167
223
|
|
168
224
|
# Freeze the project skeleton to the current Mr Bones gem. If the project
|
@@ -173,41 +229,28 @@ class Main
|
|
173
229
|
# Bones skeleton will be copied to the user's data directory.
|
174
230
|
#
|
175
231
|
def freeze
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
tasks_only = false
|
180
|
-
|
181
|
-
if test(?d, data_dir)
|
182
|
-
STDOUT.puts "archiving #{data_dir}" if verbose
|
183
|
-
FileUtils.rm_rf(archive_dir)
|
184
|
-
FileUtils.mkdir(archive_dir)
|
185
|
-
FileUtils.cp_r(File.join(data_dir, '.'), archive_dir)
|
186
|
-
tasks_only = true
|
187
|
-
else
|
188
|
-
FileUtils.mkdir_p(data_dir)
|
189
|
-
end
|
232
|
+
options[:skeleton_dir] = ::Bones.path('data')
|
233
|
+
options[:name] = 'data' if name.nil?
|
234
|
+
options[:output_dir] = File.join(mrbones_dir, name)
|
190
235
|
|
191
|
-
|
192
|
-
|
236
|
+
archive(output_dir, "#{output_dir}.archive")
|
237
|
+
FileUtils.mkdir_p(output_dir)
|
193
238
|
|
194
|
-
|
195
|
-
|
239
|
+
files_to_copy.each do |file|
|
240
|
+
src = File.join(skeleton_dir, file)
|
241
|
+
dst = File.join(output_dir, file)
|
196
242
|
|
197
|
-
|
243
|
+
@io.puts "freezing #{dst}" if verbose?
|
198
244
|
FileUtils.mkdir_p(File.dirname(dst))
|
199
245
|
FileUtils.cp(src, dst)
|
200
246
|
end
|
201
247
|
|
248
|
+
copy_tasks(File.join(output_dir, 'tasks'), 'freezing') if with_tasks?
|
249
|
+
|
202
250
|
File.open(frozen_version_file, 'w') {|fd| fd.puts ::Bones::VERSION}
|
203
251
|
|
204
|
-
|
205
|
-
STDOUT.puts "project skeleton tasks have been updated " <<
|
206
|
-
"from Mr Bones #{::Bones::VERSION}"
|
207
|
-
else
|
208
|
-
STDOUT.puts "project skeleton has been frozen " <<
|
252
|
+
@io.puts "project skeleton has been frozen " <<
|
209
253
|
"to Mr Bones #{::Bones::VERSION}"
|
210
|
-
end
|
211
254
|
end
|
212
255
|
|
213
256
|
# Unfreeze the project skeleton. The default Mr Bones skeleton will be
|
@@ -215,20 +258,14 @@ class Main
|
|
215
258
|
# one exists.
|
216
259
|
#
|
217
260
|
def unfreeze
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
if
|
222
|
-
|
223
|
-
|
224
|
-
FileUtils.mkdir(archive_dir)
|
225
|
-
FileUtils.cp_r(File.join(data_dir, '.'), archive_dir)
|
226
|
-
FileUtils.rm_rf(data_dir)
|
227
|
-
|
228
|
-
STDOUT.puts "project skeleton has been unfrozen"
|
229
|
-
STDOUT.puts "(default Mr Bones #{::Bones::VERSION} sekeleton will be used)"
|
261
|
+
options[:name] = 'data' if name.nil?
|
262
|
+
options[:output_dir] = File.join(mrbones_dir, name)
|
263
|
+
|
264
|
+
if archive(output_dir, "#{output_dir}.archive")
|
265
|
+
@io.puts "project skeleton has been unfrozen"
|
266
|
+
@io.puts "(default Mr Bones #{::Bones::VERSION} skeleton will be used)"
|
230
267
|
else
|
231
|
-
|
268
|
+
@io.puts "project skeleton is not frozen (no action taken)"
|
232
269
|
end
|
233
270
|
FileUtils.rm_f frozen_version_file
|
234
271
|
end
|
@@ -237,10 +274,10 @@ class Main
|
|
237
274
|
# the new project directory
|
238
275
|
#
|
239
276
|
def files_to_copy
|
240
|
-
rgxp = %r/\A#{
|
277
|
+
rgxp = %r/\A#{skeleton_dir}\/?/o
|
241
278
|
exclude = %r/tmp$|bak$|~$|CVS|\.svn/o
|
242
279
|
|
243
|
-
ary = Dir.glob(File.join(
|
280
|
+
ary = Dir.glob(File.join(skeleton_dir, '**', '*')).map do |filename|
|
244
281
|
next if exclude =~ filename
|
245
282
|
next if test(?d, filename)
|
246
283
|
filename.sub rgxp, ''
|
@@ -251,9 +288,6 @@ class Main
|
|
251
288
|
ary
|
252
289
|
end
|
253
290
|
|
254
|
-
|
255
|
-
private
|
256
|
-
|
257
291
|
# Copy a file from the Bones prototype project location to the user
|
258
292
|
# specified project location. A message will be displayed to the screen
|
259
293
|
# indicating that the file is being created.
|
@@ -262,9 +296,9 @@ class Main
|
|
262
296
|
dir = File.dirname(file).sub('NAME', name)
|
263
297
|
dir = (dir == '.' ? output_dir : File.join(output_dir, dir))
|
264
298
|
dst = File.join(dir, File.basename(file, '.erb').sub('NAME', name))
|
265
|
-
src = File.join(
|
299
|
+
src = File.join(skeleton_dir, file)
|
266
300
|
|
267
|
-
|
301
|
+
@io.puts(test(?e, dst) ? "updating #{dst}" : "creating #{dst}") if verbose?
|
268
302
|
FileUtils.mkdir_p(dir)
|
269
303
|
|
270
304
|
if '.erb' == File.extname(file)
|
@@ -277,10 +311,50 @@ class Main
|
|
277
311
|
FileUtils.chmod(File.stat(src).mode, dst)
|
278
312
|
end
|
279
313
|
|
314
|
+
# Archive the contents of the _from_ directory into the _to_ directory.
|
315
|
+
# The _to_ directory will be deleted if it currently exists. After the
|
316
|
+
# copy the _from_ directory will be deleted.
|
317
|
+
#
|
318
|
+
# Returns +true+ if the directory was archived. Returns +false+ if the
|
319
|
+
# directory was not archived.
|
320
|
+
#
|
321
|
+
def archive( from, to )
|
322
|
+
if test(?d, from)
|
323
|
+
@io.puts "archiving #{from}" if verbose?
|
324
|
+
FileUtils.rm_rf(to)
|
325
|
+
FileUtils.mkdir(to)
|
326
|
+
FileUtils.cp_r(File.join(from, '.'), to)
|
327
|
+
FileUtils.rm_rf(from)
|
328
|
+
true
|
329
|
+
else
|
330
|
+
false
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# Copy the Mr Bones tasks into the _to_ directory. If we are in verbose
|
335
|
+
# mode, then a message will be displayed to the user. This message can be
|
336
|
+
# passed in as the _msg_ argument. The current file being copied is
|
337
|
+
# appened to the end of the message.
|
338
|
+
#
|
339
|
+
def copy_tasks( to, msg = nil )
|
340
|
+
Dir.glob(::Bones.path(%w[lib bones tasks *])).sort.each do |src|
|
341
|
+
dst = File.join(to, File.basename(src))
|
342
|
+
|
343
|
+
if msg
|
344
|
+
@io.puts "#{msg} #{dst}" if verbose?
|
345
|
+
else
|
346
|
+
@io.puts(test(?e, dst) ? "updating #{dst}" : "creating #{dst}") if verbose?
|
347
|
+
end
|
348
|
+
|
349
|
+
FileUtils.mkdir_p(File.dirname(dst))
|
350
|
+
FileUtils.cp(src, dst)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
280
354
|
# Prints an abort _msg_ to the screen and then exits the Ruby interpreter.
|
281
355
|
#
|
282
356
|
def abort( msg )
|
283
|
-
|
357
|
+
@err.puts msg
|
284
358
|
exit 1
|
285
359
|
end
|
286
360
|
|