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'
|
||||||
gem 'guard-rspec'
|
gem 'guard-rspec'
|
||||||
|
gem 'guard-cucumber'
|
||||||
|
|
||||||
gem 'mocha'
|
gem 'mocha'
|
||||||
gem 'fakefs'
|
gem 'fakefs'
|
||||||
gem 'rspec', '~> 2.6.0'
|
gem 'rspec', '~> 2.6.0'
|
||||||
gem 'rake'
|
gem 'rake'
|
||||||
|
|
||||||
|
gem 'cucumber'
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
# A sample Guardfile
|
# A sample Guardfile
|
||||||
# More info at https://github.com/guard/guard#readme
|
# More info at https://github.com/guard/guard#readme
|
||||||
|
|
||||||
|
group :rspec do
|
||||||
guard 'rspec', :cli => '-c', :version => 2 do
|
guard 'rspec', :cli => '-c', :version => 2 do
|
||||||
watch(%r{^spec/.+_spec\.rb$})
|
watch(%r{^spec/.+_spec\.rb$})
|
||||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
||||||
watch('spec/spec_helper.rb') { "spec" }
|
watch('spec/spec_helper.rb') { "spec" }
|
||||||
end
|
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"
|
"#$! - no rspec"
|
||||||
end
|
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 ]
|
||||||
|
|
||||||
|
@ -29,12 +29,20 @@ class PenchantCLI < Thor
|
|||||||
end
|
end
|
||||||
|
|
||||||
method_options :deployment => false
|
method_options :deployment => false
|
||||||
|
method_options :switch_back => false
|
||||||
desc "gemfile ENV", "Switch the gemfile environment, or rebuild the current environment if not given"
|
desc "gemfile ENV", "Switch the gemfile environment, or rebuild the current environment if not given"
|
||||||
def gemfile(env = get_current_env)
|
def gemfile(env = get_current_env)
|
||||||
if env
|
if env
|
||||||
|
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" : ''}..."
|
puts "[penchant] Rebunding for #{env} environment#{options[:deployment] ? ", deployment mode" : ''}..."
|
||||||
|
|
||||||
Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
|
Penchant::Gemfile.do_full_env_switch!(env, options[:deployment])
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
gemfile = Penchant::Gemfile.new
|
gemfile = Penchant::Gemfile.new
|
||||||
if !gemfile.has_gemfile?
|
if !gemfile.has_gemfile?
|
||||||
|
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
|
module Penchant
|
||||||
class Gemfile
|
class Gemfile
|
||||||
attr_reader :path
|
attr_reader :path, :is_deployment
|
||||||
|
|
||||||
class << self
|
def self.do_full_env_switch!(env, deployment = false)
|
||||||
def do_full_env_switch!(env, deployment = false)
|
return false if !(gemfile = pre_switch(env, deployment))
|
||||||
gemfile = Penchant::Gemfile.new
|
|
||||||
gemfile.run_dot_penchant!(env, deployment)
|
|
||||||
|
|
||||||
if !gemfile.has_gemfile_erb?
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
gemfile.switch_to!(env, deployment)
|
gemfile.switch_to!(env, deployment)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.switch_back!(fallback_env)
|
||||||
|
return false if !(gemfile = pre_switch(fallback_env))
|
||||||
|
|
||||||
|
gemfile.switch_back!(fallback_env)
|
||||||
end
|
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)
|
def initialize(path = Dir.pwd)
|
||||||
@path = path
|
@path = path
|
||||||
end
|
end
|
||||||
@ -26,7 +35,7 @@ module Penchant
|
|||||||
end
|
end
|
||||||
|
|
||||||
def has_gemfile?
|
def has_gemfile?
|
||||||
File.file?('Gemfile')
|
File.file?(gemfile_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_dot_penchant?
|
def has_dot_penchant?
|
||||||
@ -42,33 +51,52 @@ module Penchant
|
|||||||
end
|
end
|
||||||
|
|
||||||
def environment
|
def environment
|
||||||
File.readlines(gemfile_path).first.strip[%r{environment: ([^, ]*)}, 1]
|
gemfile_header.strip[%r{environment: ([^, ]*)}, 1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def deployment?
|
def deployment?
|
||||||
File.readlines(gemfile_path).first['deployment mode'] != nil
|
gemfile_header['deployment mode'] != nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def switch_to!(gemfile_env = nil, deployment = false)
|
def switch_to!(gemfile_env = nil, deployment = false)
|
||||||
@env, @is_deployment = gemfile_env, deployment
|
@env, @is_deployment = gemfile_env, deployment
|
||||||
template = File.read(gemfile_erb_path)
|
|
||||||
|
|
||||||
File.open(gemfile_path, 'wb') do |fh|
|
output = [ header, ERB.new(template).result(binding) ]
|
||||||
fh.puts "# generated by penchant, environment: #{@env || "none"}#{@is_deployment ? " , deployment mode" : ""}"
|
|
||||||
|
|
||||||
fh.print ERB.new(template).result(binding)
|
File.open(gemfile_path, 'wb') { |fh| fh.print output.join("\n") }
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_dot_penchant!(env, deployment)
|
def run_dot_penchant!(env, deployment)
|
||||||
DotPenchant.run(env || environment, deployment) if has_dot_penchant?
|
DotPenchant.run(env || environment, deployment) if has_dot_penchant?
|
||||||
end
|
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
|
private
|
||||||
def file_in_path(file)
|
def file_in_path(file)
|
||||||
File.join(@path, file)
|
File.join(@path, file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def template
|
||||||
|
File.read(gemfile_erb_path)
|
||||||
|
end
|
||||||
|
|
||||||
def env(check, &block)
|
def env(check, &block)
|
||||||
instance_eval(&block) if check.to_s == @env.to_s
|
instance_eval(&block) if check.to_s == @env.to_s
|
||||||
end
|
end
|
||||||
@ -76,6 +104,10 @@ module Penchant
|
|||||||
def no_deployment(&block)
|
def no_deployment(&block)
|
||||||
instance_eval(&block) if !@is_deployment
|
instance_eval(&block) if !@is_deployment
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gemfile_header
|
||||||
|
(has_gemfile? and File.readlines(gemfile_path).first) or ""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,5 +146,149 @@ ERB
|
|||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
penchant gemfile remote
|
penchant gemfile remote --switch-back
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user