shoe 0.5.1 → 0.6.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 (53) hide show
  1. data/{doc/bundler.rdoc → BUNDLER.rdoc} +0 -0
  2. data/CHANGELOG.rdoc +15 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +21 -3
  5. data/README.rdoc +22 -2
  6. data/TODO.rdoc +3 -3
  7. data/bin/shoe +16 -2
  8. data/data/shoe/templates/application.erb +23 -0
  9. data/data/shoe/templates/executable.erb +18 -0
  10. data/data/shoe/templates/extconf.erb +2 -0
  11. data/data/shoe/templates/extension.erb +9 -0
  12. data/data/shoe/templates/gemspec.erb +50 -0
  13. data/data/shoe/templates/gitignore.erb +4 -0
  14. data/data/shoe/templates/gitkeep.erb +0 -0
  15. data/data/shoe/templates/manpage.erb +30 -0
  16. data/data/shoe/templates/module.erb +31 -0
  17. data/data/shoe/templates/module_test.rb +7 -0
  18. data/data/shoe/templates/rakefile.erb +3 -0
  19. data/data/shoe/templates/readme.erb +3 -0
  20. data/data/shoe/templates/test_helper.erb +2 -0
  21. data/features/cucumber.feature +7 -8
  22. data/features/generator.feature +32 -0
  23. data/features/release.feature +8 -8
  24. data/features/step_definitions/shoe_steps.rb +0 -9
  25. data/features/support/env.rb +5 -9
  26. data/features/test.feature +4 -4
  27. data/lib/shoe.rb +20 -2
  28. data/lib/shoe/extensions.rb +10 -0
  29. data/lib/shoe/extensions/doc_manager.rb +11 -0
  30. data/lib/shoe/extensions/option_parser.rb +25 -0
  31. data/lib/shoe/extensions/pathname.rb +16 -0
  32. data/lib/shoe/extensions/source_index.rb +17 -0
  33. data/lib/shoe/extensions/specification.rb +19 -0
  34. data/lib/shoe/extensions/validator.rb +15 -0
  35. data/lib/shoe/generator.rb +122 -40
  36. data/lib/shoe/tasks.rb +2 -0
  37. data/lib/shoe/tasks/abstract.rb +3 -69
  38. data/lib/shoe/tasks/compile.rb +3 -1
  39. data/lib/shoe/tasks/cucumber.rb +13 -10
  40. data/lib/shoe/tasks/rdoc.rb +3 -22
  41. data/lib/shoe/tasks/release.rb +7 -12
  42. data/lib/shoe/tasks/ronn.rb +77 -0
  43. data/lib/shoe/tasks/test.rb +2 -26
  44. data/man/shoe.1 +64 -0
  45. data/man/shoe.1.ronn +63 -0
  46. data/shoe.gemspec +4 -1
  47. metadata +59 -15
  48. data/features/getting_started.feature +0 -29
  49. data/lib/shoe/templates/gemspec.erb +0 -41
  50. data/lib/shoe/templates/rakefile.erb +0 -3
  51. data/lib/shoe/templates/readme.erb +0 -3
  52. data/lib/shoe/templates/version.erb +0 -3
  53. data/lib/shoe/version.rb +0 -3
@@ -1,12 +1,3 @@
1
- Given /^I have created a project called "([^\"]*)"$/ do |name|
2
- create_directory(name)
3
- create_file("#{name}/Gemfile", <<-END.gsub(/^\s*/, ''))
4
- source :rubygems
5
- gem 'shoe', :group => :development
6
- END
7
- run('bundle exec shoe .', name)
8
- end
9
-
10
1
  Given /^I have created a directory called "([^\"]*)"$/ do |name|
11
2
  create_directory(name)
12
3
  end
@@ -19,7 +19,7 @@ class WorkingDirectory
19
19
  end
20
20
 
21
21
  def create_file(path, contents)
22
- file(path).open('w') { |file| file.write(be_sneaky_with_the_gemfile(contents)) }
22
+ file(path).open('w') { |file| file.write(contents) }
23
23
  end
24
24
 
25
25
  def append_file(path, contents)
@@ -47,19 +47,15 @@ class WorkingDirectory
47
47
 
48
48
  private
49
49
 
50
- def be_sneaky_with_the_gemfile(contents)
51
- contents.sub("gem 'shoe'", "gem 'shoe', :path => '#{PROJECT_ROOT.expand_path}'")
52
- end
53
-
54
50
  def isolate_environment(command)
