TwP-bones 2.3.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 +183 -0
- data/README.rdoc +370 -0
- data/Rakefile +59 -0
- data/bin/bones +7 -0
- data/data/.bnsignore +12 -0
- data/data/History.txt.bns +4 -0
- data/data/README.txt.bns +48 -0
- data/data/Rakefile.bns +30 -0
- data/data/bin/NAME.bns +8 -0
- data/data/lib/NAME.rb.bns +49 -0
- data/data/spec/NAME_spec.rb.bns +7 -0
- data/data/spec/spec_helper.rb.bns +16 -0
- data/data/test/test_NAME.rb +0 -0
- data/lib/bones/annotation_extractor.rb +111 -0
- data/lib/bones/app/command.rb +130 -0
- data/lib/bones/app/create_command.rb +86 -0
- data/lib/bones/app/file_manager.rb +176 -0
- data/lib/bones/app/freeze_command.rb +72 -0
- data/lib/bones/app/info_command.rb +58 -0
- data/lib/bones/app/unfreeze_command.rb +53 -0
- data/lib/bones/app/update_command.rb +47 -0
- data/lib/bones/app.rb +92 -0
- data/lib/bones/debug.rb +71 -0
- data/lib/bones/smtp_tls.rb +75 -0
- data/lib/bones/tasks/ann.rake +80 -0
- data/lib/bones/tasks/bones.rake +20 -0
- data/lib/bones/tasks/gem.rake +201 -0
- data/lib/bones/tasks/git.rake +40 -0
- data/lib/bones/tasks/notes.rake +27 -0
- data/lib/bones/tasks/post_load.rake +34 -0
- data/lib/bones/tasks/rdoc.rake +50 -0
- data/lib/bones/tasks/rubyforge.rake +55 -0
- data/lib/bones/tasks/setup.rb +296 -0
- data/lib/bones/tasks/spec.rake +54 -0
- data/lib/bones/tasks/svn.rake +47 -0
- data/lib/bones/tasks/test.rake +40 -0
- data/lib/bones.rb +62 -0
- data/spec/bones/app/file_manager_spec.rb +150 -0
- data/spec/bones/app_spec.rb +97 -0
- data/spec/bones_spec.rb +18 -0
- data/spec/data/data/NAME/NAME.rb.bns +5 -0
- data/spec/data/data/README.txt.bns +48 -0
- data/spec/data/data/Rakefile.bns +30 -0
- data/spec/data/data/lib/NAME.rb.bns +49 -0
- data/spec/data/foo/README.txt +0 -0
- data/spec/data/foo/Rakefile +0 -0
- data/spec/spec_helper.rb +44 -0
- metadata +126 -0
|
@@ -0,0 +1,58 @@
|
|
|
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
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
|
@@ -0,0 +1,47 @@
|
|
|
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/app.rb
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require 'erb'
|
|
5
|
+
|
|
6
|
+
module Bones
|
|
7
|
+
class App
|
|
8
|
+
|
|
9
|
+
# Create a new instance of App, and run the +bones+ application given
|
|
10
|
+
# the command line _args_.
|
|
11
|
+
#
|
|
12
|
+
def self.run( args )
|
|
13
|
+
self.new.run args
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Create a new main instance using _io_ for standard output and _err_ for
|
|
17
|
+
# error messages.
|
|
18
|
+
#
|
|
19
|
+
def initialize( out = STDOUT, err = STDERR )
|
|
20
|
+
@out = out
|
|
21
|
+
@err = err
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Parse the desired user command and run that command object.
|
|
25
|
+
#
|
|
26
|
+
def run( args )
|
|
27
|
+
cmd_str = args.shift
|
|
28
|
+
cmd = case cmd_str
|
|
29
|
+
when 'create'; CreateCommand.new(@out, @err)
|
|
30
|
+
when 'update'; UpdateCommand.new(@out, @err)
|
|
31
|
+
when 'freeze'; FreezeCommand.new(@out, @err)
|
|
32
|
+
when 'unfreeze'; UnfreezeCommand.new(@out, @err)
|
|
33
|
+
when 'info'; InfoCommand.new(@out, @err)
|
|
34
|
+
when nil, '-h', '--help'
|
|
35
|
+
help
|
|
36
|
+
when '-v', '--version'
|
|
37
|
+
@out.puts "Mr Bones #{::Bones::VERSION}"
|
|
38
|
+
nil
|
|
39
|
+
else
|
|
40
|
+
raise "Unknown command #{cmd_str.inspect}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
cmd.run args if cmd
|
|
44
|
+
|
|
45
|
+
rescue StandardError => err
|
|
46
|
+
@err.puts "ERROR: While executing bones ... (#{err.class})"
|
|
47
|
+
@err.puts " #{err.to_s}"
|
|
48
|
+
exit 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Show the toplevel Mr Bones help message.
|
|
52
|
+
#
|
|
53
|
+
def help
|
|
54
|
+
@out.puts <<-MSG
|
|
55
|
+
|
|
56
|
+
Mr Bones is a handy tool that builds a skeleton for your new Ruby
|
|
57
|
+
projects. The skeleton contains some starter code and a collection of
|
|
58
|
+
rake tasks to ease the management and deployment of your source code.
|
|
59
|
+
|
|
60
|
+
Usage:
|
|
61
|
+
bones -h/--help
|
|
62
|
+
bones -v/--version
|
|
63
|
+
bones command [options] [arguments]
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
bones create new_project
|
|
67
|
+
bones freeze -r git://github.com/fudgestudios/bort.git bort
|
|
68
|
+
bones create -s bort new_rails_project
|
|
69
|
+
|
|
70
|
+
Commands:
|
|
71
|
+
bones create create a new project from a skeleton
|
|
72
|
+
bones update copy Mr Bones tasks to a project
|
|
73
|
+
bones freeze create a new skeleton in ~/.mrbones/
|
|
74
|
+
bones unfreeze remove a skeleton from ~/.mrbones/
|
|
75
|
+
bones info show information about available skeletons
|
|
76
|
+
|
|
77
|
+
Further Help:
|
|
78
|
+
Each command has a '--help' option that will provide detailed
|
|
79
|
+
information for that command.
|
|
80
|
+
|
|
81
|
+
http://codeforpeople.rubyforge.org/bones/
|
|
82
|
+
|
|
83
|
+
MSG
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end # class App
|
|
88
|
+
end # module Bones
|
|
89
|
+
|
|
90
|
+
Bones.require_all_libs_relative_to(__FILE__)
|
|
91
|
+
|
|
92
|
+
# EOF
|
data/lib/bones/debug.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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.truncate 0
|
|
28
|
+
next if k =~ %r/^_/o
|
|
29
|
+
|
|
30
|
+
val = h[k.to_sym]
|
|
31
|
+
if val.instance_of?(OpenStruct)
|
|
32
|
+
self.show(val, prefix + k + '.')
|
|
33
|
+
else
|
|
34
|
+
PP.pp(val, sio, VAR_LENGTH)
|
|
35
|
+
sio.seek 0
|
|
36
|
+
val = sio.read
|
|
37
|
+
val = val.split("\n").join(SEP)
|
|
38
|
+
|
|
39
|
+
key = prefix + k
|
|
40
|
+
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
|
41
|
+
puts(FMT % [key, val])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Print a single attribute from the given _ostruct_ to stdout. The
|
|
47
|
+
# attributed is identified by the given _key_.
|
|
48
|
+
#
|
|
49
|
+
def self.show_attr( ostruct, key )
|
|
50
|
+
sio = StringIO.new
|
|
51
|
+
|
|
52
|
+
key = key.dup if key.frozen?
|
|
53
|
+
val = key.split('.').inject(ostruct) {|os,k| os.send(k)}
|
|
54
|
+
|
|
55
|
+
if val.instance_of?(OpenStruct)
|
|
56
|
+
self.show(val, key + '.')
|
|
57
|
+
else
|
|
58
|
+
PP.pp(val, sio, VAR_LENGTH)
|
|
59
|
+
sio.seek 0
|
|
60
|
+
val = sio.read
|
|
61
|
+
val = val.split("\n").join(SEP)
|
|
62
|
+
|
|
63
|
+
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
|
64
|
+
puts(FMT % [key, val])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end # module Debug
|
|
69
|
+
end # module Bones
|
|
70
|
+
|
|
71
|
+
# EOF
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
# This code enables SMTPTLS authentication requireed for sending mail
|
|
3
|
+
# via the gmail servers. I found this code via a blog entry from James
|
|
4
|
+
# Britt.
|
|
5
|
+
#
|
|
6
|
+
# http://d.hatena.ne.jp/zorio/20060416
|
|
7
|
+
# http://www.jamesbritt.com/2007/12/18/sending-mail-through-gmail-with-ruby-s-net-smtp
|
|
8
|
+
|
|
9
|
+
require "openssl"
|
|
10
|
+
require "net/smtp"
|
|
11
|
+
|
|
12
|
+
Net::SMTP.class_eval do
|
|
13
|
+
private
|
|
14
|
+
def do_start(helodomain, user, secret, authtype)
|
|
15
|
+
raise IOError, 'SMTP session already started' if @started
|
|
16
|
+
|
|
17
|
+
if user or secret
|
|
18
|
+
if 3 == self.method(:check_auth_args).arity
|
|
19
|
+
check_auth_args(user, secret, authtype)
|
|
20
|
+
else
|
|
21
|
+
check_auth_args(user, secret)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
|
|
26
|
+
@socket = Net::InternetMessageIO.new(sock)
|
|
27
|
+
@socket.read_timeout = 60 #@read_timeout
|
|
28
|
+
@socket.debug_output = STDERR #@debug_output
|
|
29
|
+
|
|
30
|
+
check_response(critical { recv_response() })
|
|
31
|
+
do_helo(helodomain)
|
|
32
|
+
|
|
33
|
+
raise 'openssl library not installed' unless defined?(OpenSSL)
|
|
34
|
+
starttls
|
|
35
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
|
36
|
+
ssl.sync_close = true
|
|
37
|
+
ssl.connect
|
|
38
|
+
@socket = Net::InternetMessageIO.new(ssl)
|
|
39
|
+
@socket.read_timeout = 60 #@read_timeout
|
|
40
|
+
@socket.debug_output = STDERR #@debug_output
|
|
41
|
+
do_helo(helodomain)
|
|
42
|
+
|
|
43
|
+
authenticate user, secret, authtype if user
|
|
44
|
+
@started = true
|
|
45
|
+
ensure
|
|
46
|
+
unless @started
|
|
47
|
+
# authentication failed, cancel connection.
|
|
48
|
+
@socket.close if not @started and @socket and not @socket.closed?
|
|
49
|
+
@socket = nil
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def do_helo(helodomain)
|
|
54
|
+
begin
|
|
55
|
+
if @esmtp
|
|
56
|
+
ehlo helodomain
|
|
57
|
+
else
|
|
58
|
+
helo helodomain
|
|
59
|
+
end
|
|
60
|
+
rescue Net::ProtocolError
|
|
61
|
+
if @esmtp
|
|
62
|
+
@esmtp = false
|
|
63
|
+
@error_occured = false
|
|
64
|
+
retry
|
|
65
|
+
end
|
|
66
|
+
raise
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def starttls
|
|
71
|
+
getok('STARTTLS')
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# EOF
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
if HAVE_BONES
|
|
3
|
+
|
|
4
|
+
namespace :bones do
|
|
5
|
+
|
|
6
|
+
desc 'Show the PROJ open struct'
|
|
7
|
+
task :debug do |t|
|
|
8
|
+
atr = if t.application.top_level_tasks.length == 2
|
|
9
|
+
t.application.top_level_tasks.pop
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
if atr then Bones::Debug.show_attr(PROJ, atr)
|
|
13
|
+
else Bones::Debug.show PROJ end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end # namespace :bones
|
|
17
|
+
|
|
18
|
+
end # HAVE_BONES
|
|
19
|
+
|
|
20
|
+
# EOF
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
|
|
2
|
+
require 'find'
|
|
3
|
+
require 'rake/packagetask'
|
|
4
|
+
require 'rubygems/user_interaction'
|
|
5
|
+
require 'rubygems/builder'
|
|
6
|
+
|
|
7
|
+
module Bones
|
|
8
|
+
class GemPackageTask < Rake::PackageTask
|
|
9
|
+
# Ruby GEM spec containing the metadata for this package. The
|
|
10
|
+
# name, version and package_files are automatically determined
|
|
11
|
+
# from the GEM spec and don't need to be explicitly provided.
|
|
12
|
+
#
|
|
13
|
+
attr_accessor :gem_spec
|
|
14
|
+
|
|
15
|
+
# Tasks from the Bones gem directory
|
|
16
|
+
attr_reader :bones_files
|
|
17
|
+
|
|
18
|
+
# Create a GEM Package task library. Automatically define the gem
|
|
19
|
+
# if a block is given. If no block is supplied, then +define+
|
|
20
|
+
# needs to be called to define the task.
|
|
21
|
+
#
|
|
22
|
+
def initialize(gem_spec)
|
|
23
|
+
init(gem_spec)
|
|
24
|
+
yield self if block_given?
|
|
25
|
+
define if block_given?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Initialization tasks without the "yield self" or define
|
|
29
|
+
# operations.
|
|
30
|
+
#
|
|
31
|
+
def init(gem)
|
|
32
|
+
super(gem.name, gem.version)
|
|
33
|
+
@gem_spec = gem
|
|
34
|
+
@package_files += gem_spec.files if gem_spec.files
|
|
35
|
+
@bones_files = []
|
|
36
|
+
|
|
37
|
+
local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
|
|
38
|
+
if !test(?e, local_setup)
|
|
39
|
+
Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Create the Rake tasks and actions specified by this
|
|
44
|
+
# GemPackageTask. (+define+ is automatically called if a block is
|
|
45
|
+
# given to +new+).
|
|
46
|
+
#
|
|
47
|
+
def define
|
|
48
|
+
super
|
|
49
|
+
task :prereqs
|
|
50
|
+
task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
|
|
51
|
+
file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
|
|
52
|
+
when_writing("Creating GEM") {
|
|
53
|
+
chdir(package_dir_path) do
|
|
54
|
+
Gem::Builder.new(gem_spec).build
|
|
55
|
+
verbose(true) {
|
|
56
|
+
mv gem_file, "../#{gem_file}"
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
file package_dir_path => bones_files do
|
|
63
|
+
mkdir_p package_dir rescue nil
|
|
64
|
+
|
|
65
|
+
gem_spec.files = (gem_spec.files +
|
|
66
|
+
bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
|
|
67
|
+
|
|
68
|
+
bones_files.each do |fn|
|
|
69
|
+
base_fn = File.join('tasks', File.basename(fn))
|
|
70
|
+
f = File.join(package_dir_path, base_fn)
|
|
71
|
+
fdir = File.dirname(f)
|
|
72
|
+
mkdir_p(fdir) if !File.exist?(fdir)
|
|
73
|
+
if File.directory?(fn)
|
|
74
|
+
mkdir_p(f)
|
|
75
|
+
else
|
|
76
|
+
raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f)
|
|
77
|
+
safe_ln(fn, f)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def gem_file
|
|
84
|
+
if @gem_spec.platform == Gem::Platform::RUBY
|
|
85
|
+
"#{package_name}.gem"
|
|
86
|
+
else
|
|
87
|
+
"#{package_name}-#{@gem_spec.platform}.gem"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end # class GemPackageTask
|
|
91
|
+
end # module Bones
|
|
92
|
+
|
|
93
|
+
namespace :gem do
|
|
94
|
+
|
|
95
|
+
PROJ.gem._spec = Gem::Specification.new do |s|
|
|
96
|
+
s.name = PROJ.name
|
|
97
|
+
s.version = PROJ.version
|
|
98
|
+
s.summary = PROJ.summary
|
|
99
|
+
s.authors = Array(PROJ.authors)
|
|
100
|
+
s.email = PROJ.email
|
|
101
|
+
s.homepage = Array(PROJ.url).first
|
|
102
|
+
s.rubyforge_project = PROJ.rubyforge.name
|
|
103
|
+
|
|
104
|
+
s.description = PROJ.description
|
|
105
|
+
|
|
106
|
+
PROJ.gem.dependencies.each do |dep|
|
|
107
|
+
s.add_dependency(*dep)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
PROJ.gem.development_dependencies.each do |dep|
|
|
111
|
+
s.add_development_dependency(*dep)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
s.files = PROJ.gem.files
|
|
115
|
+
s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
|
|
116
|
+
s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
|
|
117
|
+
|
|
118
|
+
s.bindir = 'bin'
|
|
119
|
+
dirs = Dir["{#{PROJ.libs.join(',')}}"]
|
|
120
|
+
s.require_paths = dirs unless dirs.empty?
|
|
121
|
+
|
|
122
|
+
incl = Regexp.new(PROJ.rdoc.include.join('|'))
|
|
123
|
+
excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
|
|
124
|
+
excl = Regexp.new(excl.join('|'))
|
|
125
|
+
rdoc_files = PROJ.gem.files.find_all do |fn|
|
|
126
|
+
case fn
|
|
127
|
+
when excl; false
|
|
128
|
+
when incl; true
|
|
129
|
+
else false end
|
|
130
|
+
end
|
|
131
|
+
s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
|
|
132
|
+
s.extra_rdoc_files = rdoc_files
|
|
133
|
+
s.has_rdoc = true
|
|
134
|
+
|
|
135
|
+
if test ?f, PROJ.test.file
|
|
136
|
+
s.test_file = PROJ.test.file
|
|
137
|
+
else
|
|
138
|
+
s.test_files = PROJ.test.files.to_a
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Do any extra stuff the user wants
|
|
142
|
+
PROJ.gem.extras.each do |msg, val|
|
|
143
|
+
case val
|
|
144
|
+
when Proc
|
|
145
|
+
val.call(s.send(msg))
|
|
146
|
+
else
|
|
147
|
+
s.send "#{msg}=", val
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end # Gem::Specification.new
|
|
151
|
+
|
|
152
|
+
Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg|
|
|
153
|
+
pkg.need_tar = PROJ.gem.need_tar
|
|
154
|
+
pkg.need_zip = PROJ.gem.need_zip
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
desc 'Show information about the gem'
|
|
158
|
+
task :debug => 'gem:prereqs' do
|
|
159
|
+
puts PROJ.gem._spec.to_ruby
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
desc 'Write the gemspec '
|
|
163
|
+
task :spec => 'gem:prereqs' do
|
|
164
|
+
File.open("#{PROJ.name}.gemspec", 'w') do |f|
|
|
165
|
+
f.write PROJ.gem._spec.to_ruby
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
desc 'Install the gem'
|
|
170
|
+
task :install => [:clobber, 'gem:package'] do
|
|
171
|
+
sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
|
|
172
|
+
|
|
173
|
+
# use this version of the command for rubygems > 1.0.0
|
|
174
|
+
#sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
desc 'Uninstall the gem'
|
|
178
|
+
task :uninstall do
|
|
179
|
+
installed_list = Gem.source_index.find_name(PROJ.name)
|
|
180
|
+
if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
|
|
181
|
+
sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
desc 'Reinstall the gem'
|
|
186
|
+
task :reinstall => [:uninstall, :install]
|
|
187
|
+
|
|
188
|
+
desc 'Cleanup the gem'
|
|
189
|
+
task :cleanup do
|
|
190
|
+
sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
|
|
191
|
+
end
|
|
192
|
+
end # namespace :gem
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
desc 'Alias to gem:package'
|
|
196
|
+
task :gem => 'gem:package'
|
|
197
|
+
|
|
198
|
+
task :clobber => 'gem:clobber_package'
|
|
199
|
+
remove_desc_for_task 'gem:clobber_package'
|
|
200
|
+
|
|
201
|
+
# EOF
|