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.
Files changed (75) hide show
  1. data/History.txt +2 -0
  2. data/README.rdoc +54 -306
  3. data/Rakefile +28 -37
  4. data/bin/bones +10 -3
  5. data/{spec/data/data → default}/.bnsignore +3 -1
  6. data/{data → default}/History.txt.bns +0 -0
  7. data/{data → default}/README.txt.bns +0 -0
  8. data/default/Rakefile.bns +21 -0
  9. data/{data → default}/bin/NAME.bns +0 -0
  10. data/{data → default}/lib/NAME.rb.bns +0 -0
  11. data/{data → default}/spec/NAME_spec.rb.bns +0 -0
  12. data/{data → default}/spec/spec_helper.rb.bns +0 -0
  13. data/{data → default}/test/test_NAME.rb +0 -0
  14. data/lib/bones.rb +73 -31
  15. data/lib/bones/annotation_extractor.rb +16 -26
  16. data/lib/bones/app.rb +87 -58
  17. data/lib/bones/app/command.rb +143 -64
  18. data/lib/bones/app/create.rb +93 -0
  19. data/lib/bones/app/file_manager.rb +7 -8
  20. data/lib/bones/app/freeze.rb +59 -0
  21. data/lib/bones/app/info.rb +39 -0
  22. data/lib/bones/app/unfreeze.rb +44 -0
  23. data/lib/bones/colors.rb +54 -0
  24. data/lib/bones/gem_package_task.rb +71 -0
  25. data/lib/bones/helpers.rb +93 -0
  26. data/lib/bones/plugins/ann.rb +166 -0
  27. data/lib/bones/plugins/bones_plugin.rb +193 -0
  28. data/lib/bones/plugins/gem.rb +274 -0
  29. data/lib/bones/plugins/notes.rb +45 -0
  30. data/lib/bones/plugins/rdoc.rb +93 -0
  31. data/lib/bones/plugins/test.rb +57 -0
  32. data/lib/bones/smtp_tls.rb +1 -0
  33. data/spec/bones/app/file_manager_spec.rb +6 -6
  34. data/spec/bones/app_spec.rb +14 -18
  35. data/spec/bones_spec.rb +9 -4
  36. data/{data → spec/data/default}/.bnsignore +0 -0
  37. data/spec/data/{data → default}/History +0 -0
  38. data/spec/data/{data → default}/NAME/NAME.rb.bns +0 -0
  39. data/spec/data/{data → default}/README.txt.bns +0 -0
  40. data/{data → spec/data/default}/Rakefile.bns +0 -0
  41. data/spec/data/{data → default}/lib/NAME.rb.bns +0 -0
  42. metadata +94 -68
  43. data/lib/bones/app/create_command.rb +0 -86
  44. data/lib/bones/app/freeze_command.rb +0 -73
  45. data/lib/bones/app/info_command.rb +0 -58
  46. data/lib/bones/app/unfreeze_command.rb +0 -53
  47. data/lib/bones/app/update_command.rb +0 -47
  48. data/lib/bones/debug.rb +0 -72
  49. data/lib/bones/tasks/ann.rake +0 -80
  50. data/lib/bones/tasks/bones.rake +0 -20
  51. data/lib/bones/tasks/gem.rake +0 -201
  52. data/lib/bones/tasks/git.rake +0 -40
  53. data/lib/bones/tasks/notes.rake +0 -27
  54. data/lib/bones/tasks/post_load.rake +0 -34
  55. data/lib/bones/tasks/rdoc.rake +0 -51
  56. data/lib/bones/tasks/rubyforge.rake +0 -55
  57. data/lib/bones/tasks/setup.rb +0 -292
  58. data/lib/bones/tasks/spec.rake +0 -54
  59. data/lib/bones/tasks/svn.rake +0 -47
  60. data/lib/bones/tasks/test.rake +0 -40
  61. data/lib/bones/tasks/zentest.rake +0 -36
  62. data/spec/data/data/Rakefile.bns +0 -30
  63. data/tasks/ann.rake +0 -80
  64. data/tasks/bones.rake +0 -20
  65. data/tasks/gem.rake +0 -201
  66. data/tasks/git.rake +0 -40
  67. data/tasks/notes.rake +0 -27
  68. data/tasks/post_load.rake +0 -34
  69. data/tasks/rdoc.rake +0 -51
  70. data/tasks/rubyforge.rake +0 -55
  71. data/tasks/setup.rb +0 -292
  72. data/tasks/spec.rake +0 -54
  73. data/tasks/svn.rake +0 -47
  74. data/tasks/test.rake +0 -40
  75. data/tasks/zentest.rake +0 -36
