burke 0.2.2 → 0.3.5

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/lib/burke.rb CHANGED
@@ -1,469 +1,245 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
- require 'hashie'
3
+ require 'burke/holder'
4
4
 
5
- class Smash < Hashie::Mash
6
- def initialize *args
7
- super
8
- @read_filters = {}
9
- @write_filters = {}
10
- end
11
-
12
- def method_missing name, *args
13
- key = convert_key(name)
14
- if key? key or @read_filters.key? key
15
- value = self[key]
16
- yield value if block_given?
17
- value
18
- else
19
- super
20
- end
21
- end
22
-
23
- def [](key)
24
- filter = @read_filters[convert_key(key)]
25
- value = super(key)
26
- filter.nil? ? value : filter[value]
27
- end
5
+ module Burke
6
+ VERSION = File.read(File.join(File.dirname(File.dirname(__FILE__)), 'VERSION'))
28
7
 
29
- def []=(key, value)
30
- filter = @write_filters[convert_key(key)]
31
- value = filter[value] if filter
32
- super(key, value)
33
- end
8
+ class Settings < Holder ; end
34
9
 
35
- def read_filter key, &block
36
- key = convert_key(key)
37
- @read_filters[key] = block
10
+ class TaskDefinition
11
+ ALL = {}
12
+
13
+ attr_reader :name, :block, :prerequisites
14
+
15
+ def initialize *args, &block
16
+ a1, a2 = *args
17
+ name = nil
18
+ prereqs = nil
19
+ if a1.is_a? Hash
20
+ name, prereqs = *a1.entries[0]
21
+ else
22
+ name, prereqs = a1, a2
23
+ end
24
+ @name = String(name)
25
+ @prerequisites = [*prereqs].compact.map {|e| String(e)}
26
+ @block = block
27
+ ALL[@name] = self
28
+ end
29
+
30
+ def execute(s)
31
+ unless @executed
32
+ execute_prerequisites(s)
33
+ @block.call(s)
34
+ @executed = true
35
+ end
36
+ end
37
+
38
+ def execute_prerequisites(s)
39
+ @prerequisites.each do |prereq|
40
+ ALL[prereq].execute(s)
41
+ end
42
+ end
38
43
  end
39
44
 
40
- def write_filter key, &block
41
- @write_filters[convert_key(key)] = block
45
+ def self.define_task *args, &block
46
+ TaskDefinition.new *args, &block
42
47
  end
43
48
  end
44
49
 
50
+ require 'burke/tasks/rspec'
51
+ require 'burke/tasks/test'
52
+ require 'burke/tasks/clean'
53
+ require 'burke/tasks/docs'
54
+ require 'burke/tasks/rdoc'
55
+ require 'burke/tasks/yard'
56
+ require 'burke/tasks/gems'
57
+ require 'burke/tasks/release'
58
+
45
59
  module Burke
46
- VERSION = File.read(File.join(File.dirname(File.dirname(__FILE__)), 'VERSION'))
47
- ALL_TASKS = [:clean, :yard, :rdoc, :rspec, :rspec_rcov, :gems, :install, :test]
48
60
  @tasks = []
61
+ @enabled_tasks = TaskDefinition::ALL.keys
49
62
 
50
- class << self
51
- def enable_all opts={}
52
- @tasks = ALL_TASKS.dup
53
- disable opts[:except] if opts[:except]
54
- end
63
+ class DependencySettings < Holder
64
+ def self.field_exists? name ; true ; end
65
+ end
66
+
67
+ class Settings < Holder
68
+ fields *(Gem::Specification.attribute_names - [:dependencies, :development_dependencies])
69
+ fields *%w[author gems]
55
70
 
56
- def enable *args
57
- @tasks.concat([*args].map {|t| t.to_sym})
58
- @tasks.uniq!
59
- end
71
+ field(:has_rdoc) { Burke.task_enabled? :rdoc }
60
72
 
61
- def disable *args
62
- dis = [*args].map {|t| t.to_sym}
63
- @tasks.reject! {|t| dis.include? t}
73
+ field :rdoc_options do
74
+ opts = []
75
+ opts << "--title" << docs.title
76
+ opts << "--main" << docs.readme_file if docs.readme_file
77
+ opts.freeze
64
78
  end
65
79
 
66
- def setup
67
- @settings = create_settings
68
-
69
- yield @settings
70
-
71
- if @tasks.include? :gems and GemTaskManager::TASKS.empty?
72
- @settings.gems.platform 'ruby'
73
- end
74
-
75
- generate_tasks
76
-
77
- return @settings
80
+ field :extra_rdoc_files do
81
+ docs.extra_files
78
82
  end
