bones 1.3.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +22 -1
- data/Manifest.txt +5 -4
- data/README.txt +76 -6
- data/Rakefile +21 -17
- data/bin/bones +0 -0
- data/data/Rakefile.erb +2 -2
- data/data/bin/NAME.erb +0 -0
- data/data/tasks/ann.rake +19 -14
- data/data/tasks/bones.rake +5 -24
- data/data/tasks/gem.rake +37 -35
- data/data/tasks/notes.rake +28 -0
- data/data/tasks/post_load.rake +16 -11
- data/data/tasks/{doc.rake → rdoc.rake} +10 -7
- data/data/tasks/rubyforge.rake +10 -10
- data/data/tasks/setup.rb +119 -80
- data/data/tasks/spec.rake +12 -13
- data/data/tasks/svn.rake +15 -11
- data/data/tasks/test.rake +6 -6
- data/lib/bones.rb +10 -2
- data/lib/bones/annotation_extractor.rb +32 -11
- data/lib/bones/debug.rb +72 -0
- data/lib/bones/main.rb +41 -25
- data/tasks/ann.rake +20 -15
- data/tasks/bones.rake +5 -24
- data/tasks/gem.rake +38 -36
- data/tasks/notes.rake +28 -0
- data/tasks/post_load.rake +16 -11
- data/tasks/{doc.rake → rdoc.rake} +11 -8
- data/tasks/rubyforge.rake +11 -11
- data/tasks/setup.rb +120 -81
- data/tasks/spec.rake +12 -13
- data/tasks/svn.rake +16 -12
- data/tasks/test.rake +6 -6
- metadata +9 -8
- data/data/tasks/annotations.rake +0 -22
- data/tasks/annotations.rake +0 -22
data/data/tasks/svn.rake
CHANGED
@@ -1,32 +1,36 @@
|
|
1
1
|
# $Id$
|
2
2
|
|
3
|
+
if HAVE_SVN
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
unless PROJ.svn_root
|
5
|
+
unless PROJ.svn.root
|
7
6
|
info = %x/svn info ./
|
8
7
|
m = %r/^Repository Root:\s+(.*)$/.match(info)
|
9
|
-
PROJ.
|
8
|
+
PROJ.svn.root = (m.nil? ? '' : m[1])
|
10
9
|
end
|
11
|
-
PROJ.
|
10
|
+
PROJ.svn.root = File.join(PROJ.svn.root, PROJ.svn.path) unless PROJ.svn.path.empty?
|
12
11
|
|
13
12
|
namespace :svn do
|
14
13
|
|
14
|
+
# A prerequisites task that all other tasks depend upon
|
15
|
+
task :prereqs
|
16
|
+
|
15
17
|
desc 'Show tags from the SVN repository'
|
16
|
-
task :show_tags do |t|
|
17
|
-
tags = %x/svn list #{File.join(PROJ.
|
18
|
+
task :show_tags => 'svn:prereqs' do |t|
|
19
|
+
tags = %x/svn list #{File.join(PROJ.svn.root, PROJ.svn.tags)}/
|
18
20
|
tags.gsub!(%r/\/$/, '')
|
21
|
+
tags = tags.split("\n").sort {|a,b| b <=> a}
|
19
22
|
puts tags
|
20
23
|
end
|
21
24
|
|
22
25
|
desc 'Create a new tag in the SVN repository'
|
23
|
-
task :create_tag do |t|
|
26
|
+
task :create_tag => 'svn:prereqs' do |t|
|
24
27
|
v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
|
25
28
|
abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
|
26
29
|
|
27
|
-
|
30
|
+
svn = PROJ.svn
|
31
|
+
trunk = File.join(svn.root, svn.trunk)
|
28
32
|
tag = "%s-%s" % [PROJ.name, PROJ.version]
|
29
|
-
tag = File.join(
|
33
|
+
tag = File.join(svn.root, svn.tags, tag)
|
30
34
|
msg = "Creating tag for #{PROJ.name} version #{PROJ.version}"
|
31
35
|
|
32
36
|
puts "Creating SVN tag '#{tag}'"
|
@@ -39,6 +43,6 @@ end # namespace :svn
|
|
39
43
|
|
40
44
|
task 'gem:release' => 'svn:create_tag'
|
41
45
|
|
42
|
-
end # if PROJ.svn
|
46
|
+
end # if PROJ.svn.path
|
43
47
|
|
44
48
|
# EOF
|
data/data/tasks/test.rake
CHANGED
@@ -6,19 +6,19 @@ namespace :test do
|
|
6
6
|
|
7
7
|
Rake::TestTask.new(:run) do |t|
|
8
8
|
t.libs = PROJ.libs
|
9
|
-
t.test_files = if test(?f, PROJ.
|
10
|
-
else PROJ.
|
9
|
+
t.test_files = if test(?f, PROJ.test.file) then [PROJ.test.file]
|
10
|
+
else PROJ.test.files end
|
11
11
|
t.ruby_opts += PROJ.ruby_opts
|
12
|
-
t.ruby_opts += PROJ.
|
12
|
+
t.ruby_opts += PROJ.test.opts
|
13
13
|
end
|
14
14
|
|
15
15
|
if HAVE_RCOV
|
16
16
|
desc 'Run rcov on the unit tests'
|
17
17
|
task :rcov => :clobber_rcov do
|
18
|
-
opts = PROJ.
|
18
|
+
opts = PROJ.rcov.opts.dup << '-o' << PROJ.rcov.dir
|
19
19
|
opts = opts.join(' ')
|
20
|
-
files = if test(?f, PROJ.
|
21
|
-
else PROJ.
|
20
|
+
files = if test(?f, PROJ.test.file) then [PROJ.test.file]
|
21
|
+
else PROJ.test.files end
|
22
22
|
files = files.join(' ')
|
23
23
|
sh "#{RCOV} #{files} #{opts}"
|
24
24
|
end
|
data/lib/bones.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
-
# $Id: bones.rb
|
1
|
+
# $Id: bones.rb 571 2008-03-12 04:30:45Z tim_pease $
|
2
2
|
|
3
3
|
module Bones
|
4
4
|
|
5
5
|
# :stopdoc:
|
6
|
-
VERSION = '
|
6
|
+
VERSION = '2.0.0'
|
7
7
|
PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
8
8
|
WIN32 = %r/win32/ =~ RUBY_PLATFORM
|
9
9
|
DEV_NULL = WIN32 ? 'NUL:' : '/dev/null'
|
10
10
|
# :startdoc:
|
11
11
|
|
12
|
+
# Returns the path for Mr Bones. If any arguments are given,
|
13
|
+
# they will be joined to the end of the path using
|
14
|
+
# <tt>File.join</tt>.
|
15
|
+
#
|
16
|
+
def self.path( *args )
|
17
|
+
args.empty? ? PATH : File.join(PATH, *args)
|
18
|
+
end
|
19
|
+
|
12
20
|
# call-seq:
|
13
21
|
# Bones.require_all_libs_relative_to( filename, directory = nil )
|
14
22
|
#
|
@@ -1,4 +1,11 @@
|
|
1
|
-
# $Id: annotation_extractor.rb
|
1
|
+
# $Id: annotation_extractor.rb 588 2008-04-07 20:43:07Z tim_pease $
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'facets/ansicode'
|
5
|
+
HAVE_COLOR = true
|
6
|
+
rescue LoadError
|
7
|
+
HAVE_COLOR = false
|
8
|
+
end
|
2
9
|
|
3
10
|
module Bones
|
4
11
|
|
@@ -23,20 +30,26 @@ class AnnotationExtractor
|
|
23
30
|
# will search for all athe annotations and display them on standard
|
24
31
|
# output.
|
25
32
|
#
|
26
|
-
def self.enumerate( project, tag, opts = {} )
|
27
|
-
extractor = new(project, tag)
|
33
|
+
def self.enumerate( project, tag, id = nil, opts = {} )
|
34
|
+
extractor = new(project, tag, id)
|
28
35
|
extractor.display(extractor.find, opts)
|
29
36
|
end
|
30
37
|
|
31
|
-
attr_reader :tag, :project
|
38
|
+
attr_reader :tag, :project, :id
|
32
39
|
|
33
40
|
# Creates a new annotation extractor configured to use the _project_ open
|
34
41
|
# strcut and to search for the given _tag_ (which can be more than one tag
|
35
42
|
# via a regular expression 'or' operation -- i.e. THIS|THAT|OTHER)
|
36
43
|
#
|
37
|
-
def initialize( project, tag )
|
44
|
+
def initialize( project, tag, id)
|
38
45
|
@project = project
|
39
46
|
@tag = tag
|
47
|
+
@id = @id_rgxp = nil
|
48
|
+
|
49
|
+
unless id.nil? or id.empty?
|
50
|
+
@id = id
|
51
|
+
@id_rgxp = Regexp.new(Regexp.escape(id), Regexp::IGNORECASE)
|
52
|
+
end
|
40
53
|
end
|
41
54
|
|
42
55
|
# Iterate over all the files in the project manifest and extract
|
@@ -46,11 +59,12 @@ class AnnotationExtractor
|
|
46
59
|
def find
|
47
60
|
results = {}
|
48
61
|
rgxp = %r/(#{tag}):?\s*(.*?)(?:\s*(?:-?%>|\*+\/))?$/o
|
49
|
-
extensions = project.annotation_extensions.dup
|
50
|
-
exclude = if project.annotation_exclude.empty? then nil
|
51
|
-
else Regexp.new(project.annotation_exclude.join('|')) end
|
52
62
|
|
53
|
-
project.
|
63
|
+
extensions = project.notes.extensions.dup
|
64
|
+
exclude = if project.notes.exclude.empty? then nil
|
65
|
+
else Regexp.new(project.notes.exclude.join('|')) end
|
66
|
+
|
67
|
+
project.gem.files.each do |fn|
|
54
68
|
next if exclude && exclude =~ fn
|
55
69
|
next unless extensions.include? File.extname(fn)
|
56
70
|
results.update(extract_annotations_from(fn, rgxp))
|
@@ -66,8 +80,15 @@ class AnnotationExtractor
|
|
66
80
|
lineno = 0
|
67
81
|
result = File.readlines(file).inject([]) do |list, line|
|
68
82
|
lineno += 1
|
69
|
-
next list unless
|
70
|
-
list << Annotation.new(lineno,
|
83
|
+
next list unless m = pattern.match(line)
|
84
|
+
next list << Annotation.new(lineno, m[1], m[2]) unless id
|
85
|
+
|
86
|
+
text = m[2]
|
87
|
+
if text =~ @id_rgxp
|
88
|
+
text.gsub!(@id_rgxp) {|str| Console::ANSICode.green(str)} if HAVE_COLOR
|
89
|
+
list << Annotation.new(lineno, m[1], text)
|
90
|
+
end
|
91
|
+
list
|
71
92
|
end
|
72
93
|
result.empty? ? {} : { file => result }
|
73
94
|
end
|
data/lib/bones/debug.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# $Id: debug.rb 579 2008-03-19 18:53:22Z tim_pease $
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module Bones
|
7
|
+
|
8
|
+
# Helper module that will pretty print OpenStruct objects. It is used mainly
|
9
|
+
# for debugging the Mr Bones project open struct.
|
10
|
+
#
|
11
|
+
module Debug
|
12
|
+
|
13
|
+
# :stopdoc:
|
14
|
+
KEY_LENGTH = 20
|
15
|
+
VAR_LENGTH = 78 - 6 - KEY_LENGTH
|
16
|
+
SEP = "\n" + ' '*(KEY_LENGTH+6)
|
17
|
+
FMT = " %-#{KEY_LENGTH}s => %s"
|
18
|
+
# :startdoc:
|
19
|
+
|
20
|
+
# Print all the keys for the given _ostruct_ to stdout. If a _prefix_ is
|
21
|
+
# given, then the open struct keys will be prefixed with this string.
|
22
|
+
#
|
23
|
+
def self.show( ostruct, prefix = '' )
|
24
|
+
sio = StringIO.new
|
25
|
+
|
26
|
+
h = ostruct.instance_variable_get(:@table)
|
27
|
+
h.keys.map {|k| k.to_s}.sort.each do |k|
|
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/main.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: main.rb
|
1
|
+
# $Id: main.rb 579 2008-03-19 18:53:22Z tim_pease $
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'optparse'
|
@@ -26,7 +26,7 @@ class Main
|
|
26
26
|
#
|
27
27
|
def parse( args )
|
28
28
|
self.data = File.join(mrbones_dir, 'data')
|
29
|
-
self.data =
|
29
|
+
self.data = ::Bones.path('data') unless test(?d, data)
|
30
30
|
self.update = false
|
31
31
|
self.verbose = false
|
32
32
|
|
@@ -41,6 +41,18 @@ class Main
|
|
41
41
|
opts.on('-d', '--directory DIRECTORY', String,
|
42
42
|
'project directory to create',
|
43
43
|
'(defaults to project_name)') {|dir| self.output_dir = dir}
|
44
|
+
opts.on('-s', '--skeleton NAME', String,
|
45
|
+
'project skeleton to use') do |name|
|
46
|
+
path = File.join(mrbones_dir, name)
|
47
|
+
if test(?d, path)
|
48
|
+
self.data = path
|
49
|
+
elsif test(?d, name)
|
50
|
+
self.data = name
|
51
|
+
else
|
52
|
+
STDOUT.puts " unknown skeleton '#{name}'"
|
53
|
+
exit
|
54
|
+
end
|
55
|
+
end
|
44
56
|
|
45
57
|
opts.separator ''
|
46
58
|
opts.on('--freeze', 'freeze the project skeleton') {freeze; exit}
|
@@ -56,9 +68,13 @@ class Main
|
|
56
68
|
opts.separator ''
|
57
69
|
opts.separator 'common options:'
|
58
70
|
|
59
|
-
opts.on_tail( '-h', '--help', 'show this message' )
|
71
|
+
opts.on_tail( '-h', '--help', 'show this message' ) do
|
72
|
+
STDOUT.puts opts
|
73
|
+
exit
|
74
|
+
end
|
75
|
+
|
60
76
|
opts.on_tail( '--version', 'show version' ) do
|
61
|
-
puts "Mr Bones #{::Bones::VERSION}"
|
77
|
+
STDOUT.puts "Mr Bones #{::Bones::VERSION}"
|
62
78
|
exit
|
63
79
|
end
|
64
80
|
|
@@ -67,7 +83,7 @@ class Main
|
|
67
83
|
self.name = args.empty? ? nil : args.join('_')
|
68
84
|
|
69
85
|
if name.nil?
|
70
|
-
puts opts
|
86
|
+
STDOUT.puts opts
|
71
87
|
::Kernel.abort
|
72
88
|
end
|
73
89
|
|
@@ -154,7 +170,7 @@ class Main
|
|
154
170
|
# Bones skeleton will be copied to the user's data directory.
|
155
171
|
#
|
156
172
|
def freeze
|
157
|
-
self.data =
|
173
|
+
self.data = ::Bones.path('data')
|
158
174
|
data_dir = File.join(mrbones_dir, 'data')
|
159
175
|
archive_dir = File.join(mrbones_dir, 'archive')
|
160
176
|
tasks_only = false
|
@@ -214,6 +230,24 @@ class Main
|
|
214
230
|
FileUtils.rm_f frozen_version_file
|
215
231
|
end
|
216
232
|
|
233
|
+
# Returns a list of the files to copy from the bones/data directory to
|
234
|
+
# the new project directory
|
235
|
+
#
|
236
|
+
def files_to_copy
|
237
|
+
rgxp = %r/\A#{data}\/?/o
|
238
|
+
exclude = %r/tmp$|bak$|~$|CVS|\.svn/o
|
239
|
+
|
240
|
+
ary = Dir.glob(File.join(data, '**', '*')).map do |filename|
|
241
|
+
next if exclude =~ filename
|
242
|
+
next if test(?d, filename)
|
243
|
+
filename.sub rgxp, ''
|
244
|
+
end
|
245
|
+
|
246
|
+
ary.compact!
|
247
|
+
ary.sort!
|
248
|
+
ary
|
249
|
+
end
|
250
|
+
|
217
251
|
|
218
252
|
private
|
219
253
|
|
@@ -227,7 +261,7 @@ class Main
|
|
227
261
|
dst = File.join(dir, File.basename(file, '.erb').sub('NAME', name))
|
228
262
|
src = File.join(data, file)
|
229
263
|
|
230
|
-
puts
|
264
|
+
STDOUT.puts(test(?e, dst) ? "updating #{dst}" : "creating #{dst}") if verbose
|
231
265
|
FileUtils.mkdir_p(dir)
|
232
266
|
|
233
267
|
if '.erb' == File.extname(file)
|
@@ -247,24 +281,6 @@ class Main
|
|
247
281
|
exit 1
|
248
282
|
end
|
249
283
|
|
250
|
-
# Returns a list of the files to copy from the bones/data directory to
|
251
|
-
# the new project directory
|
252
|
-
#
|
253
|
-
def files_to_copy
|
254
|
-
rgxp = %r/\A#{data}\/?/o
|
255
|
-
exclude = %r/tmp$|bak$|~$|CVS|\.svn/o
|
256
|
-
|
257
|
-
ary = Dir.glob(File.join(data, '**', '*')).map do |filename|
|
258
|
-
next if exclude =~ filename
|
259
|
-
next if test(?d, filename)
|
260
|
-
filename.sub rgxp, ''
|
261
|
-
end
|
262
|
-
|
263
|
-
ary.compact!
|
264
|
-
ary.sort!
|
265
|
-
ary
|
266
|
-
end
|
267
|
-
|
268
284
|
# Returns the .bones resource directory in the user's home directory.
|
269
285
|
#
|
270
286
|
def mrbones_dir
|
data/tasks/ann.rake
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id$
|
1
|
+
# $Id: ann.rake 585 2008-04-07 20:15:39Z tim_pease $
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'bones/smtp_tls'
|
@@ -9,12 +9,16 @@ require 'time'
|
|
9
9
|
|
10
10
|
namespace :ann do
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# A prerequisites task that all other tasks depend upon
|
13
|
+
task :prereqs
|
14
|
+
|
15
|
+
file PROJ.ann.file do
|
16
|
+
ann = PROJ.ann
|
17
|
+
puts "Generating #{ann.file}"
|
18
|
+
File.open(ann.file,'w') do |fd|
|
15
19
|
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
16
20
|
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
17
|
-
fd.puts(" #{PROJ.url}") if PROJ.url
|
21
|
+
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
18
22
|
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
19
23
|
fd.puts
|
20
24
|
fd.puts("== DESCRIPTION")
|
@@ -23,23 +27,24 @@ namespace :ann do
|
|
23
27
|
fd.puts
|
24
28
|
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
25
29
|
fd.puts
|
26
|
-
|
30
|
+
ann.paragraphs.each do |p|
|
27
31
|
fd.puts "== #{p.upcase}"
|
28
32
|
fd.puts
|
29
33
|
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
30
34
|
fd.puts
|
31
35
|
end
|
32
|
-
fd.puts
|
36
|
+
fd.puts ann.text if ann.text
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
40
|
desc "Create an announcement file"
|
37
|
-
task :announcement => PROJ.
|
41
|
+
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
38
42
|
|
39
43
|
desc "Send an email announcement"
|
40
|
-
task :email => PROJ.
|
41
|
-
|
42
|
-
|
44
|
+
task :email => ['ann:prereqs', PROJ.ann.file] do
|
45
|
+
ann = PROJ.ann
|
46
|
+
from = ann.email[:from] || PROJ.email
|
47
|
+
to = Array(ann.email[:to])
|
43
48
|
|
44
49
|
### build a mail header for RFC 822
|
45
50
|
rfc822msg = "From: #{from}\n"
|
@@ -49,11 +54,11 @@ namespace :ann do
|
|
49
54
|
rfc822msg << "\n"
|
50
55
|
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
51
56
|
rfc822msg << "Message-Id: "
|
52
|
-
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{
|
53
|
-
rfc822msg << File.read(
|
57
|
+
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
58
|
+
rfc822msg << File.read(ann.file)
|
54
59
|
|
55
60
|
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
56
|
-
|
61
|
+
ann.email[key]
|
57
62
|
end
|
58
63
|
|
59
64
|
params[3] = PROJ.email if params[3].nil?
|
@@ -71,6 +76,6 @@ end # namespace :ann
|
|
71
76
|
desc 'Alias to ann:announcement'
|
72
77
|
task :ann => 'ann:announcement'
|
73
78
|
|
74
|
-
CLOBBER << PROJ.
|
79
|
+
CLOBBER << PROJ.ann.file
|
75
80
|
|
76
81
|
# EOF
|