penchant 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -5,7 +5,11 @@ gemspec
5
5
 
6
6
  gem 'guard'
7
7
  gem 'guard-rspec'
8
+ gem 'guard-cucumber'
9
+
8
10
  gem 'mocha'
9
11
  gem 'fakefs'
10
12
  gem 'rspec', '~> 2.6.0'
11
13
  gem 'rake'
14
+
15
+ gem 'cucumber'
data/Guardfile CHANGED
@@ -1,9 +1,18 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard 'rspec', :cli => '-c', :version => 2 do
5
- watch(%r{^spec/.+_spec\.rb$})
6
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
4
+ group :rspec do
5
+ guard 'rspec', :cli => '-c', :version => 2 do
6
+ watch(%r{^spec/.+_spec\.rb$})
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
+ watch('spec/spec_helper.rb') { "spec" }
9
+ end
8
10
  end
9
11
 
12
+ group :cucumber do
13
+ guard 'cucumber' do
14
+ watch(%r{^features/.+\.feature$})
15
+ watch(%r{^features/support/.+$}) { 'features' }
16
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
17
+ end
18
+ end
data/README.md CHANGED
@@ -46,7 +46,8 @@ You can also run `penchant gemfile ENV`.
46
46
 
47
47
  Use `no_deployment` blocks to indicate gems that shouldn't even appear in `Gemfiles` destined for
48
48
  remote servers. *Very* helpful when you have OS-specific gems and are developing on one platform
49
- and deploying on another:
49
+ and deploying on another, or if you don't want to deal with the dependencies for your testing
50
+ frameworks:
50
51
 
51
52
  ``` erb
52
53
  <% no_deployment do %>
@@ -59,11 +60,15 @@ and deploying on another:
59
60
  when /linux/
60
61
  gem 'libnotify', :require => nil
61
62
  end
63
+
64
+ group :test do
65
+ # ... all your testing libraries you won't need on the deployed end ...
66
+ end
62
67
  <% end %>
63
68
  ```
64
69
 
65
70
  Run `penchant gemfile ENV --deployment` to get this behavior. This is run by default when the
66
- pre-commit git hook runs.
71
+ pre-commit git hook runs, but only after the default Rake task passes.
67
72
 
68
73
  ## initialize-environment
69
74
 
data/Rakefile CHANGED
@@ -9,5 +9,24 @@ rescue LoadError
9
9
  "#$! - no rspec"
10
10
  end
11
11
 
12
- task :default => :spec
12
+ begin
13
+ require 'rspec/core/rake_task'
14
+
15
+ RSpec::Core::RakeTask.new(:spec)
16
+ rescue LoadError
17
+ "#$! - no rspec"
18
+ end
19
+
20
+ begin
21
+ require 'cucumber'
22
+ require 'cucumber/rake/task'
23
+
24
+ Cucumber::Rake::Task.new(:cucumber) do |t|
25
+ t.cucumber_opts = "features --format pretty"
26
+ end
27
+ rescue LoadError
28
+ "#$! - no cucumber"
29
+ end
30
+
31
+ task :default => [ :spec, :cucumber ]
13
32
 
data/bin/penchant CHANGED
@@ -29,11 +29,19 @@ class PenchantCLI < Thor
29
29
  end
30
30
 
31
31
  method_options :deployment => false
32
+ method_options :switch_back => false
32
33
  desc "gemfile ENV", "Switch the gemfile environment, or rebuild the current environment if not given"
33
34
  def gemfile(env = get_current_env)
34
35
  if env
35
- puts "[penchant] Rebunding for #{env} environment#{options[:deployment] ? ", deployment mode" : ''}..."
36
- Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
36
+ if options[:switch_back]
37
+ puts "[penchant] Switching back, fallback: #{env}..."
38
+
39
+ Penchant::Gemfile.switch_back!(env)
40
+ else
41
+ puts "[penchant] Rebunding for #{env} environment#{options[:deployment] ? ", deployment mode" : ''}..."
42
+
43
+ Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
44
+ end
37
45
  end
38
46
 
39
47
  gemfile = Penchant::Gemfile.new
