bones 2.5.1 → 3.0.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/History.txt +2 -0
- data/README.rdoc +54 -306
- data/Rakefile +28 -37
- data/bin/bones +10 -3
- data/{spec/data/data → default}/.bnsignore +3 -1
- data/{data → default}/History.txt.bns +0 -0
- data/{data → default}/README.txt.bns +0 -0
- data/default/Rakefile.bns +21 -0
- data/{data → default}/bin/NAME.bns +0 -0
- data/{data → default}/lib/NAME.rb.bns +0 -0
- data/{data → default}/spec/NAME_spec.rb.bns +0 -0
- data/{data → default}/spec/spec_helper.rb.bns +0 -0
- data/{data → default}/test/test_NAME.rb +0 -0
- data/lib/bones.rb +73 -31
- data/lib/bones/annotation_extractor.rb +16 -26
- data/lib/bones/app.rb +87 -58
- data/lib/bones/app/command.rb +143 -64
- data/lib/bones/app/create.rb +93 -0
- data/lib/bones/app/file_manager.rb +7 -8
- data/lib/bones/app/freeze.rb +59 -0
- data/lib/bones/app/info.rb +39 -0
- data/lib/bones/app/unfreeze.rb +44 -0
- data/lib/bones/colors.rb +54 -0
- data/lib/bones/gem_package_task.rb +71 -0
- data/lib/bones/helpers.rb +93 -0
- data/lib/bones/plugins/ann.rb +166 -0
- data/lib/bones/plugins/bones_plugin.rb +193 -0
- data/lib/bones/plugins/gem.rb +274 -0
- data/lib/bones/plugins/notes.rb +45 -0
- data/lib/bones/plugins/rdoc.rb +93 -0
- data/lib/bones/plugins/test.rb +57 -0
- data/lib/bones/smtp_tls.rb +1 -0
- data/spec/bones/app/file_manager_spec.rb +6 -6
- data/spec/bones/app_spec.rb +14 -18
- data/spec/bones_spec.rb +9 -4
- data/{data → spec/data/default}/.bnsignore +0 -0
- data/spec/data/{data → default}/History +0 -0
- data/spec/data/{data → default}/NAME/NAME.rb.bns +0 -0
- data/spec/data/{data → default}/README.txt.bns +0 -0
- data/{data → spec/data/default}/Rakefile.bns +0 -0
- data/spec/data/{data → default}/lib/NAME.rb.bns +0 -0
- metadata +94 -68
- data/lib/bones/app/create_command.rb +0 -86
- data/lib/bones/app/freeze_command.rb +0 -73
- data/lib/bones/app/info_command.rb +0 -58
- data/lib/bones/app/unfreeze_command.rb +0 -53
- data/lib/bones/app/update_command.rb +0 -47
- data/lib/bones/debug.rb +0 -72
- data/lib/bones/tasks/ann.rake +0 -80
- data/lib/bones/tasks/bones.rake +0 -20
- data/lib/bones/tasks/gem.rake +0 -201
- data/lib/bones/tasks/git.rake +0 -40
- data/lib/bones/tasks/notes.rake +0 -27
- data/lib/bones/tasks/post_load.rake +0 -34
- data/lib/bones/tasks/rdoc.rake +0 -51
- data/lib/bones/tasks/rubyforge.rake +0 -55
- data/lib/bones/tasks/setup.rb +0 -292
- data/lib/bones/tasks/spec.rake +0 -54
- data/lib/bones/tasks/svn.rake +0 -47
- data/lib/bones/tasks/test.rake +0 -40
- data/lib/bones/tasks/zentest.rake +0 -36
- data/spec/data/data/Rakefile.bns +0 -30
- data/tasks/ann.rake +0 -80
- data/tasks/bones.rake +0 -20
- data/tasks/gem.rake +0 -201
- data/tasks/git.rake +0 -40
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -34
- data/tasks/rdoc.rake +0 -51
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -292
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
- data/tasks/zentest.rake +0 -36
@@ -1,86 +0,0 @@
|
|
1
|
-
|
2
|
-
module Bones
|
3
|
-
class App
|
4
|
-
|
5
|
-
class CreateCommand < Command
|
6
|
-
|
7
|
-
def run( args )
|
8
|
-
parse args
|
9
|
-
|
10
|
-
fm = FileManager.new(
|
11
|
-
:source => repository || skeleton_dir,
|
12
|
-
:destination => output_dir,
|
13
|
-
:stdout => @out,
|
14
|
-
:stderr => @err,
|
15
|
-
:verbose => verbose?
|
16
|
-
)
|
17
|
-
raise "Output directory already exists #{output_dir.inspect}" if test(?e, fm.destination)
|
18
|
-
|
19
|
-
begin
|
20
|
-
fm.copy
|
21
|
-
copy_tasks(File.join(output_dir, 'tasks')) if with_tasks?
|
22
|
-
fm.finalize name
|
23
|
-
|
24
|
-
pwd = File.expand_path(FileUtils.pwd)
|
25
|
-
msg = "Created '#{name}'"
|
26
|
-
msg << " in directory '#{output_dir}'" if name != output_dir
|
27
|
-
@out.puts msg
|
28
|
-
|
29
|
-
if test(?f, File.join(output_dir, 'Rakefile'))
|
30
|
-
begin
|
31
|
-
FileUtils.cd output_dir
|
32
|
-
@out.puts "Now you need to fix these files"
|
33
|
-
system "#{::Bones::RUBY} -S rake notes"
|
34
|
-
ensure
|
35
|
-
FileUtils.cd pwd
|
36
|
-
end
|
37
|
-
end
|
38
|
-
rescue Exception => err
|
39
|
-
FileUtils.rm_rf output_dir
|
40
|
-
msg = "Could not create '#{name}'"
|
41
|
-
msg << " in directory '#{output_dir}'" if name != output_dir
|
42
|
-
raise msg
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def parse( args )
|
47
|
-
std_opts = standard_options
|
48
|
-
|
49
|
-
opts = OptionParser.new
|
50
|
-
opts.banner = 'Usage: bones create [options] <project_name>'
|
51
|
-
|
52
|
-
opts.separator ''
|
53
|
-
opts.separator " Create a new project from a Mr Bones project skeleton. The skeleton can"
|
54
|
-
opts.separator " be the default project skeleton from the Mr Bones gem or one of the named"
|
55
|
-
opts.separator " skeletons found in the '~/.mrbones/' folder. A git or svn repository can"
|
56
|
-
opts.separator " be used as the skeleton if the '--repository' flag is given."
|
57
|
-
|
58
|
-
opts.separator ''
|
59
|
-
opts.on(*std_opts[:directory])
|
60
|
-
opts.on(*std_opts[:skeleton])
|
61
|
-
opts.on(*std_opts[:repository])
|
62
|
-
opts.on(*std_opts[:with_tasks])
|
63
|
-
|
64
|
-
opts.separator ''
|
65
|
-
opts.separator ' Common Options:'
|
66
|
-
opts.on_tail( '-h', '--help', 'show this message' ) {
|
67
|
-
@out.puts opts
|
68
|
-
exit
|
69
|
-
}
|
70
|
-
|
71
|
-
# parse the command line arguments
|
72
|
-
opts.parse! args
|
73
|
-
options[:name] = args.empty? ? nil : args.join('_')
|
74
|
-
|
75
|
-
if name.nil?
|
76
|
-
@out.puts opts
|
77
|
-
exit 1
|
78
|
-
end
|
79
|
-
options[:output_dir] = name if output_dir.nil?
|
80
|
-
end
|
81
|
-
|
82
|
-
end # class CreateCommand
|
83
|
-
end # class App
|
84
|
-
end # module Bones
|
85
|
-
|
86
|
-
# EOF
|
@@ -1,73 +0,0 @@
|
|
1
|
-
|
2
|
-
module Bones
|
3
|
-
class App
|
4
|
-
|
5
|
-
class FreezeCommand < Command
|
6
|
-
|
7
|
-
def run( args )
|
8
|
-
parse args
|
9
|
-
|
10
|
-
fm = FileManager.new(
|
11
|
-
:source => repository || ::Bones.path('data'),
|
12
|
-
:destination => output_dir,
|
13
|
-
:stdout => @out,
|
14
|
-
:stderr => @err,
|
15
|
-
:verbose => verbose?
|
16
|
-
)
|
17
|
-
|
18
|
-
fm.archive_destination
|
19
|
-
return freeze_to_repository if repository
|
20
|
-
|
21
|
-
fm.copy
|
22
|
-
copy_tasks(File.join(output_dir, 'tasks')) if with_tasks?
|
23
|
-
|
24
|
-
@out.puts "Project skeleton #{name.inspect} " <<
|
25
|
-
"has been frozen to Mr Bones #{::Bones::VERSION}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def parse( args )
|
29
|
-
std_opts = standard_options
|
30
|
-
|
31
|
-
opts = OptionParser.new
|
32
|
-
opts.banner = 'Usage: bones freeze [options] [skeleton_name]'
|
33
|
-
|
34
|
-
opts.separator ''
|
35
|
-
opts.separator ' Freeze the project skeleton to the current Mr Bones project skeleton.'
|
36
|
-
opts.separator ' If a name is not given, then the default name "data" will be used.'
|
37
|
-
opts.separator ' Optionally a git or svn repository can be frozen as the project'
|
38
|
-
opts.separator ' skeleton.'
|
39
|
-
|
40
|
-
opts.separator ''
|
41
|
-
opts.on(*std_opts[:repository])
|
42
|
-
opts.on(*std_opts[:with_tasks])
|
43
|
-
|
44
|
-
opts.separator ''
|
45
|
-
opts.separator ' Common Options:'
|
46
|
-
opts.on_tail( '-h', '--help', 'show this message' ) {
|
47
|
-
@out.puts opts
|
48
|
-
exit
|
49
|
-
}
|
50
|
-
|
51
|
-
# parse the command line arguments
|
52
|
-
opts.parse! args
|
53
|
-
options[:name] = args.empty? ? 'data' : args.join('_')
|
54
|
-
options[:output_dir] = File.join(mrbones_dir, name)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Freeze the project skeleton to the git or svn repository that the user
|
58
|
-
# passed in on the command line. This essentially creates an alias to the
|
59
|
-
# reposiory using the name passed in on the command line.
|
60
|
-
#
|
61
|
-
def freeze_to_repository
|
62
|
-
FileUtils.mkdir_p(File.dirname(output_dir))
|
63
|
-
File.open(output_dir, 'w') {|fd| fd.puts repository}
|
64
|
-
@out.puts "Project skeleton #{name.inspect} " <<
|
65
|
-
"has been frozen to #{repository.inspect}"
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
end # class FreezeCommand
|
70
|
-
end # class App
|
71
|
-
end # module Bones
|
72
|
-
|
73
|
-
# EOF
|
@@ -1,58 +0,0 @@
|
|
1
|
-
|
2
|
-
module Bones
|
3
|
-
class App
|
4
|
-
|
5
|
-
class InfoCommand < Command
|
6
|
-
|
7
|
-
def run( args )
|
8
|
-
parse args
|
9
|
-
|
10
|
-
skeleton_dir = File.join(mrbones_dir, 'data')
|
11
|
-
skeleton_dir = ::Bones.path('data') unless test(?d, skeleton_dir)
|
12
|
-
|
13
|
-
msg = "\n"
|
14
|
-
msg << "The default project skeleton will be copied from:\n"
|
15
|
-
msg << " " << skeleton_dir << "\n\n"
|
16
|
-
|
17
|
-
fmt = " %-12s => %s\n"
|
18
|
-
msg << "Available projects skeletons are:\n"
|
19
|
-
Dir.glob(File.join(mrbones_dir, '*')).sort.each do |fn|
|
20
|
-
next if fn =~ %r/\.archive$/
|
21
|
-
next if File.basename(fn) == 'data'
|
22
|
-
|
23
|
-
if test(?f, fn)
|
24
|
-
msg << fmt % [File.basename(fn), File.read(fn).strip]
|
25
|
-
else
|
26
|
-
msg << " " << File.basename(fn) << "\n"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
@out.puts msg
|
31
|
-
@out.puts
|
32
|
-
end
|
33
|
-
|
34
|
-
def parse( args )
|
35
|
-
std_opts = standard_options
|
36
|
-
|
37
|
-
opts = OptionParser.new
|
38
|
-
opts.banner = 'Usage: bones info'
|
39
|
-
|
40
|
-
opts.separator ''
|
41
|
-
opts.separator ' Shows information about available skeletons'
|
42
|
-
|
43
|
-
opts.separator ''
|
44
|
-
opts.separator ' Common Options:'
|
45
|
-
opts.on_tail( '-h', '--help', 'show this message' ) {
|
46
|
-
@out.puts opts
|
47
|
-
exit
|
48
|
-
}
|
49
|
-
|
50
|
-
# parse the command line arguments
|
51
|
-
opts.parse! args
|
52
|
-
end
|
53
|
-
|
54
|
-
end # class InfoCommand
|
55
|
-
end # class App
|
56
|
-
end # module Bones
|
57
|
-
|
58
|
-
# EOF
|
@@ -1,53 +0,0 @@
|
|
1
|
-
|
2
|
-
module Bones
|
3
|
-
class App
|
4
|
-
|
5
|
-
class UnfreezeCommand < Command
|
6
|
-
|
7
|
-
def run( args )
|
8
|
-
parse args
|
9
|
-
|
10
|
-
fm = FileManager.new(
|
11
|
-
:source => repository || ::Bones.path('data'),
|
12
|
-
:destination => output_dir,
|
13
|
-
:stdout => @out,
|
14
|
-
:stderr => @err,
|
15
|
-
:verbose => verbose?
|
16
|
-
)
|
17
|
-
|
18
|
-
if fm.archive_destination
|
19
|
-
@out.puts "Project skeleton #{name.inspect} has been unfrozen"
|
20
|
-
else
|
21
|
-
@out.puts "Project skeleton #{name.inspect} is not frozen " <<
|
22
|
-
"(no action taken)"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def parse( args )
|
27
|
-
std_opts = standard_options
|
28
|
-
|
29
|
-
opts = OptionParser.new
|
30
|
-
opts.banner = 'Usage: bones unfreeze [skeleton_name]'
|
31
|
-
|
32
|
-
opts.separator ''
|
33
|
-
opts.separator " Removes the named skeleton from the '~/.mrbones/' folder. If a name is"
|
34
|
-
opts.separator " not given then the default skeleton is removed."
|
35
|
-
|
36
|
-
opts.separator ''
|
37
|
-
opts.separator ' Common Options:'
|
38
|
-
opts.on_tail( '-h', '--help', 'show this message' ) {
|
39
|
-
@out.puts opts
|
40
|
-
exit
|
41
|
-
}
|
42
|
-
|
43
|
-
# parse the command line arguments
|
44
|
-
opts.parse! args
|
45
|
-
options[:name] = args.empty? ? 'data' : args.join('_')
|
46
|
-
options[:output_dir] = File.join(mrbones_dir, name)
|
47
|
-
end
|
48
|
-
|
49
|
-
end # class UnfreezeCommand
|
50
|
-
end # class App
|
51
|
-
end # module Bones
|
52
|
-
|
53
|
-
# EOF
|
@@ -1,47 +0,0 @@
|
|
1
|
-
|
2
|
-
module Bones
|
3
|
-
class App
|
4
|
-
|
5
|
-
class UpdateCommand < Command
|
6
|
-
|
7
|
-
def run( args )
|
8
|
-
parse args
|
9
|
-
|
10
|
-
raise "'#{output_dir}' does not exist" unless test(?e, output_dir)
|
11
|
-
copy_tasks(File.join(output_dir, 'tasks'))
|
12
|
-
|
13
|
-
msg = "Updated tasks in directory '#{output_dir}'"
|
14
|
-
@out.puts msg
|
15
|
-
end
|
16
|
-
|
17
|
-
def parse( args )
|
18
|
-
std_opts = standard_options
|
19
|
-
|
20
|
-
opts = OptionParser.new
|
21
|
-
opts.banner = 'Usage: bones update <directory>'
|
22
|
-
|
23
|
-
opts.separator ''
|
24
|
-
opts.separator ' Copy the Mr Bones rake tasks into the project directory'
|
25
|
-
|
26
|
-
opts.separator ''
|
27
|
-
opts.separator ' Common Options:'
|
28
|
-
opts.on_tail( '-h', '--help', 'show this message' ) {
|
29
|
-
@out.puts opts
|
30
|
-
exit
|
31
|
-
}
|
32
|
-
|
33
|
-
# parse the command line arguments
|
34
|
-
opts.parse! args
|
35
|
-
options[:output_dir] = args.empty? ? nil : args.join('_')
|
36
|
-
|
37
|
-
if output_dir.nil?
|
38
|
-
@out.puts opts
|
39
|
-
exit 1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
end # class CreateCommand
|
44
|
-
end # class App
|
45
|
-
end # module Bones
|
46
|
-
|
47
|
-
# EOF
|
data/lib/bones/debug.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'pp'
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
module Bones
|
6
|
-
|
7
|
-
# Helper module that will pretty print OpenStruct objects. It is used mainly
|
8
|
-
# for debugging the Mr Bones project open struct.
|
9
|
-
#
|
10
|
-
module Debug
|
11
|
-
|
12
|
-
# :stopdoc:
|
13
|
-
KEY_LENGTH = 20
|
14
|
-
VAR_LENGTH = 78 - 6 - KEY_LENGTH
|
15
|
-
SEP = "\n" + ' '*(KEY_LENGTH+6)
|
16
|
-
FMT = " %-#{KEY_LENGTH}s => %s"
|
17
|
-
# :startdoc:
|
18
|
-
|
19
|
-
# Print all the keys for the given _ostruct_ to stdout. If a _prefix_ is
|
20
|
-
# given, then the open struct keys will be prefixed with this string.
|
21
|
-
#
|
22
|
-
def self.show( ostruct, prefix = '' )
|
23
|
-
sio = StringIO.new
|
24
|
-
|
25
|
-
h = ostruct.instance_variable_get(:@table)
|
26
|
-
h.keys.map {|k| k.to_s}.sort.each do |k|
|
27
|
-
sio.seek 0
|
28
|
-
sio.truncate 0
|
29
|
-
next if k =~ %r/^_/o
|
30
|
-
|
31
|
-
val = h[k.to_sym]
|
32
|
-
if val.instance_of?(OpenStruct)
|
33
|
-
self.show(val, prefix + k + '.')
|
34
|
-
else
|
35
|
-
PP.pp(val, sio, VAR_LENGTH)
|
36
|
-
sio.seek 0
|
37
|
-
val = sio.read
|
38
|
-
val = val.split("\n").join(SEP)
|
39
|
-
|
40
|
-
key = prefix + k
|
41
|
-
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
42
|
-
puts(FMT % [key, val])
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Print a single attribute from the given _ostruct_ to stdout. The
|
48
|
-
# attributed is identified by the given _key_.
|
49
|
-
#
|
50
|
-
def self.show_attr( ostruct, key )
|
51
|
-
sio = StringIO.new
|
52
|
-
|
53
|
-
key = key.dup if key.frozen?
|
54
|
-
val = key.split('.').inject(ostruct) {|os,k| os.send(k)}
|
55
|
-
|
56
|
-
if val.instance_of?(OpenStruct)
|
57
|
-
self.show(val, key + '.')
|
58
|
-
else
|
59
|
-
PP.pp(val, sio, VAR_LENGTH)
|
60
|
-
sio.seek 0
|
61
|
-
val = sio.read
|
62
|
-
val = val.split("\n").join(SEP)
|
63
|
-
|
64
|
-
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
65
|
-
puts(FMT % [key, val])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end # module Debug
|
70
|
-
end # module Bones
|
71
|
-
|
72
|
-
# EOF
|
data/lib/bones/tasks/ann.rake
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
|
2
|
-
begin
|
3
|
-
require 'bones/smtp_tls'
|
4
|
-
rescue LoadError
|
5
|
-
require 'net/smtp'
|
6
|
-
end
|
7
|
-
require 'time'
|
8
|
-
|
9
|
-
namespace :ann do
|
10
|
-
|
11
|
-
# A prerequisites task that all other tasks depend upon
|
12
|
-
task :prereqs
|
13
|
-
|
14
|
-
file PROJ.ann.file do
|
15
|
-
ann = PROJ.ann
|
16
|
-
puts "Generating #{ann.file}"
|
17
|
-
File.open(ann.file,'w') do |fd|
|
18
|
-
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
19
|
-
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
20
|
-
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
21
|
-
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
22
|
-
fd.puts
|
23
|
-
fd.puts("== DESCRIPTION")
|
24
|
-
fd.puts
|
25
|
-
fd.puts(PROJ.description)
|
26
|
-
fd.puts
|
27
|
-
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
28
|
-
fd.puts
|
29
|
-
ann.paragraphs.each do |p|
|
30
|
-
fd.puts "== #{p.upcase}"
|
31
|
-
fd.puts
|
32
|
-
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
33
|
-
fd.puts
|
34
|
-
end
|
35
|
-
fd.puts ann.text if ann.text
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "Create an announcement file"
|
40
|
-
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
41
|
-
|
42
|
-
desc "Send an email announcement"
|
43
|
-
task :email => ['ann:prereqs', PROJ.ann.file] do
|
44
|
-
ann = PROJ.ann
|
45
|
-
from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
|
46
|
-
to = Array(ann.email[:to])
|
47
|
-
|
48
|
-
### build a mail header for RFC 822
|
49
|
-
rfc822msg = "From: #{from}\n"
|
50
|
-
rfc822msg << "To: #{to.join(',')}\n"
|
51
|
-
rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
|
52
|
-
rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
|
53
|
-
rfc822msg << "\n"
|
54
|
-
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
55
|
-
rfc822msg << "Message-Id: "
|
56
|
-
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
57
|
-
rfc822msg << File.read(ann.file)
|
58
|
-
|
59
|
-
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
60
|
-
ann.email[key]
|
61
|
-
end
|
62
|
-
|
63
|
-
params[3] = PROJ.email if params[3].nil?
|
64
|
-
|
65
|
-
if params[4].nil?
|
66
|
-
STDOUT.write "Please enter your e-mail password (#{params[3]}): "
|
67
|
-
params[4] = STDIN.gets.chomp
|
68
|
-
end
|
69
|
-
|
70
|
-
### send email
|
71
|
-
Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
|
72
|
-
end
|
73
|
-
end # namespace :ann
|
74
|
-
|
75
|
-
desc 'Alias to ann:announcement'
|
76
|
-
task :ann => 'ann:announcement'
|
77
|
-
|
78
|
-
CLOBBER << PROJ.ann.file
|
79
|
-
|
80
|
-
# EOF
|