implement switching back to prior env on post-commit, should fix #2
This commit is contained in:
parent
9354fed2dc
commit
b30d56819e
4
Gemfile
4
Gemfile
@ -5,7 +5,11 @@ gemspec
|
||||
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
gem 'guard-cucumber'
|
||||
|
||||
gem 'mocha'
|
||||
gem 'fakefs'
|
||||
gem 'rspec', '~> 2.6.0'
|
||||
gem 'rake'
|
||||
|
||||
gem 'cucumber'
|
||||
|
17
Guardfile
17
Guardfile
@ -1,9 +1,18 @@
|
||||
# A sample Guardfile
|
||||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
guard 'rspec', :cli => '-c', :version => 2 do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
||||
watch('spec/spec_helper.rb') { "spec" }
|
||||
group :rspec do
|
||||
guard 'rspec', :cli => '-c', :version => 2 do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
||||
watch('spec/spec_helper.rb') { "spec" }
|
||||
end
|
||||
end
|
||||
|
||||
group :cucumber do
|
||||
guard 'cucumber' do
|
||||
watch(%r{^features/.+\.feature$})
|
||||
watch(%r{^features/support/.+$}) { 'features' }
|
||||
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
||||
end
|
||||
end
|
||||
|
21
Rakefile
21
Rakefile
@ -9,5 +9,24 @@ rescue LoadError
|
||||
"#$! - no rspec"
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
begin
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
rescue LoadError
|
||||
"#$! - no rspec"
|
||||
end
|
||||
|
||||
begin
|
||||
require 'cucumber'
|
||||
require 'cucumber/rake/task'
|
||||
|
||||
Cucumber::Rake::Task.new(:cucumber) do |t|
|
||||
t.cucumber_opts = "features --format pretty"
|
||||
end
|
||||
rescue LoadError
|
||||
"#$! - no cucumber"
|
||||
end
|
||||
|
||||
task :default => [ :spec, :cucumber ]
|
||||
|
||||
|
12
bin/penchant
12
bin/penchant
@ -29,11 +29,19 @@ class PenchantCLI < Thor
|
||||
end
|
||||
|
||||
method_options :deployment => false
|
||||
method_options :switch_back => false
|
||||
desc "gemfile ENV", "Switch the gemfile environment, or rebuild the current environment if not given"
|
||||
def gemfile(env = get_current_env)
|
||||
if env
|
||||
puts "[penchant] Rebunding for #{env} environment#{options[:deployment] ? ", deployment mode" : ''}..."
|
||||
Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
|
||||
if options[:switch_back]
|
||||
puts "[penchant] Switching back, fallback: #{env}..."
|
||||
|
||||
Penchant::Gemfile.switch_back!(env)
|
||||
else
|
||||
puts "[penchant] Rebunding for #{env} environment#{options[:deployment] ? ", deployment mode" : ''}..."
|
||||
|
||||
Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
|
||||
end
|
||||
end
|
||||
|
||||
gemfile = Penchant::Gemfile.new
|
||||
|
18
features/cli.feature
Normal file
18
features/cli.feature
Normal file
@ -0,0 +1,18 @@
|
||||
Feature: CLI
|
||||
Scenario: Switch back to the original pre-deployment environment
|
||||
Given I have the file "tmp/Gemfile.erb" with the content:
|
||||
"""
|
||||
gem 'rake'
|
||||
"""
|
||||
And I have the file "tmp/Gemfile" with the content:
|
||||
"""
|
||||
# generated by penchant, environment: production, deployment mode (was local)
|
||||
"""
|
||||
When I run "bin/penchant gemfile other --switch-back" in the "tmp" directory
|
||||
Then the file "tmp/Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
gem 'rake'
|
||||
"""
|
||||
And the output should include "fallback: other"
|
||||
|
33
features/gemfile.feature
Normal file
33
features/gemfile.feature
Normal file
@ -0,0 +1,33 @@
|
||||
@fakefs
|
||||
Feature: Gemfiles
|
||||
Scenario: When rebuilding for deployment, save the original state
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
this is content
|
||||
"""
|
||||
And I have the file "Gemfile" with the content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
"""
|
||||
When I rebuild the Gemfile for "production" mode with deployment
|
||||
Then the file "Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: production, deployment mode (was local)
|
||||
this is content
|
||||
"""
|
||||
|
||||
Scenario: When unbundling from deployment with an original state, switch to that state
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
this is content
|
||||
"""
|
||||
And I have the file "Gemfile" with the content:
|
||||
"""
|
||||
# generated by penchant, environment: production, deployment mode (was local)
|
||||
"""
|
||||
When I rebuild the Gemfile asking to switch back to the previous state
|
||||
Then the file "Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
this is content
|
||||
"""
|
@ -0,0 +1,5 @@
|
||||
Given /^I have the file "([^"]*)" with the content:$/ do |file, string|
|
||||
FileUtils.mkdir_p File.dirname(file)
|
||||
|
||||
File.open(file, 'wb') { |fh| fh.print string }
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
Then /^the file "([^"]*)" should have the following content:$/ do |file, string|
|
||||
File.read(file).should == string
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
Then /^the output should include "([^"]*)"$/ do |text|
|
||||
@output.should include(text)
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
When /^I rebuild the Gemfile asking to switch back to the previous state$/ do
|
||||
Penchant::Gemfile.switch_back!("remote")
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
When /^I rebuild the Gemfile for "([^"]*)" mode with deployment$/ do |env|
|
||||
Penchant::Gemfile.do_full_env_switch!(env, true)
|
||||
end
|
3
features/step_definitions/when/i_run_in.rb
Normal file
3
features/step_definitions/when/i_run_in.rb
Normal file
@ -0,0 +1,3 @@
|
||||
When /^I run "([^"]*)" in the "([^"]*)" directory$/ do |command, dir|
|
||||
@output = %x{bash -c 'opwd=$PWD; cd #{dir} && $opwd/#{command}'}
|
||||
end
|
13
features/support/env.rb
Normal file
13
features/support/env.rb
Normal file
@ -0,0 +1,13 @@
|
||||
require 'fakefs/safe'
|
||||
require 'penchant'
|
||||
|
||||
Before('@fakefs') do
|
||||
FakeFS.activate!
|
||||
end
|
||||
|
||||
After do
|
||||
FakeFS.deactivate!
|
||||
|
||||
FileUtils.rm_rf 'tmp'
|
||||
end
|
||||
|
@ -2,21 +2,30 @@ require 'erb'
|
||||
|
||||
module Penchant
|
||||
class Gemfile
|
||||
attr_reader :path
|
||||
attr_reader :path, :is_deployment
|
||||
|
||||
class << self
|
||||
def do_full_env_switch!(env, deployment = false)
|
||||
gemfile = Penchant::Gemfile.new
|
||||
gemfile.run_dot_penchant!(env, deployment)
|
||||
def self.do_full_env_switch!(env, deployment = false)
|
||||
return false if !(gemfile = pre_switch(env, deployment))
|
||||
|
||||
if !gemfile.has_gemfile_erb?
|
||||
return false
|
||||
end
|
||||
|
||||
gemfile.switch_to!(env, deployment)
|
||||
end
|
||||
gemfile.switch_to!(env, deployment)
|
||||
end
|
||||
|
||||
def self.switch_back!(fallback_env)
|
||||
return false if !(gemfile = pre_switch(fallback_env))
|
||||
|
||||
gemfile.switch_back!(fallback_env)
|
||||
end
|
||||
|
||||
def self.pre_switch(env, deployment = false)
|
||||
gemfile = Penchant::Gemfile.new
|
||||
return false if !gemfile.has_gemfile_erb?
|
||||
gemfile.run_dot_penchant!(env, deployment)
|
||||
|
||||
gemfile
|
||||
end
|
||||
|
||||
def current_env ; @env ; end
|
||||
|
||||
def initialize(path = Dir.pwd)
|
||||
@path = path
|
||||
end
|
||||
@ -26,7 +35,7 @@ module Penchant
|
||||
end
|
||||
|
||||
def has_gemfile?
|
||||
File.file?('Gemfile')
|
||||
File.file?(gemfile_path)
|
||||
end
|
||||
|
||||
def has_dot_penchant?
|
||||
@ -42,33 +51,52 @@ module Penchant
|
||||
end
|
||||
|
||||
def environment
|
||||
File.readlines(gemfile_path).first.strip[%r{environment: ([^, ]*)}, 1]
|
||||
gemfile_header.strip[%r{environment: ([^, ]*)}, 1]
|
||||
end
|
||||
|
||||
def deployment?
|
||||
File.readlines(gemfile_path).first['deployment mode'] != nil
|
||||
gemfile_header['deployment mode'] != nil
|
||||
end
|
||||
|
||||
def switch_to!(gemfile_env = nil, deployment = false)
|
||||
@env, @is_deployment = gemfile_env, deployment
|
||||
template = File.read(gemfile_erb_path)
|
||||
|
||||
File.open(gemfile_path, 'wb') do |fh|
|
||||
fh.puts "# generated by penchant, environment: #{@env || "none"}#{@is_deployment ? " , deployment mode" : ""}"
|
||||
output = [ header, ERB.new(template).result(binding) ]
|
||||
|
||||
fh.print ERB.new(template).result(binding)
|
||||
end
|
||||
File.open(gemfile_path, 'wb') { |fh| fh.print output.join("\n") }
|
||||
end
|
||||
|
||||
def run_dot_penchant!(env, deployment)
|
||||
DotPenchant.run(env || environment, deployment) if has_dot_penchant?
|
||||
end
|
||||
|
||||
def header
|
||||
header = [ "# generated by penchant, environment: #{current_env}" ]
|
||||
|
||||
if is_deployment
|
||||
header << ", deployment mode (was #{environment})"
|
||||
end
|
||||
|
||||
header.join
|
||||
end
|
||||
|
||||
def prior_environment
|
||||
gemfile_header[%r{\(was (.+)\)}, 1]
|
||||
end
|
||||
|
||||
def switch_back!(fallback_env)
|
||||
switch_to!(prior_environment || fallback_env)
|
||||
end
|
||||
|
||||
private
|
||||
def file_in_path(file)
|
||||
File.join(@path, file)
|
||||
end
|
||||
|
||||
def template
|
||||
File.read(gemfile_erb_path)
|
||||
end
|
||||
|
||||
def env(check, &block)
|
||||
instance_eval(&block) if check.to_s == @env.to_s
|
||||
end
|
||||
@ -76,6 +104,10 @@ module Penchant
|
||||
def no_deployment(&block)
|
||||
instance_eval(&block) if !@is_deployment
|
||||
end
|
||||
|
||||
def gemfile_header
|
||||
(has_gemfile? and File.readlines(gemfile_path).first) or ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -146,5 +146,149 @@ ERB
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#switch_to!' do
|
||||
let(:template) { 'template' }
|
||||
let(:gemfile_path) { 'gemfile path' }
|
||||
let(:header) { 'header' }
|
||||
|
||||
let(:gemfile_out) { File.read(gemfile_path) }
|
||||
|
||||
before do
|
||||
gemfile.stubs(:template).returns(template)
|
||||
gemfile.stubs(:gemfile_path).returns(gemfile_path)
|
||||
|
||||
gemfile.expects(:header).returns(header)
|
||||
end
|
||||
|
||||
it 'should write out the new gemfile' do
|
||||
gemfile.switch_to!
|
||||
|
||||
gemfile_out.should include(template)
|
||||
gemfile_out.should include(header)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#header' do
|
||||
subject { gemfile.header }
|
||||
|
||||
let(:env) { 'env' }
|
||||
let(:prior_environment) { 'prior' }
|
||||
|
||||
before do
|
||||
gemfile.stubs(:current_env).returns(env)
|
||||
gemfile.stubs(:environment).returns(prior_environment)
|
||||
end
|
||||
|
||||
context 'not deployment' do
|
||||
before do
|
||||
gemfile.stubs(:is_deployment).returns(false)
|
||||
end
|
||||
|
||||
it { should == "# generated by penchant, environment: #{env}" }
|
||||
end
|
||||
|
||||
context 'deployment' do
|
||||
before do
|
||||
gemfile.stubs(:is_deployment).returns(true)
|
||||
end
|
||||
|
||||
it { should == "# generated by penchant, environment: #{env}, deployment mode (was #{prior_environment})" }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prior_environment' do
|
||||
subject { gemfile.prior_environment }
|
||||
|
||||
let(:prior) { 'prior' }
|
||||
|
||||
before do
|
||||
gemfile.stubs(:gemfile_header).returns("# header (was #{prior})")
|
||||
end
|
||||
|
||||
it { should == prior }
|
||||
end
|
||||
|
||||
describe '.switch_back!' do
|
||||
let(:gemfile) { stub }
|
||||
let(:fallback_env) { 'env' }
|
||||
|
||||
context 'pre_switch fails' do
|
||||
before do
|
||||
described_class.stubs(:pre_switch).returns(false)
|
||||
|
||||
gemfile.expects(:switch_back!).never
|
||||
end
|
||||
|
||||
it 'should not switch back' do
|
||||
described_class.switch_back!(fallback_env).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
context 'pre_switch succeeds' do
|
||||
before do
|
||||
described_class.stubs(:pre_switch).returns(gemfile)
|
||||
|
||||
gemfile.expects(:switch_back!).with(fallback_env)
|
||||
end
|
||||
|
||||
it 'should switch back' do
|
||||
described_class.switch_back!(fallback_env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.pre_switch' do
|
||||
subject { described_class.pre_switch(env, deployment) }
|
||||
|
||||
let(:env) { 'env' }
|
||||
let(:deployment) { 'deployment' }
|
||||
|
||||
context 'no Gemfile.erb' do
|
||||
before do
|
||||
described_class.any_instance.expects(:has_gemfile_erb?).returns(false)
|
||||
end
|
||||
|
||||
it { should be_false }
|
||||
end
|
||||
|
||||
context 'Gemfile.erb' do
|
||||
before do
|
||||
described_class.any_instance.expects(:has_gemfile_erb?).returns(true)
|
||||
described_class.any_instance.expects(:run_dot_penchant!).with(env, deployment)
|
||||
end
|
||||
|
||||
it { should be_a_kind_of(described_class) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#switch_back!' do
|
||||
let(:fallback_env) { 'fallback' }
|
||||
let(:prior) { 'prior' }
|
||||
|
||||
context 'no prior' do
|
||||
before do
|
||||
gemfile.stubs(:prior_environment).returns(nil)
|
||||
|
||||
gemfile.expects(:switch_to!).with(fallback_env)
|
||||
end
|
||||
|
||||
it 'should proxy through to switch_to!' do
|
||||
gemfile.switch_back!(fallback_env)
|
||||
end
|
||||
end
|
||||
|
||||
context 'prior' do
|
||||
before do
|
||||
gemfile.stubs(:prior_environment).returns(prior)
|
||||
|
||||
gemfile.expects(:switch_to!).with(prior)
|
||||
end
|
||||
|
||||
it 'should proxy through to switch_to!' do
|
||||
gemfile.switch_back!(fallback_env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
penchant gemfile remote
|
||||
penchant gemfile remote --switch-back
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user