79
83
 
80
- def generate_tasks
84
+ field :dependencies do
85
+ dependencies = (self.dependencies = DependencySettings.new)
81
86
  begin
82
- require 'rake/clean'
83
- CLEAN.include(*@settings.clean) if @settings.clean
84
- CLOBBER.include(*@settings.clobber) if @settings.clobber
85
- rescue LoadError
86
- end if @tasks.include? :clean
87
-
88
- unless @settings.docs.files
89
- d = @settings.docs
90
- fl = FileList.new
91
- fl.include "lib/**/*.rb"
92
- fl.include d.readme if d.readme
93
- fl.include d.license if d.license
94
- d.files = fl.to_a
95
- end
96
-
97
- begin
98
- require 'yard'
99
- opts = []
100
- d = @settings.docs
101
- opts << "--title" << "#{@settings.name} #{@settings.version}"
102
- opts << "--readme" << d.readme if d.readme
103
- opts << "--markup" << d.markup if d.markup
104
- extra_files = [d.license].compact
105
- opts << "--files" << extra_files.join(',') unless extra_files.empty?
106
- YARD::Rake::YardocTask.new 'yard' do |t|
107
- t.options = opts
87
+ require 'bundler'
88
+ bundler = Bundler.load
89
+ deps = bundler.dependencies_for(:runtime)
90
+ if deps.empty?
91
+ deps = bundler.dependencies_for(:default)
108
92
  end
109
- rescue LoadError
110
- end if @tasks.include? :yard
111
-
112
- begin
113
- require 'rake/rdoctask'
114
- d = @settings.docs
115
- Rake::RDocTask.new 'rdoc' do |r|
116
- r.rdoc_files.include d.files
117
- r.title = "#{@settings.name} #{@settings.version}"
118
- r.main = d.readme if d.readme
93
+ deps.each do |d|
94
+ dependencies[d.name] = d.requirement.to_s
119
95
  end
120
- rescue LoadError
121
- end if @tasks.include? :rdoc
122
-
123
- if @settings.has_rdoc
124
- d = @settings.docs
125
- (@settings.extra_rdoc_files ||= []).concat d.files
126
- opts = []
127
- opts << "--title" << "#{@settings.name} #{@settings.version}"
128
- opts << "--main" << d.readme if d.readme
129
- @settings.rdoc_options ||= opts
96
+ rescue
130
97
  end
131
-
132
- begin
133
- require 'spec/rake/spectask'
134
- r = @settings.rspec
135
- opts = []
136
- if r.options_file
137
- opts << "--options" << r.options_file
138
- else
139
- opts << "--colour" if r.color
140
- opts << "--format" << r.format if r.format
141
- end
142
- Spec::Rake::SpecTask.new 'spec' do |t|
143
- t.spec_files = r.spec_files
144
- t.spec_opts = opts
145
- t.ruby_opts = r.ruby_opts if r.ruby_opts
146
- end
147
-
148
- begin
149
- require 'rcov'
150
- require 'spec/rake/verify_rcov'
151
-
152
- desc "Run specs with RCov"
153
- Spec::Rake::SpecTask.new('spec:rcov') do |t|
154
- t.spec_files = r.spec_files
155
- t.spec_opts = opts
156
- t.rcov = true
157
- t.rcov_opts = ['--exclude', 'spec']
158
- end
159
-
160
- desc "Run specs with RCov and verify code coverage"
161
- RCov::VerifyTask.new('spec:rcov:verify' => 'spec:rcov') do |t|
162
- t.threshold = r.rcov.threshold
163
- t.index_html = 'coverage/index.html'
164
- end if r.rcov.threshold
165
- rescue LoadError
166
- end if @tasks.include? :rspec_rcov
167
- rescue LoadError
168
- end if @tasks.include? :rspec and !@settings.rspec.spec_files.empty?
169
-
170
- begin
171
- require 'rake/testtask'
172
- Rake::TestTask.new do |t|
173
- t.test_files = @settings.test.test_files
174
- end
175
- rescue LoadError
176
- end if @tasks.include? :test and !@settings.test.test_files.empty?
177
-
178
- begin
179
- settings.gems.individuals.each do |conf|
180
- GemTaskManager.add_task conf
181
- end
182
-
183
- if name
184
- desc "Build gem for this platform"
185
- task(:gem => GemTaskManager.task_for_this_platform.task_name)
186
- end
187
- rescue LoadError
188
- end if @tasks.include? :gems
189
-
190
- begin
191
- require 'rubygems/installer'
192
- GemTaskManager.install_task unless GemTaskManager::TASKS.empty?
193
- rescue LoadError
194
- end if @tasks.include? :install
98
+ dependencies
195
99
  end