@@ -1,22 +1,25 @@
1
1
 
2
- module Bones
3
- class App
2
+ class Bones::App::Command
4
3
 
5
- class Command
4
+ # :stopdoc:
5
+ DEFAULT_SKELETON = 'default'
6
+ # :startdoc:
6
7
 
7
- attr_reader :options
8
+ attr_reader :stdout
9
+ attr_reader :stderr
10
+ attr_reader :config
8
11
 
9
- def initialize( out = STDOUT, err = STDERR )
10
- @out = out
11
- @err = err
12
- @options = {
13
- :skeleton_dir => File.join(mrbones_dir, 'data'),
14
- :with_tasks => false,
12
+ def initialize( opts = {} )
13
+ @stdout = opts[:stdout] || $stdout
14
+ @stderr = opts[:stderr] || $stderr
15
+
16
+ @config = {
17
+ :skeleton_dir => File.join(mrbones_dir, DEFAULT_SKELETON),
15
18
  :verbose => false,
16
19
  :name => nil,
17
20
  :output_dir => nil
18
21
  }
19
- @options[:skeleton_dir] = ::Bones.path('data') unless test(?d, skeleton_dir)
22
+ @config[:skeleton_dir] = ::Bones.path(DEFAULT_SKELETON) unless test(?d, skeleton_dir)
20
23
  end
21
24
 
22
25
  def run( args )
@@ -26,57 +29,36 @@ class Command
26
29
  # The output directory where files will be written.
27
30
  #
28
31
  def output_dir
29
- options[:output_dir]
32
+ @config[:output_dir]
30
33
  end
31
34
 
32
35
  # The directory where the project skeleton is located.
33
36
  #
34
37
  def skeleton_dir
35
- options[:skeleton_dir]
38
+ @config[:skeleton_dir]
36
39
  end
37
40
 
38
41
  # The project name from the command line.
39
42
  #
40
43
  def name
41
- options[:name]
44
+ @config[:name]
42
45
  end
43
46
 
44
47
  # A git or svn repository URL from the command line.
45
48
  #
46
49
  def repository
47
- return options[:repository] if options.has_key? :repository
50
+ return @config[:repository] if @config.has_key? :repository
48
51
  return IO.read(skeleton_dir).strip if skeleton_dir and test(?f, skeleton_dir)
49
52
  nil
50
53
  end
51
54
 
52
- # Returns +true+ if we are going to copy the Mr Bones tasks into the
53
- # destination directory. Normally this will return +false+.
54
- #
55
- def with_tasks?
56
- options[:with_tasks]
57
- end
58
-
59
- #
60
- #
61
- def copy_tasks( to )
62
- fm = FileManager.new(
63
- :source => ::Bones.path(%w[lib bones tasks]),
64
- :destination => to,
65
- :stdout => @out,
66
- :stderr => @err,
67
- :verbose => verbose?
68
- )
69
- fm.archive_destination
70
- fm.copy
71
- end
72
-
73
55
  # Returns +true+ if the user has requested verbose messages.
74
56
  #
75
57
  def verbose?
76
- options[:verbose]
58
+ @config[:verbose]
77
59
  end
78
60
 
79
- # Returns the .bones resource directory in the user's home directory.
61
+ # Returns the '.mrbones' resource directory in the user's home directory.
80
62
  #
81
63
  def mrbones_dir
82
64
  return @mrbones_dir if defined? @mrbones_dir
@@ -85,45 +67,142 @@ class Command
85
67
  @mrbones_dir = File.expand_path(path)
86
68
  end
87
69
 
70
+ # Run a block of code in the given directory.
71
+ #
72
+ def in_directory( dir )
73
+ pwd = File.expand_path(FileUtils.pwd)
74
+ FileUtils.cd dir
75
+ yield
76
+ ensure
77
+ FileUtils.cd pwd
78
+ end
79
+
88
80
  #
89
81
  #
90
82
  def standard_options
91
- {
92
- :verbose => ['-v', '--verbose', 'enable verbose output',
93
- lambda {
94
- options[:verbose] = true
95
- }],
83
+ Command.standard_options
84
+ end
85
+
86
+ #
87
+ #
88
+ def parse( args )
89
+ opts = OptionParser.new
90
+
91
+ opts.banner = 'NAME'
92
+ opts.separator " bones v#{::Bones::VERSION}"
93
+ opts.separator ''
94
+
95
+ if self.class.synopsis
96
+ opts.separator 'SYNOPSIS'
97
+ self.class.synopsis.split("\n").each { |line| opts.separator " #{line.strip}" }
98
+ opts.separator ''
99
+ end
100
+
101
+ if self.class.description
102
+ opts.separator 'DESCRIPTION'
103
+ self.class.description.split("\n").each { |line| opts.separator " #{line.strip}" }
104
+ opts.separator ''
105
+ end
106
+
107
+ if self.class.options and not self.class.options.empty?
108
+ opts.separator 'PARAMETERS'
109
+ self.class.options.each { |option|
110
+ case option
111
+ when Array
112
+ option << method(option.pop) if option.last =~ %r/^__/
113
+ opts.on(*option)
114
+ when String
115
+ opts.separator(" #{option.strip}")
116
+ else opts.separator('') end
117
+ }
118
+ opts.separator ''
119
+ end
120
+
121
+ opts.separator ' Common Options:'
122
+ opts.on_tail( '-h', '--help', 'show this message' ) {
123
+ stdout.puts opts
124
+ exit
125
+ }
126
+ opts.on_tail ''
127
+
128
+ opts.parse! args
129
+ return opts
130
+ end
131
+
132
+ #
133
+ #
134
+ def self.standard_options
135
+ @standard_options ||= {
136
+ :verbose => ['-v', '--verbose', 'Enable verbose output.',
137
+ lambda { config[:verbose] = true }],
138
+
96
139
  :directory => ['-d', '--directory DIRECTORY', String,
97
- 'project directory to create', '(defaults to project_name)',
98
- lambda { |value|
99
- options[:output_dir] = value
100
- }],
140
+ 'Project directory to create.', '(defaults to project_name)',
141
+ lambda { |value| config[:output_dir] = value }],
142
+
101
143
  :skeleton => ['-s', '--skeleton NAME', String,
102
- 'project skeleton to use',
144
+ 'Project skeleton to use.',
103
145
  lambda { |value|
104
146
  path = File.join(mrbones_dir, value)
105
- if test(?e, path)
106
- options[:skeleton_dir] = path
107
- elsif test(?e, value)
108
- options[:skeleton_dir] = value
147
+ if test(?e, value)
148
+ config[:skeleton_dir] = value
149
+ elsif test(?e, path)
150
+ config[:skeleton_dir] = path
109
151
  else
110
- raise ArgumentError, "Unknown skeleton '#{value}'"
152
+ raise ArgumentError, "Unknown skeleton '#{value}'."
111
153
  end
112
154
  }],
113
- :with_tasks => ['--with-tasks', 'copy rake tasks to the project folder',
114
- lambda {
115
- options[:with_tasks] = true
116
- }],
155
+
117
156
  :repository => ['-r', '--repository URL', String,
118
- 'svn or git repository path',
119
- lambda { |value|
120
- options[:repository] = value
121
- }]
157
+ 'svn or git repository path.',
158
+ lambda { |value| config[:repository] = value }]
122
159
  }