55
- # set the PATH so bundle exec can find shoe
51
+ # set the PATH so tests can just run shoe
56
52
  ENV['PATH'] = ENV['PATH'].split(File::PATH_SEPARATOR).
57
53
  unshift(PROJECT_ROOT.join('bin')).uniq.
58
54
  join(File::PATH_SEPARATOR)
55
+ ENV['RUBYLIB'] = PROJECT_ROOT.join('lib')
59
56
 
60
- # whack most environment variables so nested bundle exec won't get confused
61
- # about where the Gemfile is
62
- "/usr/bin/env -i #{preserve_environment 'HOME', 'PATH', 'GEM_HOME', 'GEM_PATH'} #{command}"
57
+ # whack most environment variables for good hygiene
58
+ "/usr/bin/env -i #{preserve_environment 'HOME', 'PATH', 'GEM_HOME', 'GEM_PATH', 'RUBYLIB'} #{command}"
63
59
  end
64
60
 
65
61
  def preserve_environment(*variables)
@@ -4,15 +4,15 @@ Feature: Test
4
4
  I want shoe to give me a rake task
5
5
 
6
6
  Scenario: Running rake --tasks in a shoe project without tests
7
- Given I have created a project called "my_project"
7
+ Given I have run shoe --no-test-unit my_project inside "."
8
8
  And I have run git init inside "my_project"
9
- When I run bundle exec rake --tasks inside "my_project"
9
+ When I run rake --tasks inside "my_project"
10
10
  Then I should not see "rake test" on standard out
11
11
 
12
12
  Scenario: Running rake --tasks in a shoe project with tests
13
- Given I have created a project called "my_project"
13
+ Given I have run shoe --no-test-unit my_project inside "."
14
14
  And I have run git init inside "my_project"
15
15
  And I have created a directory called "my_project/test"
16
16
  And I have created a file called "my_project/test/foo_test.rb" containing ""
17
- When I run bundle exec rake --tasks inside "my_project"
17
+ When I run rake --tasks inside "my_project"
18
18
  Then I should see "rake test" on standard out
@@ -1,4 +1,22 @@
1
+ require 'pathname'
2
+ require 'rbconfig'
3
+ require 'rbconfig/datadir'
4
+
1
5
  module Shoe
2
- autoload :Generator, 'shoe/generator'
3
- autoload :Tasks, 'shoe/tasks'
6
+ VERSION = '0.6.0'
7
+
8
+ autoload :Extensions, 'shoe/extensions'
9
+ autoload :Generator, 'shoe/generator'
10
+ autoload :Tasks, 'shoe/tasks'
11
+
12
+ def self.datadir
13
+ @@datadir ||= begin
14
+ datadir = RbConfig.datadir('shoe')
15
+ if !File.exist?(datadir)
16
+ warn "#{datadir} does not exist. Trying again with relative data directory."
17
+ datadir = File.expand_path('../../data/shoe', __FILE__)
18
+ end
19
+ Pathname.new(datadir)
20
+ end
21
+ end
4
22
  end
@@ -0,0 +1,10 @@
1
+ module Shoe
2
+ module Extensions
3
+ autoload :DocManager, 'shoe/extensions/doc_manager'
4
+ autoload :OptionParser, 'shoe/extensions/option_parser'
5
+ autoload :Pathname, 'shoe/extensions/pathname'
6
+ autoload :SourceIndex, 'shoe/extensions/source_index'
7
+ autoload :Specification, 'shoe/extensions/specification'
8
+ autoload :Validator, 'shoe/extensions/validator'
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module DocManager
5
+ def self.extended(manager)
6
+ manager.instance_variable_set(:@doc_dir, Dir.pwd)
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module OptionParser
5
+ attr_accessor :defaults
6
+
7
+ def order(*args, &block)
8
+ begin
9
+ super(defaults.dup.concat(*args), &block)
10
+ rescue ::OptionParser::ParseError
11
+ abort($!)
12
+ end
13
+ end
14
+
15
+ def summarize(*args, &block)
16
+ return <<-END.gsub(/^ {10}/, '')
17
+ #{super}
18
+ Defaults:
19
+ #{summary_indent}#{defaults.join(' ')}
20
+ END
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module Pathname
5
+ def install(contents, mode)
6
+ if exist?
7
+ warn "#{to_s} exists. Not clobbering."
8
+ else
9
+ open('w') { |file| file.write(contents) }
10
+ chmod(mode)
11
+ end
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module SourceIndex
5
+ attr_accessor :local_gemspec
6
+
7
+ def find_name(*args)
8
+ if args.first == local_gemspec.name
9
+ [local_gemspec]
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module Specification
5
+ def self.extended(specification)
6
+ specification.loaded_from = Dir.pwd
7
+ end
8
+
9
+ def full_gem_path
10
+ Dir.pwd
11
+ end
12
+
13
+ def has_version_greater_than?(string)
14
+ version > Gem::Version.new(string)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Shoe
2
+ module Extensions
3
+
4
+ module Validator
5
+ def alert_error(*args)
6
+ # no-op
7
+ end
8
+
9
+ def unit_test(*args)
10
+ exit(1) unless super.passed?
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -1,63 +1,145 @@
1
1
  require 'erb'
