bueller 0.0.1

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 (109) hide show
  1. data/ChangeLog.markdown +141 -0
  2. data/LICENSE +20 -0
  3. data/README.markdown +182 -0
  4. data/bin/bueller +5 -0
  5. data/lib/bueller/commands/build_gem.rb +50 -0
  6. data/lib/bueller/commands/git_tag_release.rb +63 -0
  7. data/lib/bueller/commands/install_gem.rb +36 -0
  8. data/lib/bueller/commands/release_to_github.rb +41 -0
  9. data/lib/bueller/commands/release_to_rubygems.rb +26 -0
  10. data/lib/bueller/commands/version/base.rb +36 -0
  11. data/lib/bueller/commands/version/bump_major.rb +11 -0
  12. data/lib/bueller/commands/version/bump_minor.rb +12 -0
  13. data/lib/bueller/commands/version/bump_patch.rb +14 -0
  14. data/lib/bueller/commands/version/write.rb +21 -0
  15. data/lib/bueller/commands/write_gemspec.rb +29 -0
  16. data/lib/bueller/commands.rb +18 -0
  17. data/lib/bueller/errors.rb +8 -0
  18. data/lib/bueller/gemspec_helper.rb +83 -0
  19. data/lib/bueller/generator/application.rb +51 -0
  20. data/lib/bueller/generator/bacon_mixin.rb +43 -0
  21. data/lib/bueller/generator/github_mixin.rb +29 -0
  22. data/lib/bueller/generator/micronaut_mixin.rb +41 -0
  23. data/lib/bueller/generator/minitest_mixin.rb +42 -0
  24. data/lib/bueller/generator/options.rb +154 -0
  25. data/lib/bueller/generator/rdoc_mixin.rb +9 -0
  26. data/lib/bueller/generator/riot_mixin.rb +42 -0
  27. data/lib/bueller/generator/rspec_mixin.rb +50 -0
  28. data/lib/bueller/generator/shindo_mixin.rb +44 -0
  29. data/lib/bueller/generator/shoulda_mixin.rb +42 -0
  30. data/lib/bueller/generator/testspec_mixin.rb +42 -0
  31. data/lib/bueller/generator/testunit_mixin.rb +39 -0
  32. data/lib/bueller/generator/yard_mixin.rb +14 -0
  33. data/lib/bueller/generator.rb +291 -0
  34. data/lib/bueller/rubyforge_tasks.rb +88 -0
  35. data/lib/bueller/tasks.rb +133 -0
  36. data/lib/bueller/templates/.document +11 -0
  37. data/lib/bueller/templates/.gitignore +40 -0
  38. data/lib/bueller/templates/Gemfile +1 -0
  39. data/lib/bueller/templates/LICENSE +20 -0
  40. data/lib/bueller/templates/README.rdoc +17 -0
  41. data/lib/bueller/templates/Rakefile +20 -0
  42. data/lib/bueller/templates/bacon/flunking.rb +7 -0
  43. data/lib/bueller/templates/bacon/helper.rb +8 -0
  44. data/lib/bueller/templates/bueller_tasks.erb +10 -0
  45. data/lib/bueller/templates/features/default.feature +9 -0
  46. data/lib/bueller/templates/features/support/env.rb +16 -0
  47. data/lib/bueller/templates/gemspec +27 -0
  48. data/lib/bueller/templates/micronaut/flunking.rb +7 -0
  49. data/lib/bueller/templates/micronaut/helper.rb +17 -0
  50. data/lib/bueller/templates/minitest/flunking.rb +7 -0
  51. data/lib/bueller/templates/minitest/helper.rb +11 -0
  52. data/lib/bueller/templates/other_tasks.erb +84 -0
  53. data/lib/bueller/templates/riot/flunking.rb +11 -0
  54. data/lib/bueller/templates/riot/helper.rb +3 -0
  55. data/lib/bueller/templates/rspec/.rspec +1 -0
  56. data/lib/bueller/templates/rspec/flunking.rb +7 -0
  57. data/lib/bueller/templates/rspec/helper.rb +19 -0
  58. data/lib/bueller/templates/shindo/flunking.rb +8 -0
  59. data/lib/bueller/templates/shindo/helper.rb +5 -0
  60. data/lib/bueller/templates/shoulda/flunking.rb +7 -0
  61. data/lib/bueller/templates/shoulda/helper.rb +10 -0
  62. data/lib/bueller/templates/testspec/flunking.rb +7 -0
  63. data/lib/bueller/templates/testspec/helper.rb +7 -0
  64. data/lib/bueller/templates/testunit/flunking.rb +7 -0
  65. data/lib/bueller/templates/testunit/helper.rb +9 -0
  66. data/lib/bueller/version_helper.rb +59 -0
  67. data/lib/bueller.rb +139 -0
  68. data/spec/bueller/commands/build_gem_spec.rb +38 -0
  69. data/spec/bueller/commands/git_tag_release_spec.rb +79 -0
  70. data/spec/bueller/commands/install_gem_spec.rb +11 -0
  71. data/spec/bueller/commands/release_to_github_spec.rb +54 -0
  72. data/spec/bueller/commands/release_to_rubygems_spec.rb +15 -0
  73. data/spec/bueller/commands/version/bump_major_spec.rb +12 -0
  74. data/spec/bueller/commands/version/bump_minor_spec.rb +12 -0
  75. data/spec/bueller/commands/version/bump_patch_spec.rb +12 -0
  76. data/spec/bueller/commands/write_gemspec_spec.rb +32 -0
  77. data/spec/bueller/gemspec_helper_spec.rb +55 -0
  78. data/spec/bueller/generator/application_spec.rb +67 -0
  79. data/spec/bueller/generator/options_spec.rb +206 -0
  80. data/spec/bueller/generator_mixins_spec.rb +23 -0
  81. data/spec/bueller/generator_spec.rb +274 -0
  82. data/spec/bueller/tasks_spec.rb +29 -0
  83. data/spec/bueller/version_helper_spec.rb +57 -0
  84. data/spec/bueller_spec.rb +94 -0
  85. data/spec/fixtures/bar/bar.gemspec +41 -0
  86. data/spec/fixtures/bar/bin/foo_the_ultimate_bin +1 -0
  87. data/spec/fixtures/bar/hey_include_me_in_gemspec +0 -0
  88. data/spec/fixtures/bar/lib/foo_the_ultimate_lib.rb +1 -0
  89. data/spec/fixtures/existing-project/LICENSE +20 -0
  90. data/spec/fixtures/existing-project/README.rdoc +7 -0
  91. data/spec/fixtures/existing-project/Rakefile +69 -0
  92. data/spec/fixtures/existing-project/existing-project.gemspec +20 -0
  93. data/spec/fixtures/existing-project/lib/existing_project_with_version.rb +0 -0
  94. data/spec/fixtures/existing-project/test/existing_project_with_version_test.rb +7 -0
  95. data/spec/fixtures/existing-project/test/test_helper.rb +10 -0
  96. data/spec/fixtures/existing-project-with-version-constant/LICENSE +20 -0
  97. data/spec/fixtures/existing-project-with-version-constant/README.rdoc +7 -0
  98. data/spec/fixtures/existing-project-with-version-constant/Rakefile +69 -0
  99. data/spec/fixtures/existing-project-with-version-constant/existing-project-with-version.gemspec +19 -0
  100. data/spec/fixtures/existing-project-with-version-constant/lib/existing_project_with_version.rb +0 -0
  101. data/spec/fixtures/existing-project-with-version-constant/test/existing_project_with_version_test.rb +7 -0
  102. data/spec/fixtures/existing-project-with-version-constant/test/test_helper.rb +10 -0
  103. data/spec/spec_helper.rb +11 -0
  104. data/spec/support/application.rb +28 -0
  105. data/spec/support/file_system.rb +24 -0
  106. data/spec/support/gemspec.rb +28 -0
  107. data/spec/support/git.rb +19 -0
  108. data/spec/support/have_version.rb +18 -0
  109. metadata +381 -0