123
160
  end
124
161
 
125
- end # class Command
126
- end # class App
127
- end # module Bones
162
+ module ClassMethods
163
+ def synopsis( *args )
164
+ @synopsis = args.join("\n") unless args.empty?
165
+ @synopsis
166
+ end
167
+
168
+ def description( *args )
169
+ @description = args.join("\n") unless args.empty?
170
+ @description
171
+ end
172
+
173
+ def summary( *args )
174
+ @summary = args.join("\n") unless args.empty?
175
+ @summary
176
+ end
177
+
178
+ def option( *args, &block )
179
+ args.flatten!
180
+ block = args.pop if block.nil? and Proc === args.last
181
+
182
+ if block
183
+ args.each { |val|
184
+ next unless val.instance_of? String
185
+ next unless val =~ %r/^--(\w+)/
186
+
187
+ args << "__#$1"
188
+ define_method(args.last.to_sym, &block)
189
+ options << args
190
+ break
191
+ }
192
+ else
193
+ options << (args.length > 1 ? args : args.first )
194
+ end
195
+ end
196
+
197
+ def options
198
+ @options ||= []
199
+ end
200
+ end
201
+
202
+ def self.inherited( other )
203
+ other.extend ClassMethods
204
+ end
205
+
206
+ end # class Bones::App::Command
128
207
 