196
100
 
197
- def base_gemspec
198
- if @base_gemspec.nil?
199
- @base_gemspec = Gem::Specification.new
200
-
201
- attrs = Gem::Specification.attribute_names
202
- attrs -= [:dependencies, :development_dependencies]
203
- attrs += [:author]
204
-
205
- attrs.each do |attr|
206
- value = @settings.send(attr)
207
- @base_gemspec.send("#{attr}=", value) if value
208
- end
209
-
210
- @settings.dependencies.each do |gem, requirements|
211
- @base_gemspec.add_dependency gem.to_s, *requirements
212
- end
213
-
214
- @settings.development_dependencies.each do |gem, requirements|
215
- @base_gemspec.add_development_dependency gem.to_s, *requirements
101
+ field :development_dependencies do
102
+ dev_deps = (self.development_dependencies = DependencySettings.new)
103
+ begin
104
+ require 'bundler'
105
+ Bundler.load.dependencies_for(:development).each do |d|
106
+ dev_deps[d.name] = d.requirement.to_s
216
107
  end
108
+ rescue
217
109
  end
218
-
219
- @base_gemspec
110
+ dev_deps
220
111
  end
221
112
 
222
- def settings
223
- @settings
224
- end
113
+ field(:rakefile_file) { find_file('rakefile').freeze }
114
+ field(:version_file) { find_file('version{.*,}').freeze }
225
115
 
226
- def create_settings
227
- # TODO: put default values in getter filters
228
- s = Smash.new
229
- s.docs!
230
- s.rspec!.rcov!
231
- s.test!
232
- s.gems = GemSettings.new
233
- s.clean = []
234
- s.clobber = []
235
-
236
- s.read_filter :dependencies do |v|
237
- if v.nil?
238
- s.dependencies = Smash.new
239
- v = s.dependencies
240
- begin
241
- require 'bundler'
242
- bundler = Bundler.load
243
- deps = bundler.dependencies_for(:runtime)
244
- if deps.empty?
245
- deps = bundler.dependencies_for(:default)
246
- end
247
- deps.each do |d|
248
- v[d.name] = d.requirement.to_s
249
- end
250
- rescue
251
- end
252
- end
253
- v
254
- end
255
-
256
- s.read_filter :development_dependencies do |v|
257
- if v.nil?
258
- s.development_dependencies = Smash.new
259
- v = s.development_dependencies
260
- begin
261
- require 'bundler'
262
- Bundler.load.dependencies_for(:development).each do |d|
263
- v[d.name] = d.requirement.to_s
264
- end
265
- rescue
266
- end
267
- end
268
- v
269
- end
270
-
271
- s.read_filter :files do |v|
272
- if v.nil?
273
- v = Dir['{lib,spec,bin}/**/*']
274
- v << s.docs.readme_file
275
- v << s.docs.license_file
276
- v << s.version_file
277
- v << s.rakefile_file
278
- v.compact.freeze
279
- else
280
- v
281
- end
282
- end
283
-
284
- s.read_filter :rakefile_file do |v|
285
- v or find_file('rakefile').freeze
286
- end
287
-
288
- s.read_filter :version_file do |v|
289
- v or find_file('version{.*,}').freeze
290
- end
291
-
292
- s.read_filter :version do |v|
293
- if v.nil? and s.version_file
294
- File.read(s.version_file).strip.freeze
295
- else
296
- v
297
- end
298
- end
299
-
300
- s.docs.read_filter :readme_file do |v|
301
- v or find_file('readme{.*,}').freeze
302
- end
303
- s.docs.read_filter(:readme) { s.docs.readme_file }
304
- s.docs.write_filter(:readme) { |v| s.docs.readme_file = v }
305
-
306
- s.docs.read_filter :license_file do |v|
307
- v or find_file('{licen{c,s}e,copying}{.*,}').freeze
308
- end
309
- s.docs.read_filter(:license) { s.docs.license_file }
310
- s.docs.write_filter(:license) { |v| s.docs.license_file = v }
311
-
312
- s.docs.read_filter :markup do |v|
313
- readme = s.docs.readme
314
- if v.nil? and readme
315
- case File.extname(readme).downcase
316
- when '.rdoc'
317
- 'rdoc'
318
- when '.md', '.markdown'
319
- 'markdown'
320
- when '.textile'
321
- 'textile'
322
- end.freeze
323
- else
324
- v
325
- end
326
- end
327
-
328
- s.test.read_filter :test_files do |v|
329
- v or Dir['test/**/{*_{test,tc},{test,tc}_*}.rb'].freeze
330
- end
331
-
332
- s.rspec.read_filter :options_file do |v|
333
- v or find_file('{{spec/,}{spec.opts,.specopts}}').freeze
334
- end
335
-
336
- s.rspec.read_filter :color do |v|
337
- v.nil? ? true : v
338
- end
339
-
340
- s.rspec.read_filter :spec_files do |v|
341
- v or Dir['spec/**/*_spec.rb'].freeze
342
- end
343
-
344
- s.rspec.write_filter(:ruby_opts) { |v| [*v] }
345
-
346
- return s
347
- end
116
+ field(:version) { File.read(version_file).strip.freeze if version_file }
348
117
 
