From dd42150ddb21166fd78dff5dbc5c2e58b12eea94 Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sun, 19 Mar 2017 19:47:01 -0700 Subject: [PATCH 1/3] Invoke `bundle` correctly within feature tests During the feature tests we create a separate directory with its own `Gemfile` and use `bundle` and `bundle exec` within that directory. However if `bundle exec` was used to run the feature tests, then a bundler environment is already loaded, and so the test Gemfile is never consulted. Running `bundle` doesn't have the desired effect, because the child process inherits the bundler environment variables from the parent process. Bundler's solution for this problem is the `Bundle.with_clean_env` method. This ensures that the child process doesn't inherit the parent's bundler environment. --- spec/support/test_app.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/spec/support/test_app.rb b/spec/support/test_app.rb index ac1e5071..2bdf37ba 100644 --- a/spec/support/test_app.rb +++ b/spec/support/test_app.rb @@ -44,14 +44,14 @@ module TestApp end Dir.chdir(test_app_path) do - `bundle` + run "bundle" end end def install_test_app_with(config) create_test_app Dir.chdir(test_app_path) do - `bundle exec cap install STAGES=#{stage}` + run "cap install STAGES=#{stage}" end write_local_deploy_file(config) end @@ -91,14 +91,15 @@ module TestApp end def cap(task, subdirectory=nil) - run "bundle exec cap #{stage} #{task}", subdirectory + run "cap #{stage} #{task} --trace", subdirectory end def run(command, subdirectory=nil) output = nil + command = "bundle exec #{command}" unless command =~ /^bundle\b/ dir = subdirectory ? test_app_path.join(subdirectory) : test_app_path Dir.chdir(dir) do - output = `#{command}` + output = with_clean_bundler_env { `#{command}` } end [$CHILD_STATUS.success?, output] end @@ -187,4 +188,9 @@ module TestApp def git_wrapper_path "/tmp/git-ssh-my_app_name-#{stage}-#{current_user}.sh" end + + def with_clean_bundler_env(&block) + return yield unless defined?(Bundler) + Bundler.with_clean_env(&block) + end end From 84407c63a7aac67a2b8608f88a6a5a05fe70fbc7 Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sun, 19 Mar 2017 19:58:09 -0700 Subject: [PATCH 2/3] Use empty app as background for cap install tests Previously, a fully-configured app was used as the background for the `cap install` feature tests. This somewhat defeated the purpose of these tests, because `cap install` is supposed to be run on a project that hasn't yet been "capified". --- features/installation.feature | 6 +++--- features/step_definitions/setup.rb | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/features/installation.feature b/features/installation.feature index 20d23296..60fca09c 100644 --- a/features/installation.feature +++ b/features/installation.feature @@ -1,16 +1,16 @@ Feature: Installation Background: - Given a test app with the default configuration + Given a test app without any configuration Scenario: With default stages - When I run cap "install" + When I run "cap install" Then the deploy.rb file is created And the default stage files are created And the tasks folder is created Scenario: With specified stages - When I run cap "install STAGES=qa,production" + When I run "cap install STAGES=qa,production" Then the deploy.rb file is created And the specified stage files are created And the tasks folder is created diff --git a/features/step_definitions/setup.rb b/features/step_definitions/setup.rb index e1b7e5a5..69b2b9a6 100644 --- a/features/step_definitions/setup.rb +++ b/features/step_definitions/setup.rb @@ -2,6 +2,10 @@ Given(/^a test app with the default configuration$/) do TestApp.install end +Given(/^a test app without any configuration$/) do + TestApp.create_test_app +end + Given(/^servers with the roles app and web$/) do begin vagrant_cli_command("up") From 27a8fbe8efe2fb3970574eb016f731e2017365be Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sun, 19 Mar 2017 20:02:38 -0700 Subject: [PATCH 3/3] Allow `cap -T` to work when no Capfile is present Previously, the `cap -T` command assumed the presence of the `load:defaults` task. This task is only present if a proper Capfile is loaded, and so `cap -T` wouldn't work in a new, not yet "capified" project. This commit fixes the bug by testing that `load:defaults` is defined before calling it. --- CHANGELOG.md | 1 + features/installation.feature | 5 +++++ lib/capistrano/application.rb | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff399936..70350769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ gem "capistrano", :github => "capistrano/capistrano" https://github.com/capistrano/capistrano/compare/v3.7.2...HEAD * Your contribution here! +* [#1867](https://github.com/capistrano/capistrano/pull/1867): Allow `cap -T` to run without Capfile present - [@mattbrictson](https://github.com/mattbrictson) ## `3.8.0` (2017-03-10) diff --git a/features/installation.feature b/features/installation.feature index 60fca09c..47574262 100644 --- a/features/installation.feature +++ b/features/installation.feature @@ -3,6 +3,11 @@ Feature: Installation Background: Given a test app without any configuration + Scenario: The "install" task documentation can be viewed + When I run "cap -T" + Then the task is successful + And contains "cap install" in the output + Scenario: With default stages When I run "cap install" Then the deploy.rb file is created diff --git a/lib/capistrano/application.rb b/lib/capistrano/application.rb index d1423e14..101a6090 100644 --- a/lib/capistrano/application.rb +++ b/lib/capistrano/application.rb @@ -96,7 +96,7 @@ module Capistrano end def load_imports - if options.show_tasks + if options.show_tasks && Rake::Task.task_defined?("load:defaults") invoke "load:defaults" set(:stage, "") Dir[deploy_config_path].each { |f| add_import f }