129
208
  # EOF
@@ -0,0 +1,93 @@
1
+
2
+ module Bones::App
3
+ class Create < Command
4
+
5
+ def self.initialize_create
6
+ synopsis 'bones create [options] <project_name>'
7
+
8
+ summary 'create a new project from a skeleton'
9
+
10
+ description <<-__
11
+ Create a new project from a Mr Bones project skeleton. The skeleton can
12
+ be the default project skeleton from the Mr Bones gem or one of the named
13
+ skeletons found in the '~/.mrbones/' folder. A git or svn repository can
14
+ be used as the skeleton if the '--repository' flag is given.
15
+ __
16
+
17
+ option(standard_options[:directory])
18
+ option(standard_options[:skeleton])
19
+ option(standard_options[:repository])
20
+ option(standard_options[:verbose])
21
+ end
22
+
23
+ def self.in_output_directory( *args )
24
+ @in_output_directory ||= []
25
+ @in_output_directory.concat(args.map {|str| str.to_sym})
26
+ @in_output_directory
27
+ end
28
+
29
+ def run
30
+ raise Error, "Output directory #{output_dir.inspect} already exists." if test ?e, output_dir
31
+
32
+ copy_files
33
+ announce
34
+
35
+ in_directory(output_dir) {
36
+ self.class.in_output_directory.each {|cmd| self.send cmd}
37
+ fixme
38
+ }
39
+ end
40
+
41
+ def parse( args )
42
+ opts = super args
43
+
44
+ config[:name] = args.empty? ? nil : args.join('_')
45
+ config[:output_dir] = name if output_dir.nil?
46
+
47
+ if name.nil?
48
+ stdout.puts opts
49
+ exit 1
50
+ end
51
+ end
52
+
53
+ def copy_files
54
+ fm = FileManager.new(
55
+ :source => repository || skeleton_dir,
56
+ :destination => output_dir,
57
+ :stdout => stdout,
58
+ :stderr => stderr,
59
+ :verbose => verbose?
60
+ )
61
+
62
+ fm.copy
63
+ fm.finalize name
64
+ rescue Bones::App::FileManager::Error => err
65
+ FileUtils.rm_rf output_dir
66
+ msg = "Could not create '#{name}'"
67
+ msg << " in directory '#{output_dir}'" if name != output_dir
68
+ msg << "\n\t#{err.message}"
69
+ raise Error, msg
70
+ rescue Exception => err
71
+ FileUtils.rm_rf output_dir
72
+ msg = "Could not create '#{name}'"
73
+ msg << " in directory '#{output_dir}'" if name != output_dir
74
+ msg << "\n\t#{err.inspect}"
75
+ raise Error, msg
76
+ end
77
+
78
+ def announce
79
+ msg = "Created '#{name}'"
80
+ msg << " in directory '#{output_dir}'" if name != output_dir
81
+ stdout.puts msg
82
+ end
83
+
84
+ def fixme
85
+ return unless test ?f, 'Rakefile'
86
+ stdout.puts 'Now you need to fix these files'
87
+ system "#{::Bones::RUBY} -S rake notes"
88
+ end
89
+
90
+ end # class Create
91
+ end # module Bones::App
92
+
93
+ # EOF
@@ -1,11 +1,11 @@
1
1
 
