juwelier 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.document +8 -0
  4. data/.semver +5 -0
  5. data/.travis.yml +7 -0
  6. data/.yardopts +2 -0
  7. data/ChangeLog.markdown +230 -0
  8. data/Gemfile +40 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.markdown +252 -0
  11. data/Rakefile +78 -0
  12. data/bin/juwelier +9 -0
  13. data/features/generator/cucumber.feature +103 -0
  14. data/features/generator/directory_layout.feature +86 -0
  15. data/features/generator/dotdocument.feature +13 -0
  16. data/features/generator/env_options.feature +9 -0
  17. data/features/generator/gemfile.feature +81 -0
  18. data/features/generator/git.feature +102 -0
  19. data/features/generator/license.feature +20 -0
  20. data/features/generator/rakefile.feature +158 -0
  21. data/features/generator/readme.feature +12 -0
  22. data/features/generator/test.feature +54 -0
  23. data/features/generator/test_helper.feature +149 -0
  24. data/features/placeholder.feature +5 -0
  25. data/features/step_definitions/debug_steps.rb +6 -0
  26. data/features/step_definitions/filesystem_steps.rb +70 -0
  27. data/features/step_definitions/generator_steps.rb +387 -0
  28. data/features/step_definitions/task_steps.rb +6 -0
  29. data/features/support/env.rb +41 -0
  30. data/features/tasks/build_gem.feature +9 -0
  31. data/features/tasks/version.feature +31 -0
  32. data/features/tasks/version_bumping.feature +49 -0
  33. data/juwelier.gemspec +241 -0
  34. data/lib/juwelier.rb +178 -0
  35. data/lib/juwelier/commands.rb +20 -0
  36. data/lib/juwelier/commands/build_gem.rb +40 -0
  37. data/lib/juwelier/commands/check_dependencies.rb +66 -0
  38. data/lib/juwelier/commands/install_gem.rb +31 -0
  39. data/lib/juwelier/commands/release_gemspec.rb +87 -0
  40. data/lib/juwelier/commands/release_to_git.rb +64 -0
  41. data/lib/juwelier/commands/release_to_rubygems.rb +28 -0
  42. data/lib/juwelier/commands/validate_gemspec.rb +30 -0
  43. data/lib/juwelier/commands/version/base.rb +55 -0
  44. data/lib/juwelier/commands/version/bump_major.rb +13 -0
  45. data/lib/juwelier/commands/version/bump_minor.rb +12 -0
  46. data/lib/juwelier/commands/version/bump_patch.rb +14 -0
  47. data/lib/juwelier/commands/version/write.rb +12 -0
  48. data/lib/juwelier/commands/write_gemspec.rb +39 -0
  49. data/lib/juwelier/errors.rb +8 -0
  50. data/lib/juwelier/gemcutter_tasks.rb +8 -0
  51. data/lib/juwelier/gemspec_helper.rb +87 -0
  52. data/lib/juwelier/generator.rb +304 -0
  53. data/lib/juwelier/generator/application.rb +63 -0
  54. data/lib/juwelier/generator/bacon_mixin.rb +43 -0
  55. data/lib/juwelier/generator/github_mixin.rb +22 -0
  56. data/lib/juwelier/generator/micronaut_mixin.rb +41 -0
  57. data/lib/juwelier/generator/minitest_mixin.rb +42 -0
  58. data/lib/juwelier/generator/options.rb +172 -0
  59. data/lib/juwelier/generator/rdoc_mixin.rb +13 -0
  60. data/lib/juwelier/generator/riot_mixin.rb +42 -0
  61. data/lib/juwelier/generator/rspec_mixin.rb +42 -0
  62. data/lib/juwelier/generator/shindo_mixin.rb +44 -0
  63. data/lib/juwelier/generator/shoulda_mixin.rb +42 -0
  64. data/lib/juwelier/generator/testspec_mixin.rb +42 -0
  65. data/lib/juwelier/generator/testunit_mixin.rb +39 -0
  66. data/lib/juwelier/generator/yard_mixin.rb +15 -0
  67. data/lib/juwelier/rubyforge_tasks.rb +95 -0
  68. data/lib/juwelier/rubygems_dot_org_tasks.rb +38 -0
  69. data/lib/juwelier/rubygems_tasks.rb +38 -0
  70. data/lib/juwelier/specification.rb +110 -0
  71. data/lib/juwelier/tasks.rb +239 -0
  72. data/lib/juwelier/templates/.document +5 -0
  73. data/lib/juwelier/templates/.gitignore +49 -0
  74. data/lib/juwelier/templates/Gemfile +12 -0
  75. data/lib/juwelier/templates/LICENSE.txt +20 -0
  76. data/lib/juwelier/templates/README.rdoc +19 -0
  77. data/lib/juwelier/templates/Rakefile +9 -0
  78. data/lib/juwelier/templates/bacon/flunking.rb +7 -0
  79. data/lib/juwelier/templates/bacon/helper.rb +10 -0
  80. data/lib/juwelier/templates/bundler_setup.erb +10 -0
  81. data/lib/juwelier/templates/features/default.feature +9 -0
  82. data/lib/juwelier/templates/features/support/env.rb +11 -0
  83. data/lib/juwelier/templates/juwelier_tasks.erb +31 -0
  84. data/lib/juwelier/templates/micronaut/flunking.rb +7 -0
  85. data/lib/juwelier/templates/micronaut/helper.rb +19 -0
  86. data/lib/juwelier/templates/minitest/flunking.rb +7 -0
  87. data/lib/juwelier/templates/minitest/helper.rb +13 -0
  88. data/lib/juwelier/templates/other_tasks.erb +70 -0
  89. data/lib/juwelier/templates/riot/flunking.rb +11 -0
  90. data/lib/juwelier/templates/riot/helper.rb +5 -0
  91. data/lib/juwelier/templates/rspec/.rspec +1 -0
  92. data/lib/juwelier/templates/rspec/flunking.rb +7 -0
  93. data/lib/juwelier/templates/rspec/helper.rb +14 -0
  94. data/lib/juwelier/templates/shindo/flunking.rb +8 -0
  95. data/lib/juwelier/templates/shindo/helper.rb +7 -0
  96. data/lib/juwelier/templates/shoulda/flunking.rb +7 -0
  97. data/lib/juwelier/templates/shoulda/helper.rb +12 -0
  98. data/lib/juwelier/templates/simplecov.erb +16 -0
  99. data/lib/juwelier/templates/testspec/flunking.rb +7 -0
  100. data/lib/juwelier/templates/testspec/helper.rb +7 -0
  101. data/lib/juwelier/templates/testunit/flunking.rb +7 -0
  102. data/lib/juwelier/templates/testunit/helper.rb +11 -0
  103. data/lib/juwelier/version.rb +10 -0
  104. data/lib/juwelier/version_helper.rb +141 -0
  105. data/test/fixtures/bar/VERSION.yml +4 -0
  106. data/test/fixtures/bar/bin/foo_the_ultimate_bin +1 -0
  107. data/test/fixtures/bar/hey_include_me_in_gemspec +0 -0
  108. data/test/fixtures/bar/lib/foo_the_ultimate_lib.rb +1 -0
  109. data/test/fixtures/existing-project-with-version-constant/.document +5 -0
  110. data/test/fixtures/existing-project-with-version-constant/.gitignore +5 -0
  111. data/test/fixtures/existing-project-with-version-constant/LICENSE.txt +20 -0
  112. data/test/fixtures/existing-project-with-version-constant/README.rdoc +7 -0
  113. data/test/fixtures/existing-project-with-version-constant/Rakefile +85 -0
  114. data/test/fixtures/existing-project-with-version-constant/existing-project-with-version.gemspec +29 -0
  115. data/test/fixtures/existing-project-with-version-constant/lib/existing_project_with_version.rb +0 -0
  116. data/test/fixtures/existing-project-with-version-constant/test/existing_project_with_version_test.rb +7 -0
  117. data/test/fixtures/existing-project-with-version-constant/test/test_helper.rb +10 -0
  118. data/test/fixtures/existing-project-with-version-plaintext/.document +5 -0
  119. data/test/fixtures/existing-project-with-version-plaintext/.gitignore +5 -0
  120. data/test/fixtures/existing-project-with-version-plaintext/LICENSE.txt +20 -0
  121. data/test/fixtures/existing-project-with-version-plaintext/README.rdoc +7 -0
  122. data/test/fixtures/existing-project-with-version-plaintext/Rakefile +84 -0
  123. data/test/fixtures/existing-project-with-version-plaintext/VERSION +1 -0
  124. data/test/fixtures/existing-project-with-version-plaintext/existing-project-with-version.gemspec +29 -0
  125. data/test/fixtures/existing-project-with-version-plaintext/lib/existing_project_with_version.rb +0 -0
  126. data/test/fixtures/existing-project-with-version-plaintext/test/existing_project_with_version_test.rb +7 -0
  127. data/test/fixtures/existing-project-with-version-plaintext/test/test_helper.rb +10 -0
  128. data/test/fixtures/existing-project-with-version-yaml/.document +5 -0
  129. data/test/fixtures/existing-project-with-version-yaml/.gitignore +5 -0
  130. data/test/fixtures/existing-project-with-version-yaml/LICENSE.txt +20 -0
  131. data/test/fixtures/existing-project-with-version-yaml/README.rdoc +7 -0
  132. data/test/fixtures/existing-project-with-version-yaml/Rakefile +84 -0
  133. data/test/fixtures/existing-project-with-version-yaml/VERSION.yml +4 -0
  134. data/test/fixtures/existing-project-with-version-yaml/bin/foo_the_ultimate_bin +0 -0
  135. data/test/fixtures/existing-project-with-version-yaml/existing-project-with-version.gemspec +29 -0
  136. data/test/fixtures/existing-project-with-version-yaml/lib/existing_project_with_version.rb +0 -0
  137. data/test/fixtures/existing-project-with-version-yaml/test/existing_project_with_version_test.rb +7 -0
  138. data/test/fixtures/existing-project-with-version-yaml/test/test_helper.rb +10 -0
  139. data/test/geminstaller.yml +12 -0
  140. data/test/juwelier/commands/test_build_gem.rb +112 -0
  141. data/test/juwelier/commands/test_install_gem.rb +35 -0
  142. data/test/juwelier/commands/test_release_to_gemcutter.rb +39 -0
  143. data/test/juwelier/commands/test_release_to_git.rb +271 -0
  144. data/test/juwelier/commands/test_release_to_github.rb +477 -0
  145. data/test/juwelier/commands/test_validate_gemspec.rb +27 -0
  146. data/test/juwelier/commands/test_write_gemspec.rb +103 -0
  147. data/test/juwelier/commands/version/test_base.rb +53 -0
  148. data/test/juwelier/commands/version/test_bump_major.rb +22 -0
  149. data/test/juwelier/commands/version/test_bump_minor.rb +19 -0
  150. data/test/juwelier/commands/version/test_bump_patch.rb +20 -0
  151. data/test/juwelier/commands/version/test_write.rb +22 -0
  152. data/test/juwelier/generator/test_application.rb +142 -0
  153. data/test/juwelier/generator/test_options.rb +227 -0
  154. data/test/juwelier/test_gemspec_helper.rb +44 -0
  155. data/test/juwelier/test_generator.rb +140 -0
  156. data/test/juwelier/test_generator_initialization.rb +150 -0
  157. data/test/juwelier/test_generator_mixins.rb +23 -0
  158. data/test/juwelier/test_specification.rb +245 -0
  159. data/test/juwelier/test_tasks.rb +50 -0
  160. data/test/juwelier/test_version_helper.rb +214 -0
  161. data/test/shoulda_macros/juwelier_macros.rb +35 -0
  162. data/test/test_helper.rb +174 -0
  163. data/test/test_juwelier.rb +177 -0
  164. metadata +396 -0