@@ -0,0 +1,42 @@
1
+ class Bueller
2
+ class Generator
3
+ module TestspecMixin
4
+ def self.extended(generator)
5
+ generator.development_dependencies << 'test-spec'
6
+ end
7
+
8
+ def default_task
9
+ 'test'
10
+ end
11
+
12
+ def feature_support_require
13
+ 'test/unit/assertions'
14
+ end
15
+
16
+ def feature_support_extend
17
+ 'Test::Unit::Assertions'
18
+ end
19
+
20
+ def test_dir
21
+ 'test'
22
+ end
23
+
24
+ def test_task
25
+ 'test'
26
+ end
27
+
28
+ def test_pattern
29
+ 'test/**/*_test.rb'
30
+ end
31
+
32
+ def test_filename
33
+ "#{require_name}_test.rb"
34
+ end
35
+
36
+ def test_helper_filename
37
+ "test_helper.rb"
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,39 @@
1
+ class Bueller
2
+ class Generator
3
+ module TestunitMixin
4
+
5
+ def default_task
6
+ 'test'
7
+ end
8
+
9
+ def feature_support_require
10
+ 'test/unit/assertions'
11
+ end
12
+
13
+ def feature_support_extend
14
+ 'Test::Unit::Assertions'
15
+ end
16
+
17
+ def test_dir
18
+ 'test'
19
+ end
20
+
21
+ def test_task
22
+ 'test'
23
+ end
24
+
25
+ def test_pattern
26
+ 'test/**/test_*.rb'
27
+ end
28
+
29
+ def test_filename
30
+ "test_#{require_name}.rb"
31
+ end
32
+
33
+ def test_helper_filename
34
+ "helper.rb"
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ class Bueller
2
+ class Generator
3
+ module YardMixin
4
+ def self.extended(generator)
5
+ generator.development_dependencies << 'yard'
6
+ end
7
+
8
+ def doc_task
9
+ 'yardoc'
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,291 @@
1
+ require 'git'
2
+ require 'erb'
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ require 'fileutils'
8
+
9
+ class Bueller
10
+ class NoGitUserName < StandardError
11
+ end
12
+ class NoGitUserEmail < StandardError
13
+ end
14
+ class FileInTheWay < StandardError
15
+ end
16
+ class NoGitHubRepoNameGiven < StandardError
17
+ end
18
+ class NoGitHubUser < StandardError
19
+ end
20
+ class NoGitHubToken < StandardError
21
+ end
22
+ class GitInitFailed < StandardError
23
+ end
24
+
25
+ # Generator for creating a bueller-enabled project
26
+ class Generator
27
+ require 'bueller/generator/options'
28
+ require 'bueller/generator/application'
29
+
30
+ require 'bueller/generator/github_mixin'
31
+
32
+ require 'bueller/generator/bacon_mixin'
33
+ require 'bueller/generator/micronaut_mixin'
34
+ require 'bueller/generator/minitest_mixin'
35
+ require 'bueller/generator/rspec_mixin'
36
+ require 'bueller/generator/shoulda_mixin'
37
+ require 'bueller/generator/testspec_mixin'
38
+ require 'bueller/generator/testunit_mixin'
39
+ require 'bueller/generator/riot_mixin'
40
+ require 'bueller/generator/shindo_mixin'
41
+
42
+ require 'bueller/generator/rdoc_mixin'
43
+ require 'bueller/generator/yard_mixin'
44
+
45
+ attr_accessor :target_dir, :user_name, :user_email, :summary, :homepage,
46
+ :description, :project_name, :github_username, :github_token,
47
+ :repo, :create_remote_repo,
48
+ :testing_framework, :documentation_framework,
49
+ :use_cucumber, :setup_gemcutter,
50
+ :setup_rubyforge, :use_reek, :use_roodi,
51
+ :development_dependencies,
52
+ :options,
53
+ :git_remote
54
+
55
+ alias :create_remote_repo? :create_remote_repo
56
+ alias :use_cucumber? :use_cucumber
57
+ alias :setup_rubyforge? :setup_rubyforge
58
+ alias :use_reek? :use_reek
59
+ alias :use_roodi? :use_roodi
60
+
61
+ def self.run(options = {})
62
+ generator = self.new(options)
63
+ generator.run
64
+ end
65
+
66
+ def initialize(options = {})
67
+ self.options = options
68
+
69
+ self.project_name = options[:project_name]
70
+ if self.project_name.nil? || self.project_name.squeeze.strip == ""
71
+ raise NoGitHubRepoNameGiven
72
+ end
73
+
74
+ self.development_dependencies = []
75
+ self.testing_framework = options[:testing_framework]
76
+ self.documentation_framework = options[:documentation_framework]
77
+ begin
78
+ generator_mixin_name = "#{testing_framework.to_s.capitalize}Mixin"
79
+ generator_mixin = self.class.const_get(generator_mixin_name)
80
+ extend generator_mixin
81
+ rescue NameError => e
82
+ raise ArgumentError, "Unsupported testing framework (#{testing_framework})"
83
+ end
84
+
85
+ begin
86
+ generator_mixin_name = "#{self.documentation_framework.to_s.capitalize}Mixin"
87
+ generator_mixin = self.class.const_get(generator_mixin_name)
88
+ extend generator_mixin
89
+ rescue NameError => e
90
+ raise ArgumentError, "Unsupported documentation framework (#{documentation_framework})"
91
+ end
92
+
93
+ self.target_dir = options[:directory] || self.project_name
94
+
95
+ self.summary = options[:summary] || 'TODO: one-line summary of your gem'
96
+ self.description = options[:description] || 'TODO: detailed description of your gem'
97
+ self.use_cucumber = options[:use_cucumber]
98
+ self.use_reek = options[:use_reek]
99
+ self.use_roodi = options[:use_roodi]
100
+ self.setup_gemcutter = options[:gemcutter]
101
+ self.setup_rubyforge = options[:rubyforge]
102
+
103
+ development_dependencies << 'cucumber' if use_cucumber?
104
+
105
+ development_dependencies << 'bundler'
106
+ development_dependencies << 'bueller'
107
+ development_dependencies << 'rake'
108
+ development_dependencies << 'rcov'
109
+
110
+ development_dependencies << 'reek' if use_reek?
111
+ development_dependencies << 'roodi' if use_roodi?
112
+
113
+ self.user_name = options[:user_name]
114
+ self.user_email = options[:user_email]
115
+ self.homepage = options[:homepage]
116
+
117
+ self.git_remote = options[:git_remote]
118
+
119
+ raise NoGitUserName unless self.user_name
120
+ raise NoGitUserEmail unless self.user_email
121
+
122
+ extend GithubMixin
123
+ end
124
+
125
+ def run
126
+ create_files
127
+ create_version_control
128
+ $stdout.puts "Bueller has prepared your gem in #{target_dir}"
129
+ if create_remote_repo?
130
+ create_and_push_repo
131
+ $stdout.puts "Bueller has pushed your repo to #{homepage}"
132
+ end
133
+ end
134
+
135
+ def constant_name
136
+ self.project_name.split(/[-_]/).collect{|each| each.capitalize }.join
137
+ end
138
+
139
+ def lib_filename
140
+ "#{project_name}.rb"
141
+ end
142
+
143
+ def require_name
144
+ self.project_name
145
+ end
146
+
147
+ def file_name_prefix
148
+ self.project_name.gsub('-', '_')
149
+ end
150
+
151
+ def lib_dir
152
+ 'lib'
153
+ end
154
+
155
+ def feature_filename
156
+ "#{project_name}.feature"
157
+ end
158
+
159
+ def steps_filename
160
+ "#{project_name}_steps.rb"
161
+ end
162
+
163
+ def features_dir
164
+ 'features'
165
+ end
166
+
167
+ def features_support_dir
168
+ File.join(features_dir, 'support')
169
+ end
170
+
171
+ def features_steps_dir
172
+ File.join(features_dir, 'step_definitions')
173
+ end
174
+
175
+ private
176
+
177
+ def create_files
178
+ unless File.exists?(target_dir) || File.directory?(target_dir)
179
+ FileUtils.mkdir target_dir
180
+ else
181
+ raise FileInTheWay, "The directory #{target_dir} already exists, aborting. Maybe move it out of the way before continuing?"
182
+ end
183
+
184
+
185
+ output_template_in_target '.gitignore'
186
+ output_template_in_target 'Rakefile'
187
+ output_template_in_target 'Gemfile'
188
+ output_template_in_target 'LICENSE'
189
+ output_template_in_target 'README.rdoc'
190
+ output_template_in_target '.document'
191
+ output_template_in_target 'gemspec', "#{project_name}.gemspec"
192
+
193
+ mkdir_in_target lib_dir
194
+ File.open File.join(target_dir, lib_dir, lib_filename), 'w' do |f|
195
+ f.puts "module #{constant_name}\n\nend"
196
+ end
197
+
198
+ mkdir_in_target test_dir
199
+ output_template_in_target File.join(testing_framework.to_s, 'helper.rb'),
200
+ File.join(test_dir, test_helper_filename)
201
+ output_template_in_target File.join(testing_framework.to_s, 'flunking.rb'),
202
+ File.join(test_dir, test_filename)
203
+
204
+ if use_cucumber?
205
+ mkdir_in_target features_dir
206
+ output_template_in_target File.join(%w(features default.feature)), File.join('features', feature_filename)
207
+
208
+ mkdir_in_target features_support_dir
209
+ output_template_in_target File.join(features_support_dir, 'env.rb')
210
+
211
+ mkdir_in_target features_steps_dir
212
+ touch_in_target File.join(features_steps_dir, steps_filename)
213
+ end
214
+ end
215
+
216
+ def render_template(source)
217
+ template_contents = File.read(File.join(template_dir, source))
218
+ template = ERB.new(template_contents, nil, '<>')
219
+
220
+ # squish extraneous whitespace from some of the conditionals
221
+ template.result(binding).gsub(/\n\n\n+/, "\n\n")
222
+ end
223
+
224
+ def output_template_in_target(source, destination = source)
225
+ final_destination = File.join(target_dir, destination)
226
+ template_result = render_template(source)
227
+
228
+ File.open(final_destination, 'w') {|file| file.write(template_result)}
229
+
230
+ $stdout.puts "\tcreate\t#{destination}"
231
+ end
232
+
233
+ def template_dir
234
+ File.join(File.dirname(__FILE__), 'templates')
235
+ end
236
+
237
+ def mkdir_in_target(directory)
238
+ final_destination = File.join(target_dir, directory)
239
+
240
+ FileUtils.mkdir final_destination
241
+
242
+ $stdout.puts "\tcreate\t#{directory}"
243
+ end
244
+
245
+ def touch_in_target(destination)
246
+ final_destination = File.join(target_dir, destination)
247
+ FileUtils.touch final_destination
248
+ $stdout.puts "\tcreate\t#{destination}"
249
+ end
250
+
251
+ def create_version_control
252
+ Dir.chdir(target_dir) do
253
+ begin
254
+ @repo = Git.init()
255
+ rescue Git::GitExecuteError => e
256
+ raise GitInitFailed, "Encountered an error during gitification. Maybe the repo already exists, or has already been pushed to?"
257
+ end
258
+
259
+ begin
260
+ @repo.add('.')
261
+ rescue Git::GitExecuteError => e
262
+ #raise GitAddFailed, "There was some problem adding this directory to the git changeset"
263
+ raise
264
+ end
265
+
266
+ begin
267
+ @repo.commit "Initial commit to #{project_name}."
268
+ rescue Git::GitExecuteError => e
269
+ raise
270
+ end
271
+
272
+ begin
273
+ @repo.add_remote('origin', git_remote)
274
+ rescue Git::GitExecuteError => e
275
+ puts "Encountered an error while adding origin remote. Maybe you have some weird settings in ~/.gitconfig?"
276
+ raise
277
+ end
278
+ end
279
+ end
280
+
281
+ def create_and_push_repo
282
+ Net::HTTP.post_form URI.parse('http://github.com/api/v2/yaml/repos/create'),
283
+ 'login' => github_username,
284
+ 'token' => github_token,
285
+ 'description' => summary,
286
+ 'name' => project_name
287
+ # TODO do a HEAD request to see when it's ready?
288
+ @repo.push('origin')
289
+ end
290
+ end
291
+ end
@@ -0,0 +1,88 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ class Bueller
5
+ # (Mostly deprecated) Rake tasks for putting a Bueller gem on Rubyforge.
6
+ #
7
+ # Bueller::Tasks.new needs to be used before this.
8
+ #
9
+ # Basic usage:
10
+ #
11
+ # Bueller::RubyforgeTasks.new
12
+ #
13
+ # There are a few options you can tweak:
14
+ #
15
+ # * project: the rubyforge project to operate on. This defaults to whatever you specified in your gemspec. Defaults to your gem name.
16
+ # * remote_doc_path: the place to upload docs to on Rubyforge under /var/www/gforge-projects/#{project}/
17
+ #
18
+ # See also http://wiki.github.com/technicalpickles/bueller/rubyforge
19
+ class RubyforgeTasks < ::Rake::TaskLib
20
+ # The RubyForge project to interact with. Defaults to whatever is in your bueller gemspec.
21
+ attr_accessor :project
22
+ # The path to upload docs to. It is relative to /var/www/gforge-projects/#{project}/, and defaults to your gemspec's name
23
+ attr_accessor :remote_doc_path
24
+ # Task to be used for generating documentation, before they are uploaded. Defaults to rdoc.
25
+ attr_accessor :doc_task
26
+
27
+ attr_accessor :bueller
28
+
29
+ def initialize
30
+ yield self if block_given?
31
+
32
+ define
33
+ end
34
+
35
+ def bueller
36
+ @bueller ||= Rake.application.bueller
37
+ end
38
+
39
+ def remote_doc_path
40
+ @remote_doc_path ||= bueller.gemspec.name
41
+ end
42
+
43
+ def project
44
+ @project ||= bueller.gemspec.rubyforge_project
45
+ end
46
+
47
+ def define
48
+ namespace :rubyforge do
49
+ namespace :release do
50
+ desc "Pretend to release the current gem version to RubyForge, but actually release to Gemcutter."
51
+ task :gem => 'gemcutter:release'
52
+
53
+ if publish_documentation?
54
+ desc "Publish docs to RubyForge."
55
+ task :docs => doc_task do
56
+ config = YAML.load(
57
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
58
+ )
59
+
60
+ host = "#{config['username']}@rubyforge.org"
61
+ remote_dir = "/var/www/gforge-projects/#{project}/#{remote_doc_path}"
62
+
63
+ local_dir = case self.doc_task.to_sym
64
+ when :rdoc then 'rdoc'
65
+ when :yardoc then 'doc'
66
+ else
67
+ raise "Unsure what to run to generate documentation. Please set doc_task and re-run."
68
+ end
69
+
70
+ sh %{rsync --archive --verbose --delete #{local_dir}/ #{host}:#{remote_dir}}
71
+ end
72
+ end
73
+ end
74
+
75
+ if publish_documentation?
76
+ desc "Release RDoc documentation to RubyForge"
77
+ task :release => "rubyforge:release:docs"
78
+ end
79
+ end
80
+
81
+ task :release => 'rubyforge:release'
82
+ end
83
+
84
+ def publish_documentation?
85
+ ! (doc_task == false || doc_task == :none)
86
+ end
87
+ end
88
+ end