@@ -0,0 +1,18 @@
1
+ Feature: CLI
2
+ Scenario: Switch back to the original pre-deployment environment
3
+ Given I have the file "tmp/Gemfile.erb" with the content:
4
+ """
5
+ gem 'rake'
6
+ """
7
+ And I have the file "tmp/Gemfile" with the content:
8
+ """
9
+ # generated by penchant, environment: production, deployment mode (was local)
10
+ """
11
+ When I run "bin/penchant gemfile other --switch-back" in the "tmp" directory
12
+ Then the file "tmp/Gemfile" should have the following content:
13
+ """
14
+ # generated by penchant, environment: local
15
+ gem 'rake'
16
+ """
17
+ And the output should include "fallback: other"
18
+
@@ -0,0 +1,33 @@
1
+ @fakefs
2
+ Feature: Gemfiles
3
+ Scenario: When rebuilding for deployment, save the original state
4
+ Given I have the file "Gemfile.erb" with the content:
5
+ """
6
+ this is content
7
+ """
8
+ And I have the file "Gemfile" with the content:
9
+ """
10
+ # generated by penchant, environment: local
11
+ """
12
+ When I rebuild the Gemfile for "production" mode with deployment
13
+ Then the file "Gemfile" should have the following content:
14
+ """
15
+ # generated by penchant, environment: production, deployment mode (was local)
16
+ this is content
17
+ """
18
+
19
+ Scenario: When unbundling from deployment with an original state, switch to that state
20
+ Given I have the file "Gemfile.erb" with the content:
21
+ """
22
+ this is content
23
+ """
24
+ And I have the file "Gemfile" with the content:
25
+ """
26
+ # generated by penchant, environment: production, deployment mode (was local)
27
+ """
28
+ When I rebuild the Gemfile asking to switch back to the previous state
29
+ Then the file "Gemfile" should have the following content:
30
+ """
31
+ # generated by penchant, environment: local
32
+ this is content
33
+ """
@@ -0,0 +1,5 @@
1
+ Given /^I have the file "([^"]*)" with the content:$/ do |file, string|
2
+ FileUtils.mkdir_p File.dirname(file)
3
+
4
+ File.open(file, 'wb') { |fh| fh.print string }
5
+ end
@@ -0,0 +1,3 @@
1
+ Then /^the file "([^"]*)" should have the following content:$/ do |file, string|
2
+ File.read(file).should == string
3
+ end
@@ -0,0 +1,3 @@
1
+ Then /^the output should include "([^"]*)"$/ do |text|
2
+ @output.should include(text)
3
+ end
@@ -0,0 +1,3 @@
1
+ When /^I rebuild the Gemfile asking to switch back to the previous state$/ do
2
+ Penchant::Gemfile.switch_back!("remote")
3
+ end
@@ -0,0 +1,3 @@
1
+ When /^I rebuild the Gemfile for "([^"]*)" mode with deployment$/ do |env|
2
+ Penchant::Gemfile.do_full_env_switch!(env, true)
3
+ end
@@ -0,0 +1,3 @@
1
+ When /^I run "([^"]*)" in the "([^"]*)" directory$/ do |command, dir|
2
+ @output = %x{bash -c 'opwd=$PWD; cd #{dir} && $opwd/#{command}'}
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'fakefs/safe'
2
+ require 'penchant'
3
+
4
+ Before('@fakefs') do
5
+ FakeFS.activate!
6
+ end
7
+
8
+ After do
9
+ FakeFS.deactivate!
10
+
11
+ FileUtils.rm_rf 'tmp'
12
+ end
13
+
@@ -2,21 +2,30 @@ require 'erb'
2
2
 
3
3
  module Penchant
4
4
  class Gemfile
5
- attr_reader :path
5
+ attr_reader :path, :is_deployment
6
6
 
7
- class << self
8
- def do_full_env_switch!(env, deployment = false)
9
- gemfile = Penchant::Gemfile.new
10
- gemfile.run_dot_penchant!(env, deployment)
7
+ def self.do_full_env_switch!(env, deployment = false)
8
+ return false if !(gemfile = pre_switch(env, deployment))
11
9
 
12
- if !gemfile.has_gemfile_erb?
13
- return false
14
- end
10
+ gemfile.switch_to!(env, deployment)
11
+ end
15
12
 
16
- gemfile.switch_to!(env, deployment)
17
- end
13
+ def self.switch_back!(fallback_env)
14
+ return false if !(gemfile = pre_switch(fallback_env))
15
+
16
+ gemfile.switch_back!(fallback_env)
17
+ end
18
+
19
+ def self.pre_switch(env, deployment = false)
20
+ gemfile = Penchant::Gemfile.new
21
+ return false if !gemfile.has_gemfile_erb?
22
+ gemfile.run_dot_penchant!(env, deployment)
23
+
24
+ gemfile
18
25
  end
19
26
 
27
+ def current_env ; @env ; end
28
+
20
29
  def initialize(path = Dir.pwd)
21
30
  @path = path
22
31
  end
@@ -26,7 +35,7 @@ module Penchant
26
35
  end
27
36
 
28
37
  def has_gemfile?
29
- File.file?('Gemfile')
38
+ File.file?(gemfile_path)
30
39
  end
31
40
 
32
41
  def has_dot_penchant?
@@ -42,33 +51,52 @@ module Penchant
42
51
  end
43
52
 
44
53
  def environment
45
- File.readlines(gemfile_path).first.strip[%r{environment: ([^, ]*)}, 1]
54
+ gemfile_header.strip[%r{environment: ([^, ]*)}, 1]
46
55
  end
47
56
 
48
57
  def deployment?
49
- File.readlines(gemfile_path).first['deployment mode'] != nil
58
+ gemfile_header['deployment mode'] != nil
50
59
  end
51
60
 
52
61
  def switch_to!(gemfile_env = nil, deployment = false)
53
62
  @env, @is_deployment = gemfile_env, deployment
54
- template = File.read(gemfile_erb_path)
55
63
 
56
- File.open(gemfile_path, 'wb') do |fh|
57
- fh.puts "# generated by penchant, environment: #{@env || "none"}#{@is_deployment ? " , deployment mode" : ""}"
64
+ output = [ header, ERB.new(template).result(binding) ]
58
65
 
59
- fh.print ERB.new(template).result(binding)
60
- end
66
+ File.open(gemfile_path, 'wb') { |fh| fh.print output.join("\n") }
61
67
  end
62
68
 
63
69
  def run_dot_penchant!(env, deployment)
64
70
  DotPenchant.run(env || environment, deployment) if has_dot_penchant?
65
71
  end
66
72
 
73
+ def header
74
+ header = [ "# generated by penchant, environment: #{current_env}" ]
75
+
76
+ if is_deployment
77
+ header << ", deployment mode (was #{environment})"
78
+ end
79
+
80
+ header.join
81
+ end
82
+
83
+ def prior_environment
84
+ gemfile_header[%r{\(was (.+)\)}, 1]
85
+ end
86
+
87
+ def switch_back!(fallback_env)
88
+ switch_to!(prior_environment || fallback_env)
89
+ end
90
+
67
91
  private
68
92
  def file_in_path(file)
69
93
  File.join(@path, file)
70
94
  end
71
95
 
96
+ def template
97
+ File.read(gemfile_erb_path)
98
+ end
99
+
72
100
  def env(check, &block)
73
101
  instance_eval(&block) if check.to_s == @env.to_s
74
102
  end
@@ -76,6 +104,10 @@ module Penchant
76
104
  def no_deployment(&block)
77
105
  instance_eval(&block) if !@is_deployment
78
106
  end
107
+
108
+ def gemfile_header
109
+ (has_gemfile? and File.readlines(gemfile_path).first) or ""
110
+ end
79
111
  end
80
112
  end
81
113
 
@@ -1,3 +1,3 @@
1
1
  module Penchant
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -10,6 +10,8 @@ describe Penchant::Gemfile do
10
10
  let(:gemfile_erb_path) { File.join(dir, 'Gemfile.erb') }
11
11
 
12
12
  def write_file(path, content = nil)
13
+ FileUtils.mkdir_p(File.dirname(path))
14
+
13
15
  File.open(path, 'wb') do |fh|
14
16
  content = yield if block_given?
15
17
  fh.print content
@@ -146,5 +148,149 @@ ERB
146
148
  end
147
149
  end
148
150
  end
151
+
152
+ describe '#switch_to!' do
153
+ let(:template) { 'template' }
154
+ let(:gemfile_path) { 'gemfile path' }
155
+ let(:header) { 'header' }
156
+
157
+ let(:gemfile_out) { File.read(gemfile_path) }
158
+
159
+ before do
160
+ gemfile.stubs(:template).returns(template)
161
+ gemfile.stubs(:gemfile_path).returns(gemfile_path)
162
+
163
+ gemfile.expects(:header).returns(header)
164
+ end
165
+
166
+ it 'should write out the new gemfile' do
167
+ gemfile.switch_to!
168
+
169
+ gemfile_out.should include(template)
170
+ gemfile_out.should include(header)
171
+ end
172
+ end
173
+
174
+ describe '#header' do
175
+ subject { gemfile.header }
176
+
177
+ let(:env) { 'env' }
178
+ let(:prior_environment) { 'prior' }
179
+
180
+ before do
181
+ gemfile.stubs(:current_env).returns(env)
182
+ gemfile.stubs(:environment).returns(prior_environment)
183
+ end
184
+
185
+ context 'not deployment' do
186
+ before do
187
+ gemfile.stubs(:is_deployment).returns(false)
188
+ end
189
+
190
+ it { should == "# generated by penchant, environment: #{env}" }
191
+ end
192
+
193
+ context 'deployment' do
194
+ before do
195
+ gemfile.stubs(:is_deployment).returns(true)
196
+ end
197
+
198
+ it { should == "# generated by penchant, environment: #{env}, deployment mode (was #{prior_environment})" }
199
+ end
200
+ end
201
+
202
+ describe '#prior_environment' do
203
+ subject { gemfile.prior_environment }
204
+
205
+ let(:prior) { 'prior' }
206
+
207
+ before do
208
+ gemfile.stubs(:gemfile_header).returns("# header (was #{prior})")
209
+ end
210
+
211
+ it { should == prior }
212
+ end
213
+
214
+ describe '.switch_back!' do
215
+ let(:gemfile) { stub }
216
+ let(:fallback_env) { 'env' }
217
+
218
+ context 'pre_switch fails' do
219
+ before do
220
+ described_class.stubs(:pre_switch).returns(false)
221
+
222
+ gemfile.expects(:switch_back!).never
223
+ end
224
+
225
+ it 'should not switch back' do
226
+ described_class.switch_back!(fallback_env).should be_false
227
+ end
228
+ end
229
+
230
+ context 'pre_switch succeeds' do
231
+ before do
232
+ described_class.stubs(:pre_switch).returns(gemfile)
233
+
234
+ gemfile.expects(:switch_back!).with(fallback_env)
235
+ end
236
+
237
+ it 'should switch back' do
238
+ described_class.switch_back!(fallback_env)
239
+ end
240
+ end
241
+ end
242
+
243
+ describe '.pre_switch' do
244
+ subject { described_class.pre_switch(env, deployment) }
245
+
246
+ let(:env) { 'env' }
247
+ let(:deployment) { 'deployment' }
248
+
249
+ context 'no Gemfile.erb' do
250
+ before do
251
+ described_class.any_instance.expects(:has_gemfile_erb?).returns(false)
252
+ end
253
+
254
+ it { should be_false }
255
+ end
256
+
257
+ context 'Gemfile.erb' do
258
+ before do
259
+ described_class.any_instance.expects(:has_gemfile_erb?).returns(true)
260
+ described_class.any_instance.expects(:run_dot_penchant!).with(env, deployment)
261
+ end
262
+
263
+ it { should be_a_kind_of(described_class) }
264
+ end
265
+ end
266
+
267
+ describe '#switch_back!' do
268
+ let(:fallback_env) { 'fallback' }
269
+ let(:prior) { 'prior' }
270
+
271
+ context 'no prior' do
272
+ before do
273
+ gemfile.stubs(:prior_environment).returns(nil)
274
+
275
+ gemfile.expects(:switch_to!).with(fallback_env)
276
+ end
277
+
278
+ it 'should proxy through to switch_to!' do
279
+ gemfile.switch_back!(fallback_env)
280
+ end
281
+ end
282
+
283
+ context 'prior' do
284
+ before do
285
+ gemfile.stubs(:prior_environment).returns(prior)
286
+
287
+ gemfile.expects(:switch_to!).with(prior)
288
+ end
289
+
290
+ it 'should proxy through to switch_to!' do
291
+ gemfile.switch_back!(fallback_env)
292
+ end
293
+ end
294
+ end
149
295
  end
150
296
 
@@ -1,4 +1,4 @@
1
1
  #!/bin/bash
2
2
 
3
- penchant gemfile remote
3
+ penchant gemfile remote --switch-back
4
4
 
@@ -2,6 +2,14 @@
2
2
 
3
3
  OLD_GIT_DIR=$GIT_DIR
4
4
 
5
+ if [ "$(penchant gemfile-env)" != "remote" ]; then
6
+ penchant gemfile remote
7
+ fi
8
+
9
+ bundle exec rake
10
+ R=$?
11
+ if [ $R -ne 0 ]; then exit $R; fi
12
+
5
13
  if [ "$(penchant gemfile-env)" != "remote deployment" ]; then
6
14
  unset GIT_DIR
7
15
  penchant gemfile remote --deployment
@@ -9,7 +17,3 @@ if [ "$(penchant gemfile-env)" != "remote deployment" ]; then
9
17
  git add Gemfile*
10
18
  fi
11
19
 
12
- bundle exec rake
13
- R=$?
14
- if [ $R -ne 0 ]; then exit $R; fi
15
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: penchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-13 00:00:00.000000000Z
12
+ date: 2012-04-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Things I do for my Rails projects to get up to speed in new environments
15
15
  fast
@@ -26,6 +26,15 @@ files:
26
26
  - README.md
27
27
  - Rakefile
28
28
  - bin/penchant
29
+ - features/cli.feature
30
+ - features/gemfile.feature
31
+ - features/step_definitions/given/i_have_the_file_with_content.rb
32
+ - features/step_definitions/then/the_file_should_have_content.rb
33
+ - features/step_definitions/then/the_output_should_include.rb
34
+ - features/step_definitions/when/i_rebuild_the_gemfile_switching_back.rb
35
+ - features/step_definitions/when/i_rebuild_the_gemfile_with_deployment.rb
36
+ - features/step_definitions/when/i_run_in.rb
37
+ - features/support/env.rb
29
38
  - lib/penchant.rb
30
39
  - lib/penchant/dot_penchant.rb
31
40
  - lib/penchant/gemfile.rb
@@ -56,12 +65,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
65
  - - ! '>='
57
66
  - !ruby/object:Gem::Version
58
67
  version: '0'
68
+ segments:
69
+ - 0
70
+ hash: 3149014216967544178
59
71
  required_rubygems_version: !ruby/object:Gem::Requirement
60
72
  none: false
61
73
  requirements:
62
74
  - - ! '>='
63
75
  - !ruby/object:Gem::Version
64
76
  version: '0'
77
+ segments:
78
+ - 0
79
+ hash: 3149014216967544178
65
80
  requirements: []
66
81
  rubyforge_project: penchant
67
82
  rubygems_version: 1.8.11
@@ -70,6 +85,15 @@ specification_version: 3
70
85
  summary: Things I do for my Rails projects to get up to speed in new environments
71
86
  fast
72
87
  test_files:
88
+ - features/cli.feature
89
+ - features/gemfile.feature
90
+ - features/step_definitions/given/i_have_the_file_with_content.rb
91
+ - features/step_definitions/then/the_file_should_have_content.rb
92
+ - features/step_definitions/then/the_output_should_include.rb
93
+ - features/step_definitions/when/i_rebuild_the_gemfile_switching_back.rb
94
+ - features/step_definitions/when/i_rebuild_the_gemfile_with_deployment.rb
95
+ - features/step_definitions/when/i_run_in.rb
96
+ - features/support/env.rb
73
97
  - spec/lib/penchant/dot_penchant_spec.rb
74
98
  - spec/lib/penchant/gemfile_spec.rb
75
99
  - spec/lib/penchant_spec.rb