@@ -0,0 +1,12 @@
1
+ class Juwelier
2
+ module Commands
3
+ module Version
4
+ class BumpMinor < Base
5
+
6
+ def update_version
7
+ self.version_helper.bump_minor
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ class Juwelier
2
+ module Commands
3
+ module Version
4
+ class BumpPatch < Base
5
+
6
+ def update_version
7
+ self.version_helper.bump_patch
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,12 @@
1
+ class Juwelier
2
+ module Commands
3
+ module Version
4
+ class Write < Base
5
+ attr_accessor :major, :minor, :patch, :build
6
+ def update_version
7
+ version_helper.update_to major, minor, patch, build
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,39 @@
1
+ class Juwelier
2
+ module Commands
3
+ class WriteGemspec
4
+ attr_accessor :base_dir, :gemspec, :version, :output, :gemspec_helper, :version_helper
5
+
6
+ def initialize
7
+ self.output = $stdout
8
+ end
9
+
10
+ def run
11
+ gemspec_helper.spec.version ||= begin
12
+ version_helper.refresh
13
+ version_helper.to_s
14
+ end
15
+
16
+ gemspec_helper.write
17
+
18
+ output.puts "Generated: #{gemspec_helper.path}"
19
+ end
20
+
21
+ def gemspec_helper
22
+ @gemspec_helper ||= GemSpecHelper.new(self.gemspec, self.base_dir)
23
+ end
24
+
25
+ def self.build_for(juwelier)
26
+ command = new
27
+
28
+ command.base_dir = juwelier.base_dir
29
+ command.gemspec = juwelier.gemspec
30
+ command.version = juwelier.version
31
+ command.output = juwelier.output
32
+ command.gemspec_helper = juwelier.gemspec_helper
33
+ command.version_helper = juwelier.version_helper
34
+
35
+ command
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ class Juwelier
2
+ # Gemspec related error
3
+ class GemspecError < StandardError
4
+ end
5
+
6
+ class VersionYmlError < StandardError
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'juwelier/rubygems_tasks'
2
+
3
+ class Juwelier
4
+ # Deprecated tasks for publishing to Gemcutter. See Juwelier::RubygemsDotOrgTasks
5
+ # for the current tasks to use.
6
+ class GemcutterTasks < RubygemsDotOrgTasks
7
+ end
8
+ end
@@ -0,0 +1,87 @@
1
+ class Juwelier
2
+ class GemSpecHelper
3
+ attr_accessor :spec, :base_dir
4
+
5
+ def initialize(spec, base_dir = nil)
6
+ self.spec = spec
7
+ self.base_dir = base_dir || ''
8
+
9
+ yield spec if block_given?
10
+ end
11
+
12
+ def valid?
13
+ begin
14
+ parse
15
+ true
16
+ rescue
17
+ false
18
+ end
19
+ end
20
+
21
+ def write
22
+ File.open(path, 'w') do |f|
23
+ f.write self.to_ruby
24
+ end
25
+ end
26
+
27
+ def to_ruby
28
+ normalize_files(:files)
29
+ normalize_files(:extra_rdoc_files)
30
+
31
+ gemspec_ruby = @spec.to_ruby
32
+ gemspec_ruby = prettyify_array(gemspec_ruby, :files)
33
+ gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files)
34
+ gemspec_ruby = <<-END
35
+ # Generated by juwelier
36
+ # DO NOT EDIT THIS FILE DIRECTLY
37
+ # Instead, edit Juwelier::Tasks in #{Rake.application.rakefile}, and run 'rake gemspec'
38
+ #{gemspec_ruby}
39
+ END
40
+ end
41
+
42
+ def path
43
+ denormalized_path = File.join(@base_dir, "#{@spec.name}.gemspec")
44
+ absolute_path = File.expand_path(denormalized_path)
45
+ absolute_path.gsub(Dir.getwd + File::SEPARATOR, '')
46
+ end
47
+
48
+ def parse
49
+ data = self.to_ruby
50
+ parsed_gemspec = nil
51
+ Thread.new { parsed_gemspec = eval("$SAFE = 1\n#{data}", binding, path) }.join
52
+ parsed_gemspec
53
+ end
54
+
55
+ def normalize_files(array_attribute)
56
+ array = @spec.send(array_attribute)
57
+ # only keep files, no directories, and sort
58
+ array = array.select do |path|
59
+ File.file? File.join(@base_dir, path)
60
+ end.sort
61
+
62
+ @spec.send("#{array_attribute}=", array)
63
+ end
64
+
65
+ # Adds extra space when outputting an array. This helps create better version control diffs, because otherwise it is all on the same line.
66
+ def prettyify_array(gemspec_ruby, array_name)
67
+ gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
68
+ leadin, files = match[0..-2].split("[")
69
+
70
+ leadin + "[\n #{files.gsub(%|", "|, %|",\n "|)}\n ]"
71
+ end
72
+ end
73
+
74
+ def gem_path
75
+ File.join(@base_dir, 'pkg', parse.file_name)
76
+ end
77
+
78
+ def update_version(version)
79
+ @spec.version = version.to_s
80
+ end
81
+
82
+ # Checks whether it uses the version helper or the users defined version.
83
+ def has_version?
84
+ !@spec.version.nil?
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,304 @@
1
+ require 'git'
2
+ require 'github_api'
3
+ require 'highline/import'
4
+ require 'erb'
5
+
6
+ require 'net/http'
7
+ require 'uri'
8
+
9
+ require 'fileutils'
10
+ require 'pathname'
11
+
12
+ require 'juwelier/version'
13
+
14
+ class Juwelier
15
+ class NoGitUserName < StandardError
16
+ end
17
+ class NoGitUserEmail < StandardError
18
+ end
19
+ class FileInTheWay < StandardError
20
+ end
21
+ class NoGitHubRepoNameGiven < StandardError
22
+ end
23
+ class NoGitHubUser < StandardError
24
+ end
25
+ class GitInitFailed < StandardError
26
+ end
27
+ class GitRepoCreationFailed < StandardError
28
+ end
29
+
30
+ # Generator for creating a juwelier-enabled project
31
+ class Generator
32
+ require 'juwelier/generator/options'
33
+ require 'juwelier/generator/application'
34
+
35
+ require 'juwelier/generator/github_mixin'
36
+
37
+ require 'juwelier/generator/bacon_mixin'
38
+ require 'juwelier/generator/micronaut_mixin'
39
+ require 'juwelier/generator/minitest_mixin'
40
+ require 'juwelier/generator/rspec_mixin'
41
+ require 'juwelier/generator/shoulda_mixin'
42
+ require 'juwelier/generator/testspec_mixin'
43
+ require 'juwelier/generator/testunit_mixin'
44
+ require 'juwelier/generator/riot_mixin'
45
+ require 'juwelier/generator/shindo_mixin'
46
+
47
+ require 'juwelier/generator/rdoc_mixin'
48
+ require 'juwelier/generator/yard_mixin'
49
+
50
+ attr_accessor :target_dir, :user_name, :user_email, :summary, :homepage,
51
+ :description, :project_name, :github_username,
52
+ :repo, :should_create_remote_repo,
53
+ :testing_framework, :documentation_framework,
54
+ :should_use_cucumber, :should_use_bundler,
55
+ :should_setup_rubyforge, :should_use_reek, :should_use_roodi,
56
+ :development_dependencies,
57
+ :options,
58
+ :git_remote
59
+
60
+ def initialize(options = {})
61
+ self.options = options
62
+ extracted_directory = nil
63
+
64
+ self.project_name = options[:project_name]
65
+ if self.project_name.nil? || self.project_name.squeeze.strip == ""
66
+ raise NoGitHubRepoNameGiven
67
+ else
68
+ path = File.split(self.project_name)
69
+
70
+ if path.size > 1
71
+ extracted_directory = File.join(path[0..-1])
72
+ self.project_name = path.last
73
+ end
74
+ end
75
+
76
+ self.development_dependencies = []
77
+ self.testing_framework = options[:testing_framework]
78
+ self.documentation_framework = options[:documentation_framework]
79
+ begin
80
+ generator_mixin_name = "#{self.testing_framework.to_s.capitalize}Mixin"
81
+ generator_mixin = self.class.const_get(generator_mixin_name)
82
+ extend generator_mixin
83
+ rescue NameError => e
84
+ raise ArgumentError, "Unsupported testing framework (#{testing_framework})"
85
+ end
86
+
87
+ begin
88
+ generator_mixin_name = "#{self.documentation_framework.to_s.capitalize}Mixin"
89
+ generator_mixin = self.class.const_get(generator_mixin_name)
90
+ extend generator_mixin
91
+ rescue NameError => e
92
+ raise ArgumentError, "Unsupported documentation framework (#{documentation_framework})"
93
+ end
94
+
95
+ self.target_dir = options[:directory] || extracted_directory || self.project_name
96
+
97
+ self.summary = options[:summary] || 'TODO: one-line summary of your gem'
98
+ self.description = options[:description] || 'TODO: longer description of your gem'
99
+ self.should_use_cucumber = options[:use_cucumber]
100
+ self.should_use_reek = options[:use_reek]
101
+ self.should_use_roodi = options[:use_roodi]
102
+ self.should_setup_rubyforge = options[:rubyforge]
103
+ self.should_use_bundler = options[:use_bundler]
104
+
105
+ development_dependencies << ["cucumber", ">= 0"] if should_use_cucumber
106
+
107
+ # TODO make bundler optional?
108
+ development_dependencies << ["bundler", "~> 1.0"]
109
+ development_dependencies << ["juwelier", "~> #{Juwelier::Version::STRING}"]
110
+ development_dependencies << ["simplecov", ">= 0"]
111
+
112
+ development_dependencies << ["reek", "~> 1.2.8"] if should_use_reek
113
+ development_dependencies << ["roodi", "~> 2.1.0"] if should_use_roodi
114
+
115
+ self.user_name = options[:user_name]
116
+ self.user_email = options[:user_email]
117
+ self.homepage = options[:homepage]
118
+
119
+ self.git_remote = options[:git_remote]
120
+
121
+ raise NoGitUserName unless self.user_name
122
+ raise NoGitUserEmail unless self.user_email
123
+
124
+ extend GithubMixin
125
+ end
126
+
127
+ def run
128
+ create_files
129
+ create_version_control
130
+ $stdout.puts "Juwelier has prepared your gem in #{target_dir}"
131
+ if should_create_remote_repo
132
+ create_and_push_repo
133
+ $stdout.puts "Juwelier has pushed your repo to #{git_remote}"
134
+ end
135
+ end
136
+
137
+ def constant_name
138
+ self.project_name.split(/[-_]/).collect{|each| each.capitalize }.join
139
+ end
140
+
141
+ def lib_filename
142
+ "#{project_name}.rb"
143
+ end
144
+
145
+ def require_name
146
+ self.project_name
147
+ end
148
+
149
+ def file_name_prefix
150
+ self.project_name.gsub('-', '_')
151
+ end
152
+
153
+ def lib_dir
154
+ 'lib'
155
+ end
156
+
157
+ def feature_filename
158
+ "#{project_name}.feature"
159
+ end
160
+
161
+ def steps_filename
162
+ "#{project_name}_steps.rb"
163
+ end
164
+
165
+ def features_dir
166
+ 'features'
167
+ end
168
+
169
+ def features_support_dir
170
+ File.join(features_dir, 'support')
171
+ end
172
+
173
+ def features_steps_dir
174
+ File.join(features_dir, 'step_definitions')
175
+ end
176
+
177
+ private
178
+
179
+ def create_files
180
+ unless File.exists?(target_dir) || File.directory?(target_dir)
181
+ FileUtils.mkdir target_dir
182
+ else
183
+ raise FileInTheWay, "The directory #{target_dir} already exists, aborting. Maybe move it out of the way before continuing?"
184
+ end
185
+
186
+
187
+ output_template_in_target '.gitignore'
188
+ output_template_in_target 'Rakefile'
189
+ output_template_in_target 'Gemfile' if should_use_bundler
190
+ output_template_in_target 'LICENSE.txt'
191
+ output_template_in_target 'README.rdoc'
192
+ output_template_in_target '.document'
193
+
194
+ mkdir_in_target lib_dir
195
+ touch_in_target File.join(lib_dir, lib_filename)
196
+
197
+ mkdir_in_target test_dir
198
+ output_template_in_target File.join(testing_framework.to_s, 'helper.rb'),
199
+ File.join(test_dir, test_helper_filename)
200
+ output_template_in_target File.join(testing_framework.to_s, 'flunking.rb'),
201
+ File.join(test_dir, test_filename)
202
+
203
+
204
+ if testing_framework == :rspec
205
+ output_template_in_target File.join(testing_framework.to_s, '.rspec'),
206
+ '.rspec'
207
+
208
+ end
209
+
210
+ if should_use_cucumber
211
+ mkdir_in_target features_dir
212
+ output_template_in_target File.join(%w(features default.feature)), File.join('features', feature_filename)
213
+
214
+ mkdir_in_target features_support_dir
215
+ output_template_in_target File.join(features_support_dir, 'env.rb')
216
+
217
+ mkdir_in_target features_steps_dir
218
+ touch_in_target File.join(features_steps_dir, steps_filename)
219
+ end
220
+ end
221
+
222
+ def render_template(source)
223
+ template_contents = File.read(File.join(template_dir, source))
224
+ template = ERB.new(template_contents, nil, '<>')
225
+
226
+ # squish extraneous whitespace from some of the conditionals
227
+ template.result(binding).gsub(/\n\n\n+/, "\n\n")
228
+ end
229
+
230
+ def output_template_in_target(source, destination = source)
231
+ final_destination = File.join(target_dir, destination)
232
+ template_result = render_template(source)
233
+
234
+ File.open(final_destination, 'w') {|file| file.write(template_result)}
235
+
236
+ $stdout.puts "\tcreate\t#{destination}"
237
+ end
238
+
239
+ def template_dir
240
+ File.join(File.dirname(__FILE__), 'templates')
241
+ end
242
+
243
+ def mkdir_in_target(directory)
244
+ final_destination = File.join(target_dir, directory)
245
+
246
+ FileUtils.mkdir final_destination
247
+
248
+ $stdout.puts "\tcreate\t#{directory}"
249
+ end
250
+
251
+ def touch_in_target(destination)
252
+ final_destination = File.join(target_dir, destination)
253
+ FileUtils.touch final_destination
254
+ $stdout.puts "\tcreate\t#{destination}"
255
+ end
256
+
257
+ def create_version_control
258
+ Dir.chdir(target_dir) do
259
+ begin
260
+ @repo = Git.init()
261
+ rescue Git::GitExecuteError => e
262
+ raise GitInitFailed, "Encountered an error during gitification. Maybe the repo already exists, or has already been pushed to?"
263
+ end
264
+
265
+ begin
266
+ @repo.add('.')
267
+ rescue Git::GitExecuteError => e
268
+ #raise GitAddFailed, "There was some problem adding this directory to the git changeset"
269
+ raise
270
+ end
271
+
272
+ begin
273
+ @repo.commit "Initial commit to #{project_name}."
274
+ rescue Git::GitExecuteError => e
275
+ raise
276
+ end
277
+
278
+ begin
279
+ @repo.add_remote('origin', git_remote)
280
+ rescue Git::GitExecuteError => e
281
+ puts "Encountered an error while adding origin remote. Maybe you have some weird settings in ~/.gitconfig?"
282
+ raise
283
+ end
284
+ end
285
+ end
286
+
287
+ def create_and_push_repo
288
+ puts "Please provide your Github password to create the Github repository"
289
+ begin
290
+ login = github_username
291
+ password = ask("Password: ") { |q| q.echo = false }
292
+ github = Github.new(:login => login.strip, :password => password.strip)
293
+ github.repos.create(:name => project_name, :description => summary)
294
+ rescue Github::Error::Unauthorized
295
+ puts "Wrong login/password! Please try again"
296
+ retry
297
+ rescue Github::Error::UnprocessableEntity
298
+ raise GitRepoCreationFailed, "Can't create that repo. Does it already exist?"
299
+ end
300
+ # TODO do a HEAD request to see when it's ready?
301
+ @repo.push('origin')
302
+ end
303
+ end
304
+ end