diff --git a/features/stage_failure.feature b/features/stage_failure.feature new file mode 100644 index 00000000..9201f2b7 --- /dev/null +++ b/features/stage_failure.feature @@ -0,0 +1,9 @@ +Feature: Stage failure + + Background: + Given a test app with the default configuration + And a stage file named deploy.rb + + Scenario: Running a task + When I run cap "doctor" + Then the task fails diff --git a/features/step_definitions/setup.rb b/features/step_definitions/setup.rb index a733813d..e1b7e5a5 100644 --- a/features/step_definitions/setup.rb +++ b/features/step_definitions/setup.rb @@ -52,3 +52,7 @@ Given(/^a custom task to run in the event of a failure$/) do safely_remove_file(TestApp.shared_path.join("failed")) TestApp.copy_task_to_test_app("spec/support/tasks/failed.rake") end + +Given(/^a stage file named (.+)$/) do |filename| + TestApp.write_local_stage_file(filename) +end diff --git a/lib/capistrano/dsl/stages.rb b/lib/capistrano/dsl/stages.rb index 57c9dcc9..18dd91c9 100644 --- a/lib/capistrano/dsl/stages.rb +++ b/lib/capistrano/dsl/stages.rb @@ -1,8 +1,13 @@ module Capistrano module DSL module Stages + RESERVED_NAMES = %w(deploy doctor install).freeze + private_constant :RESERVED_NAMES + def stages - Dir[stage_definitions].map { |f| File.basename(f, ".rb") } + names = Dir[stage_definitions].map { |f| File.basename(f, ".rb") } + assert_valid_stage_names(names) + names end def stage_definitions @@ -12,6 +17,15 @@ module Capistrano def stage_set? !!fetch(:stage, false) end + + private + + def assert_valid_stage_names(names) + invalid = names.find { |n| RESERVED_NAMES.include?(n) } + return if invalid.nil? + + raise t("error.invalid_stage_name", name: invalid, path: stage_config_path.join("#{invalid}.rb")) + end end end end diff --git a/lib/capistrano/i18n.rb b/lib/capistrano/i18n.rb index c18cef5f..eb0a7db5 100644 --- a/lib/capistrano/i18n.rb +++ b/lib/capistrano/i18n.rb @@ -24,6 +24,7 @@ en = { bye: "bye" }, error: { + invalid_stage_name: '"%{name}" is a reserved word and cannot be used as a stage. Rename "%{path}" to something else.', user: { does_not_exist: "User %{user} does not exists", cannot_switch: "Cannot switch to user %{user}" diff --git a/spec/support/test_app.rb b/spec/support/test_app.rb index ef0acbc6..299fe501 100644 --- a/spec/support/test_app.rb +++ b/spec/support/test_app.rb @@ -61,6 +61,12 @@ module TestApp end end + def write_local_stage_file(filename, config=nil) + File.open(test_app_path.join("config/deploy/#{filename}"), "w") do |file| + file.write(config) if config + end + end + def append_to_deploy_file(config) File.open(test_stage_path, "a") do |file| file.write config + "\n"