2
+ require 'optparse'
2
3
  require 'pathname'
3
4
 
4
5
  module Shoe
5
6
  class Generator
6
- def initialize(root)
7
- @root = Pathname.new(root).expand_path
8
- @template_path = Pathname.new(__FILE__).dirname.join('templates')
7
+ def initialize
8
+ @options = {}
9
+ @parser = OptionParser.new do |opts|
10
+ opts.extend(Extensions::OptionParser)
11
+
12
+ opts.banner = "Usage: #{File.basename($0)} [-adehtv] [path]"
13
+ opts.defaults = %w(--no-application --no-data --no-extension --test-unit .)
14
+ opts.version = Shoe::VERSION
15
+
16
+ opts.on('-a', '--[no-]application', 'Generate a command-line application.') do |application|
17
+ @options[:application] = application
18
+ end
19
+
20
+ opts.on('-d', '--[no-]data', 'Generate a data directory.') do |data|
21
+ @options[:data] = data
22
+ end
23
+
24
+ opts.on('-e', '--[no-]extension', 'Generate a C extension.') do |extension|
25
+ @options[:extension] = extension
26
+ end
27
+
28
+ opts.on('-t', '--[no-]test-unit', 'Generate Test::Unit tests.') do |test_unit|
29
+ @options[:test_unit] = test_unit
30
+ end
31
+ end
9
32
  end
10
33
 
11
- def run
12
- path('README.rdoc').install template('readme.erb')
13
- path('Rakefile').install template('rakefile.erb')
14
- path(version_path).install template('version.erb')
15
- path(gemspec_path).install template('gemspec.erb')
34
+ def run(arguments)
35
+ @parser.order(arguments) { |path| @project = Project.new(path, @options) }
36
+
37
+ @project.generate
16
38
  end
17
39
 
18
40
  private
19
41
 
20
- def project_name
21
- @root.basename.to_s
22
- end
23
42
 
24
- def project_module
25
- project_name.capitalize.gsub(/_(\w)/) { $1.upcase }
26
- end
43
+ class Project
44
+ def initialize(path, options)
45
+ @path = Pathname.new(path)
46
+ @options = options
47
+ end
27
48
 
28
- def project_version
29
- '0.0.0'
30
- end
49
+ def generate
50
+ install('gitignore.erb', '.gitignore')
51
+ install('readme.erb', 'README.rdoc')
52
+ install('rakefile.erb', 'Rakefile')
53
+ install('gemspec.erb', "#{name}.gemspec")
54
+ install('module.erb', "lib/#{name}.rb")
31
55
 
32
- def version_path
33
- "lib/#{project_name}/version.rb"
34
- end
56
+ if application?
57
+ install('executable.erb', "bin/#{name}", 0755)
58
+ install('application.erb', "lib/#{name}/application.rb")
59
+ install('manpage.erb', "man/#{name}.1.ronn")
60
+ end
35
61
 
36
- def gemspec_path
37
- "#{project_name}.gemspec"
38
- end
62
+ if data?
63
+ install('gitkeep.erb', "data/#{name}/.gitkeep")
64
+ end
39
65
 
40
- def template(name)
41
- ERB.new(template_contents(name)).result(binding)
42
- end
66
+ if extension?
67
+ install('extconf.erb', "ext/#{name}/extconf.rb")
68
+ install('extension.erb', "ext/#{name}/#{extension_name}.c")
69
+ end
43
70
 
44
- def template_contents(name)
45
- @template_path.join(name).read
46
- end
71
+ if test_unit?
72
+ install('test_helper.erb', "test/helper.rb")
73
+ install('module_test.rb', "test/#{name}_test.rb")
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def install(template, path, mode=0644)
80
+ installable_path(path).install(contents(template), mode)
81
+ end
47
82
 
