bones 1.3.5 → 2.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.
@@ -1,32 +1,36 @@
1
1
  # $Id$
2
2
 
3
+ if HAVE_SVN
3
4
 
4
- if PROJ.svn and system("svn --version 2>&1 > #{DEV_NULL}")
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.svn_root = (m.nil? ? '' : m[1])
8
+ PROJ.svn.root = (m.nil? ? '' : m[1])
10
9
  end
11
- PROJ.svn_root = File.join(PROJ.svn_root, PROJ.svn) if String === PROJ.svn
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.svn_root, PROJ.svn_tags)}/
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
- trunk = File.join(PROJ.svn_root, PROJ.svn_trunk)
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(PROJ.svn_root, PROJ.svn_tags, tag)
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
@@ -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.test_file) then [PROJ.test_file]
10
- else PROJ.tests end
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.test_opts
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.rcov_opts.dup << '-o' << PROJ.rcov_dir
18
+ opts = PROJ.rcov.opts.dup << '-o' << PROJ.rcov.dir
19
19
  opts = opts.join(' ')
20
- files = if test(?f, PROJ.test_file) then [PROJ.test_file]
21
- else PROJ.tests end
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
@@ -1,14 +1,22 @@
1
- # $Id: bones.rb 558 2008-02-27 19:46:32Z tim_pease $
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 = '1.3.5'
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 431 2007-12-31 21:24:37Z tim_pease $
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.files.each do |fn|
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 line =~ pattern
70
- list << Annotation.new(lineno, $1, $2)
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
@@ -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
@@ -1,4 +1,4 @@
1
- # $Id: main.rb 561 2008-02-27 23:28:19Z tim_pease $
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 = File.join(::Bones::PATH, 'data') unless test(?d, 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' ) {puts opts; exit}
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 = File.join(::Bones::PATH, '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 (test(?e, dst) ? "updating #{dst}" : "creating #{dst}") if verbose
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
@@ -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
- file PROJ.ann_file do
13
- puts "Generating #{PROJ.ann_file}"
14
- File.open(PROJ.ann_file,'w') do |fd|
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
- PROJ.ann_paragraphs.each do |p|
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 PROJ.ann_text if PROJ.ann_text
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.ann_file
41
+ task :announcement => ['ann:prereqs', PROJ.ann.file]
38
42
 
39
43
  desc "Send an email announcement"
40
- task :email => PROJ.ann_file do
41
- from = PROJ.ann_email[:from] || PROJ.email
42
- to = Array(PROJ.ann_email[:to])
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}@#{PROJ.ann_email[:domain]}>\n\n"
53
- rfc822msg << File.read(PROJ.ann_file)
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
- PROJ.ann_email[key]
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.ann_file
79
+ CLOBBER << PROJ.ann.file
75
80
 
76
81
  # EOF