349
- private
350
- def readable_file? file
351
- File.readable? file and File.file? file
118
+ field :files do
119
+ fs = Dir['{lib,spec,bin}/**/*']
120
+ fs << docs.readme_file
121
+ fs << docs.license_file
122
+ fs << version_file
123
+ fs << rakefile_file
124
+ fs.compact.freeze
352
125
  end
353
126
 
127
+ private
354
128
  def find_file pattern
355
129
  files = Dir.glob(pattern, File::FNM_CASEFOLD)
356
- files.find { |f| readable_file? f }
130
+ files.find { |f| File.readable? f and File.file? f }
357
131
  end
358
132
  end
359
133
 
360
- class GemTaskManager
361
- TASKS = {}
362
-
363
- def self.add_task conf
364
- spec = conf.gemspec
365
- name = "gem:#{spec.platform}"
366
- pkg_dir = Burke.settings.gems.package_dir
367
-
368
- if TASKS.empty?
369
- desc "Build gems for all targets"
370
- end
371
- task :gems => name
372
-
373
- unless ::Rake.application.last_comment
374
- desc "Build gem for target '#{spec.platform}'"
375
- end
376
-
377
- task(name) do
378
- conf.before.call spec unless conf.before.nil?
379
- builder = Gem::Builder.new(spec)
380
- builder.build
381
- verbose true do
382
- mkdir pkg_dir unless File.exists? pkg_dir
383
- mv conf.gem_file, File.join(pkg_dir, conf.gem_file)
384
- end
385
- conf.after.call spec unless conf.after.nil?
386
- end
387
-
388
- TASKS[spec.platform.to_s] = conf
389
- end
390
-
391
- def self.has_task? platform
392
- TASKS.has_key? platform
134
+ class << self
135
+ def enable_all opts={}
136
+ @enabled_tasks = TaskDefinition::ALL.keys
137
+ disable *opts[:except] if opts[:except]
393
138
  end
394
139
 
395
- def self.task_for_this_platform
396
- platform = Gem::Platform.new(RUBY_PLATFORM).to_s
397
- name = nil
398
-
399
- if GemTaskManager.has_task? platform
400
- name = platform
401
- elsif GemTaskManager.has_task? 'ruby'
402
- name = "ruby"
403
- end
404
-
405
- TASKS[name]
140
+ def disable_all opts={}
141
+ @enabled_tasks = []
142
+ enable *opts[:except] if opts[:except]
406
143
  end
407
144
 
408
- def self.install_task
409
- t = task_for_this_platform
410
-
411
- desc "Install gem for this platform"
412
- task 'install' => [t.task_name] do
413
- Gem::Installer.new(File.join(t.package_dir, t.gem_file)).install
414
- end
145
+ def enable *args
146
+ @enabled_tasks.concat([*args].map {|t| String(t)})
147
+ @enabled_tasks.uniq!
415
148
  end
416
- end
417
-
418
- class GemSettings
419
- attr_accessor :package_dir, :individuals
420
149
 
421
- def initialize
422
- @package_dir = 'pkg'
150
+ def disable *args
151
+ dis = [*args].map {|t| String(t)}
152
+ @enabled_tasks.reject! {|t| dis.include? t}
423
153
  end
424
154
 
425
- def platform plaf
426
- conf = IndividualGemSettings.new plaf
427
- @individuals ||= []
428
- @individuals << conf
429
- yield conf if block_given?
430
- conf
155
+ def settings
156
+ @settings ||= Settings.new
431
157
  end
432
158
 
433
- class IndividualGemSettings
434
- attr_reader :platform
159
+ def setup &block
160
+ settings.instance_exec settings, &block
435
161
 
436
- def initialize plaf
437
- @platform = Gem::Platform.new plaf
162
+ if task_enabled? :gems and GemTaskManager::TASKS.empty?
163
+ settings.gems.add_platform 'ruby'
438
164
  end
