juwelier 2.1.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 (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