48
- def path(name)
49
- path = @root.join(name)
50
- path.dirname.mkpath
51
- path.extend(PathExtensions)
83
+ def application?
84
+ @options[:application]
85
+ end
86
+
87
+ def data?
88
+ @options[:data]
89
+ end
90
+
91
+ def extension?
92
+ @options[:extension]
93
+ end
94
+
95
+ def test_unit?
96
+ @options[:test_unit]
97
+ end
98
+
99
+ def name
100
+ @path.expand_path.basename.to_s
101
+ end
102
+
103
+ def module_name
104
+ name.capitalize.gsub(/_(\w)/) { $1.upcase }
105
+ end
106
+
107
+ def version
108
+ '0.0.0'
109
+ end
110
+
111
+ def extension_name
112
+ 'extension'
113
+ end
114
+
115
+ def extension_module_name
116
+ extension_name.capitalize.gsub(/_(\w)/) { $1.upcase }
117
+ end
118
+
119
+ def installable_path(name)
120
+ path = @path.join(name)
121
+ path.dirname.mkpath
122
+ path.extend(Extensions::Pathname)
123
+ end
124
+
125
+ def contents(template)
126
+ Template.new(template).evaluate(binding)
127
+ end
52
128
  end
53
129
 
54
- module PathExtensions #:nodoc:
55
- def install(contents)
56
- if exist?
57
- $stderr.puts "#{to_s} exists. Not clobbering."
58
- else
59
- open('w') { |file| file.write(contents) }
60
- end
130
+ class Template
131
+ def initialize(name)
132
+ @name = name
133
+ end
134
+
135
+ def evaluate(binding)
136
+ ERB.new(contents, nil, '<>').result(binding)
137
+ end
138
+
139
+ private
140
+
141
+ def contents
142
+ Shoe.datadir.join('templates', @name).read
61
143
  end
62
144
  end
63
145
  end
@@ -6,6 +6,7 @@ module Shoe
6
6
  autoload :Compile, 'shoe/tasks/compile'
7
7
  autoload :Cucumber, 'shoe/tasks/cucumber'
8
8
  autoload :Rdoc, 'shoe/tasks/rdoc'
9
+ autoload :Ronn, 'shoe/tasks/ronn'
9
10
  autoload :Release, 'shoe/tasks/release'
10
11
  autoload :Test, 'shoe/tasks/test'
11
12
 
@@ -14,6 +15,7 @@ module Shoe
14
15
  Compile
15
16
  Cucumber
16
17
  Rdoc
18
+ Ronn
17
19
  Release
18
20
  Test
19
21
  )
@@ -5,75 +5,9 @@ module Shoe
5
5
  attr_reader :spec
6
6
 
7
7
  def initialize(spec)
8
- @spec = if spec.respond_to?(:rubygems_version)
9
- spec
10
- else
11
- Gem::Specification.load(spec)
12
- end
13
-
14
- @spec.extend(LocalGemspecExtensions)
15
-
16
- if active?
17
- define
18
- end
19
- end
20
-
21
- private
22
-
23
- module LocalGemspecExtensions #:nodoc:
24
- def full_gem_path
25
- Dir.pwd
26
- end
27
- end
28
-
29
- def warn(subject, *paragraphs)
30
- $stderr.extend(Colored).
31
- extend(Formatted).
32
- message(subject, paragraphs)
33
- end
34
-
35
- module Colored #:nodoc:
36
- YELLOW = "\e[33m"
37
- CLEAR = "\e[0m"
38
-
39
- def write(string)
40
- super(YELLOW) if tty?
41
- super
42
- super(CLEAR) if tty?
43
- end
44
- end
45
-
46
- module Formatted #:nodoc:
47
- WIDTH = 72
48
- WRAP = /(.{1,#{WIDTH}})( +|$\n?)|(.{1,#{WIDTH}})/
49
-
50
- def message(subject, paragraphs)
51
- border
52
- heading(subject)
53
- body(paragraphs)
54
- border
55
- end
56
-
57
- private
58
-
59
- def border
60
- puts '-' * WIDTH
61
- end
62
-
63
- def heading(string)
64
- puts "#{string} warning from shoe".upcase
65
- end
66
-
67
- def body(paragraphs)
68
- paragraphs.each do |paragraph|
69
- puts
70
- puts wrap(paragraph)
71
- end
72
- end
73
-
74
- def wrap(string)
75
- string.gsub(WRAP, "\\1\\3\n")
76
- end
8
+ @spec = Gem::Specification.load(spec)
9
+ @spec.extend(Extensions::Specification)
10
+ define if active?
77
11
  end
78
12
  end
79
13