439
165
 
440
- def gemspec
441
- spec = Burke.base_gemspec.dup
442
- spec.platform = @platform
443
- spec
444
- end
445
-
446
- def gem_file
447
- "#{gemspec.full_name}.gem"
448
- end
166
+ enabled = []
167
+ disabled = []
449
168
 
450
- def task_name
451
- "gem:#{platform}"
169
+ # Generate tasks
170
+ TaskDefinition::ALL.each do |name, td|
171
+ if task_enabled? name
172
+ begin
173
+ td.prerequisites.each do |prereq|
174
+ raise "prerequisite '#{prereq}' is disabled" unless task_enabled? prereq
175
+ end
176
+ td.execute(settings)
177
+ enabled << [name, nil]
178
+ rescue Exception => ex
179
+ disabled << [name, ex.message]
180
+ end
181
+ else
182
+ disabled << [name, "disabled by project developer(s)"]
183
+ end
452
184
  end
453
185
 
454
- def package_dir
455
- Burke.settings.gems.package_dir
186
+ desc 'List Burke task groups'
187
+ task 'burke:tasks' do
188
+ unless enabled.empty?
189
+ puts ' ---------'
190
+ puts ' Enabled '
191
+ puts ' ---------'
192
+ width = enabled.map {|a| a[0].length}.sort.last
193
+ enabled.sort_by {|a| a[0]}.each do |name, reason|
194
+ line = "+ #{name.ljust(width)}"
195
+ line << " (#{reason})" if reason
196
+ puts line
197
+ end
198
+ puts
199
+ end
200
+ unless disabled.empty?
201
+ puts ' ----------'
202
+ puts ' Disabled '
203
+ puts ' ----------'
204
+ width = disabled.map {|a| a[0].length}.sort.last
205
+ disabled.sort_by {|a| a[0]}.each do |name, reason|
206
+ line = "- #{name.ljust(width)}"
207
+ line << " (#{reason})" if reason
208
+ puts line
209
+ end
210
+ end
456
211
  end
457
212
 
458
- def before &block
459
- @before = block if block_given?
460
- @before
213
+ return settings
214
+ end
215
+
216
+ def task_enabled? name
217
+ @enabled_tasks.include? String(name)
218
+ end
219
+
220
+ def base_gemspec
221
+ if @base_gemspec.nil?
222
+ @base_gemspec = Gem::Specification.new
223
+
224
+ attrs = Gem::Specification.attribute_names
225
+ attrs -= [:dependencies, :development_dependencies]
226
+ attrs += [:author]
227
+
228
+ attrs.each do |attr|
229
+ value = settings.send(attr)
230
+ @base_gemspec.send("#{attr}=", value) if value
231
+ end
232
+
233
+ settings.dependencies.each do |gem, requirements|
234
+ @base_gemspec.add_dependency gem.to_s, *requirements
235
+ end
236
+
237
+ settings.development_dependencies.each do |gem, requirements|
238
+ @base_gemspec.add_development_dependency gem.to_s, *requirements
239
+ end
461
240
  end
462
241
 
463
- def after &block
464
- @after = block if block_given?
465
- @after
466
- end
242
+ @base_gemspec
467
243
  end
468
244
  end
469
245
  end
@@ -1,23 +1,26 @@
1
+ ($LOAD_PATH << File.dirname(File.expand_path(__FILE__))).uniq!
2
+ require 'spec_helper'
3
+
1
4
  DIR = File.dirname(File.expand_path(__FILE__))
2
- require File.join(DIR, 'spec_helper')
3
5
 
4
6
  describe Burke do
5
7
  describe 'settings' do
6
- context 'for example of a conventional project' do
8
+ context 'for example of a simple project' do
7
9
  before do
8
10
  @old_pwd = Dir.pwd
9
- Dir.chdir File.join(DIR, 'conventional_project')
11
+ Dir.chdir File.join(DIR, 'simple_project')
10
12
  mock_burke_setup
11
- eval(File.read('Rakefile'))
12
- @settings = Burke.test_settings
13
+ load 'Rakefile'
14
+ @settings = Burke.settings
13
15
  end
14
16
 
15
17
  subject { @settings }
16
18
 
17
- its(:name) { should eql 'conventional_project' }
19
+ its(:name) { should eql 'simple_project' }
18
20
 
19
21
  its(:version_file) { should eql 'VERSION' }
20
22
  its(:rakefile_file) { should eql 'Rakefile' }
23
+ its(:version) { should eql '1.2.3' }
21
24
 
22
25
  describe 'docs' do
23
26
  subject { @settings.docs }