diff --git a/README.md b/README.md index 7b362a03..9ec7b3c1 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,9 @@ TODO: - [x] support set/fetch/role configuration - [x] basic deploy + - [x] ask - [ ] support existing significant configuration variables - - [ ] ask + - [ ] prefer `roles(:all)` over `all_roles` - [ ] support primary servers `on primary(:db)` - [ ] basic rollback - [ ] add examples to README @@ -66,12 +67,13 @@ To create different stages: ## Configuration # config/deploy.rb - set :application, 'example app' # config/deploy/production.rb - set :stage, :production + + ask :branch, :master + role :app, %w{example.com} role :web, %w{example.com} role :db, %w{example.com} diff --git a/lib/capistrano/configuration.rb b/lib/capistrano/configuration.rb index 980995d7..cc10cf3f 100644 --- a/lib/capistrano/configuration.rb +++ b/lib/capistrano/configuration.rb @@ -7,15 +7,21 @@ module Capistrano end end + def ask(key, default=nil) + question = Question.new(self, key, default) + set(key, question) + end + def set(key, value) config[key] = value end def fetch(key, default=nil, &block) - if block_given? - config.fetch(key, &block) + value = fetch_for(key, default, &block) + if value.respond_to?(:call) + set(key, value.call) else - config.fetch(key, default) + value end end @@ -55,6 +61,55 @@ module Capistrano @config ||= Hash.new end + def fetch_for(key, default, &block) + if block_given? + config.fetch(key, &block) + else + config.fetch(key, default) + end + end + + class Question + + def initialize(env, key, default) + @env, @key, @default = env, key, default + end + + def call + ask_question + save_response + end + + private + attr_reader :env, :key, :default + + def ask_question + $stdout.puts question + end + + def save_response + env.set(key, value) + end + + def value + if response.empty? + default + else + response + end + end + + def response + @response ||= $stdin.gets.chomp + end + + def set(key, value) + end + + def question + I18n.t(:question, key: key, default_value: default, scope: :capistrano) + end + end class Roles include Enumerable diff --git a/lib/capistrano/dsl/env.rb b/lib/capistrano/dsl/env.rb index 8092488e..613d4092 100644 --- a/lib/capistrano/dsl/env.rb +++ b/lib/capistrano/dsl/env.rb @@ -14,6 +14,10 @@ module Capistrano env.set(key, value) end + def ask(key, value) + env.ask(key, value) + end + def role(name, servers) env.role(name, servers) end diff --git a/lib/capistrano/i18n.rb b/lib/capistrano/i18n.rb index ca6af225..43ad2737 100644 --- a/lib/capistrano/i18n.rb +++ b/lib/capistrano/i18n.rb @@ -11,6 +11,7 @@ en = { finished: 'Finished', stage_not_set: 'Stage not set', written_file: 'create %{file}', + question: 'Please enter %{key}: |%{default_value}|', console: { welcome: 'capistrano console - enter command to execute on %{stage}', bye: 'bye' diff --git a/lib/capistrano/templates/deploy.rb.erb b/lib/capistrano/templates/deploy.rb.erb index 0baea08a..6e500bba 100644 --- a/lib/capistrano/templates/deploy.rb.erb +++ b/lib/capistrano/templates/deploy.rb.erb @@ -4,8 +4,7 @@ set :deploy_to, '/var/www/my_app' set :scm, :git set :repo, 'git@example.com:me/my_repo.git' -set :migrations, :migrate -set :branch, :master +ask :branch, :master set :linked_files, %w{config/database.yml} set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} diff --git a/spec/lib/capistrano/configuration_spec.rb b/spec/lib/capistrano/configuration_spec.rb index 31589667..ec9d664e 100644 --- a/spec/lib/capistrano/configuration_spec.rb +++ b/spec/lib/capistrano/configuration_spec.rb @@ -98,10 +98,69 @@ module Capistrano end context 'block is passed' do - subject { config.fetch(:key, :default) { :block } } + subject { config.fetch(:key, :default) { fail 'we need this!' } } it 'returns the block value' do - expect(subject).to eq :block + expect { subject }.to raise_error + end + end + end + + describe 'asking' do + let(:question) { stub } + + before do + Configuration::Question.expects(:new).with(config, :branch, :default). + returns(question) + end + + it 'prompts for the value when fetching' do + config.ask(:branch, :default) + expect(config.fetch(:branch)).to eq question + end + end + end + + describe Configuration::Question do + let(:question) { Configuration::Question.new(env, key, default) } + let(:default) { :default } + let(:key) { :branch } + let(:env) { stub } + + describe '.new' do + it 'takes a key, default' do + question + end + end + + describe '#call' do + subject { question.call } + + context 'value is entered' do + let(:branch) { 'branch' } + + before do + $stdout.expects(:puts).with('Please enter branch: |default|') + $stdin.expects(:gets).returns(branch) + end + + it 'sets the value' do + env.expects(:set).with(key, branch) + question.call + end + end + + context 'value is not entered' do + let(:branch) { default } + + before do + $stdout.expects(:puts).with('Please enter branch: |default|') + $stdin.expects(:gets).returns('') + end + + it 'sets the default as the value' do + env.expects(:set).with(key, branch) + question.call end end end