bones 2.5.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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