2
- require 'fileutils'
3
-
4
- module Bones
5
- class App
2
+ require 'erb'
6
3
 
4
+ module Bones::App
7
5
  class FileManager
8
6
 
7
+ Error = Class.new(StandardError)
8
+
9
9
  attr_accessor :source, :destination, :archive, :verbose
10
10
  alias :verbose? :verbose
11
11
 
@@ -78,12 +78,12 @@ class FileManager
78
78
  def _checkout( repotype )
79
79
  case repotype
80
80
  when :git
81
- system('git-clone', source, destination)
81
+ Git.clone source, destination
82
82
  FileUtils.rm_rf(File.join(destination, '.git'))
83
83
  when :svn
84
84
  system('svn', 'export', source, destination)
85
85
  else
86
- raise "unknown repository type '#{repotype}'"
86
+ raise Error, "Unknown repository type '#{repotype}'."
87
87
  end
88
88
  end
89
89
 
@@ -169,7 +169,6 @@ class FileManager
169
169
  end
170
170
 
171
171
  end # class FileManager
172
- end # class App
173
- end # module Bones
172
+ end # module Bones::App
174
173
 
175
174
  # EOF
@@ -0,0 +1,59 @@
1
+
2
+ module Bones::App
3
+ class Freeze < Command
4
+
5
+ def self.initialize_freeze
6
+ synopsis 'bones freeze [options] [skeleton_name]'
7
+
8
+ summary 'create a new skeleton in ~/.mrbones/'
9
+
10
+ description <<-__
11
+ Freeze the project skeleton to the current Mr Bones project skeleton.
12
+ If a name is not given, then the default name "default" will be used.
13
+ Optionally a git or svn repository can be frozen as the project
14
+ skeleton.
15
+ __
16
+
17
+ option(standard_options[:repository])
18
+ option(standard_options[:verbose])
19
+ end
20
+
21
+ def run
22
+ fm = FileManager.new(
23
+ :source => repository || ::Bones.path(DEFAULT_SKELETON),
24
+ :destination => output_dir,
25
+ :stdout => stdout,
26
+ :stderr => stderr,
27
+ :verbose => verbose?
28
+ )
29
+
30
+ fm.archive_destination
31
+ return freeze_to_repository if repository
32
+
33
+ fm.copy
34
+
35
+ stdout.puts "Project skeleton #{name.inspect} " <<
36
+ "has been frozen to Mr Bones #{::Bones::VERSION}"
37
+ end
38
+
39
+ def parse( args )
40
+ opts = super args
41
+ config[:name] = args.empty? ? DEFAULT_SKELETON : args.join('_')
42
+ config[:output_dir] = File.join(mrbones_dir, name)
43
+ end
44
+
45
+ # Freeze the project skeleton to the git or svn repository that the user
46
+ # passed in on the command line. This essentially creates an alias to the
47
+ # reposiory using the name passed in on the command line.
48
+ #
49
+ def freeze_to_repository
50
+ FileUtils.mkdir_p(File.dirname(output_dir))
51
+ File.open(output_dir, 'w') {|fd| fd.puts repository}
52
+ stdout.puts "Project skeleton #{name.inspect} " <<
53
+ "has been frozen to #{repository.inspect}"
54
+ end
55
+
56
+ end # class Freeze
57
+ end # module Bones::App
58
+
59
+ # EOF