pulsar 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.hound.yml +3 -0
- data/.rubocop.yml +5 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -1
- data/README.md +4 -4
- data/Rakefile +3 -3
- data/lib/pulsar.rb +9 -8
- data/lib/pulsar/commands/all.rb +4 -4
- data/lib/pulsar/commands/init.rb +7 -5
- data/lib/pulsar/commands/main.rb +43 -32
- data/lib/pulsar/commands/utils.rb +7 -3
- data/lib/pulsar/generators/init_repo/apps/your_app/defaults.rb +1 -1
- data/lib/pulsar/generators/init_repo/apps/your_app/production.rb +2 -2
- data/lib/pulsar/generators/init_repo/apps/your_app/staging.rb +2 -2
- data/lib/pulsar/generators/init_repo/recipes/generic/cleanup.rb +9 -9
- data/lib/pulsar/generators/init_repo/recipes/generic/utils.rb +6 -3
- data/lib/pulsar/helpers/all.rb +7 -5
- data/lib/pulsar/helpers/capistrano.rb +4 -4
- data/lib/pulsar/helpers/clamp.rb +32 -33
- data/lib/pulsar/helpers/path.rb +15 -2
- data/lib/pulsar/helpers/shell.rb +3 -3
- data/lib/pulsar/options/all.rb +5 -3
- data/lib/pulsar/options/conf_repo.rb +17 -16
- data/lib/pulsar/options/shared.rb +3 -2
- data/lib/pulsar/version.rb +1 -1
- data/pulsar.gemspec +17 -17
- data/spec/pulsar/commands/init_spec.rb +4 -3
- data/spec/pulsar/commands/list_spec.rb +63 -47
- data/spec/pulsar/commands/main_spec.rb +175 -125
- data/spec/pulsar/commands/utils_spec.rb +13 -13
- data/spec/pulsar/helpers/capistrano_spec.rb +37 -31
- data/spec/pulsar/helpers/clamp_spec.rb +68 -37
- data/spec/pulsar/helpers/shell_spec.rb +3 -3
- data/spec/spec_helper.rb +12 -11
- data/spec/support/dummies/dummy_conf/Gemfile +1 -1
- data/spec/support/dummies/dummy_conf/apps/base.rb +5 -5
- data/spec/support/dummies/dummy_conf/apps/dummy_app/custom_stage.rb +2 -2
- data/spec/support/dummies/dummy_conf/apps/dummy_app/defaults.rb +1 -1
- data/spec/support/dummies/dummy_conf/apps/dummy_app/production.rb +2 -2
- data/spec/support/dummies/dummy_conf/apps/dummy_app/staging.rb +2 -2
- data/spec/support/dummies/dummy_conf/apps/other_dummy_app/custom_stage.rb +2 -2
- data/spec/support/dummies/dummy_conf/apps/other_dummy_app/defaults.rb +1 -1
- data/spec/support/dummies/dummy_conf/apps/other_dummy_app/production.rb +2 -2
- data/spec/support/dummies/dummy_conf/apps/other_dummy_app/staging.rb +2 -2
- data/spec/support/modules/helpers.rb +40 -35
- metadata +20 -17
data/lib/pulsar/helpers/path.rb
CHANGED
@@ -2,11 +2,11 @@ module Pulsar
|
|
2
2
|
module Helpers
|
3
3
|
module Path
|
4
4
|
def capfile_path
|
5
|
-
"#{
|
5
|
+
"#{tmp_path}/capfile-#{deploy_time}"
|
6
6
|
end
|
7
7
|
|
8
8
|
def config_path
|
9
|
-
"#{
|
9
|
+
"#{tmp_path}/conf-repo-#{setup_time}"
|
10
10
|
end
|
11
11
|
|
12
12
|
def config_app_path(app)
|
@@ -41,7 +41,20 @@ module Pulsar
|
|
41
41
|
clear_deploy_time
|
42
42
|
end
|
43
43
|
|
44
|
+
def home_path
|
45
|
+
home_dir
|
46
|
+
end
|
47
|
+
|
48
|
+
def bundle_path
|
49
|
+
File.join(home_path, 'bundle')
|
50
|
+
end
|
51
|
+
|
52
|
+
def tmp_path
|
53
|
+
File.join(home_path, 'tmp')
|
54
|
+
end
|
55
|
+
|
44
56
|
private
|
57
|
+
|
45
58
|
def clear_deploy_time
|
46
59
|
@deploy = nil
|
47
60
|
end
|
data/lib/pulsar/helpers/shell.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'fileutils'
|
2
2
|
|
3
3
|
module Pulsar
|
4
4
|
module Helpers
|
5
5
|
module Shell
|
6
6
|
include FileUtils
|
7
7
|
|
8
|
-
def cd(path, opts
|
8
|
+
def cd(path, opts)
|
9
9
|
puts "Directory: #{path.white}".yellow if opts[:verbose]
|
10
10
|
FileUtils.cd(path) { yield }
|
11
11
|
end
|
@@ -19,7 +19,7 @@ module Pulsar
|
|
19
19
|
puts "Command: #{cmd.white}".yellow if opts[:verbose]
|
20
20
|
system(cmd)
|
21
21
|
|
22
|
-
|
22
|
+
fail "Command #{cmd} Failed" if $? != 0
|
23
23
|
end
|
24
24
|
|
25
25
|
def touch(file, opts)
|
data/lib/pulsar/options/all.rb
CHANGED
@@ -2,26 +2,27 @@ module Pulsar
|
|
2
2
|
module Options
|
3
3
|
module ConfRepo
|
4
4
|
def self.included(base)
|
5
|
-
base.option [
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
base.option ['-c', '--conf-repo'], 'REPO URL',
|
6
|
+
'a git repository with deploy configurations, mainly apps and recipes',
|
7
|
+
environment_variable: 'PULSAR_CONF_REPO',
|
8
|
+
required: true
|
9
9
|
|
10
|
-
base.option [
|
11
|
-
|
12
|
-
|
10
|
+
base.option ['-k', '--keep-capfile'], :flag,
|
11
|
+
'don\'t remove the generated capfile in the TMP DIR directory',
|
12
|
+
default: false
|
13
13
|
|
14
|
-
base.option [
|
15
|
-
|
16
|
-
|
14
|
+
base.option ['-r', '--keep-repo'], :flag,
|
15
|
+
'don\'t remove the downloaded configuration repository from the TMP DIR directory',
|
16
|
+
default: false
|
17
17
|
|
18
|
-
base.option [
|
19
|
-
|
20
|
-
|
18
|
+
base.option ['-b', '--conf-branch'], 'REPO BRANCH',
|
19
|
+
'specify a branch for the configuration repository',
|
20
|
+
default: 'master'
|
21
21
|
|
22
|
-
base.option [
|
23
|
-
|
24
|
-
|
22
|
+
base.option ['-h', '--home-dir'], 'HOME DIR',
|
23
|
+
'a directory to store per-user state',
|
24
|
+
environment_variable: 'PULSAR_HOME',
|
25
|
+
default: File.join(Dir.home, '.pulsar')
|
25
26
|
end
|
26
27
|
|
27
28
|
#
|
@@ -2,12 +2,13 @@ module Pulsar
|
|
2
2
|
module Options
|
3
3
|
module Shared
|
4
4
|
def self.included(base)
|
5
|
-
base.option [
|
5
|
+
base.option ['-V', '--version'], :flag, 'print out pulsar version' do
|
6
6
|
puts(VERSION)
|
7
7
|
exit(0)
|
8
8
|
end
|
9
9
|
|
10
|
-
base.option [
|
10
|
+
base.option ['-v', '--verbose'], :flag,
|
11
|
+
'print out what pulsar is doing', default: false
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
data/lib/pulsar/version.rb
CHANGED
data/pulsar.gemspec
CHANGED
@@ -4,29 +4,29 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'pulsar/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
|
-
gem.name =
|
7
|
+
gem.name = 'pulsar'
|
8
8
|
gem.version = Pulsar::VERSION
|
9
|
-
gem.authors = [
|
10
|
-
gem.email = [
|
11
|
-
gem.
|
12
|
-
gem.
|
9
|
+
gem.authors = ['Alberto Vena', 'Matteo Latini']
|
10
|
+
gem.email = ['info@nebulab.it']
|
11
|
+
gem.homepage = 'http://pulsar.nebulab.it'
|
12
|
+
gem.description = 'Manage your Capistrano deployments with ease'
|
13
|
+
gem.summary = '
|
13
14
|
Pulsar helps with Capistrano configuration management. It uses a repository
|
14
15
|
to store all your precious configurations and recipes to build Capistrano
|
15
16
|
deploys on it.
|
16
|
-
|
17
|
-
gem.homepage = "http://pulsar.nebulab.it"
|
17
|
+
'
|
18
18
|
|
19
19
|
gem.files = `git ls-files`.split($/)
|
20
|
-
gem.executables = gem.files.grep(
|
21
|
-
gem.test_files = gem.files.grep(
|
22
|
-
gem.require_paths = [
|
20
|
+
gem.executables = gem.files.grep(/^bin\//).map { |f| File.basename(f) }
|
21
|
+
gem.test_files = gem.files.grep(/^(test|spec|features)\//)
|
22
|
+
gem.require_paths = ['lib']
|
23
23
|
|
24
|
-
gem.add_dependency
|
25
|
-
gem.add_dependency
|
26
|
-
gem.add_dependency
|
24
|
+
gem.add_dependency 'clamp', '~> 0.5'
|
25
|
+
gem.add_dependency 'bundler', '~> 1.2'
|
26
|
+
gem.add_dependency 'colored', '~> 1.2'
|
27
27
|
|
28
|
-
gem.add_development_dependency
|
29
|
-
gem.add_development_dependency
|
30
|
-
gem.add_development_dependency
|
31
|
-
gem.add_development_dependency
|
28
|
+
gem.add_development_dependency 'rake', '10.3.2'
|
29
|
+
gem.add_development_dependency 'rspec', '3.1.0'
|
30
|
+
gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.6'
|
31
|
+
gem.add_development_dependency 'rubocop', '~> 0.29.1'
|
32
32
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Pulsar::InitCommand do
|
4
|
-
let(:pulsar) { Pulsar::InitCommand.new(
|
4
|
+
let(:pulsar) { Pulsar::InitCommand.new('init') }
|
5
5
|
|
6
|
-
it
|
7
|
-
expect { pulsar.run(["#{
|
6
|
+
it 'copies over the configuration repo' do
|
7
|
+
expect { pulsar.run(["#{spec_tmp_path}/new-conf-repo"]) }
|
8
|
+
.to change { Dir.glob("#{spec_tmp_path}/new-conf-repo").length }.by(1)
|
8
9
|
end
|
9
10
|
end
|
@@ -1,74 +1,86 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Pulsar::ListCommand do
|
4
|
-
let(:pulsar) { Pulsar::ListCommand.new(
|
4
|
+
let(:pulsar) { Pulsar::ListCommand.new('list') }
|
5
5
|
|
6
|
-
it
|
7
|
-
expect { pulsar.run(full_list_args + %w(--keep-repo)) }
|
6
|
+
it 'copies a the repo over to temp directory' do
|
7
|
+
expect { pulsar.run(full_list_args + %w(--keep-repo)) }
|
8
|
+
.to change { Dir.glob("#{spec_tmp_path}/tmp/conf-repo*").length }.by(1)
|
8
9
|
end
|
9
10
|
|
10
|
-
it
|
11
|
-
system("mkdir #{
|
12
|
-
|
11
|
+
it 'copies a the repo when there is a dir with same name' do
|
12
|
+
system("mkdir -p #{spec_tmp_path}/conf-repo")
|
13
|
+
|
14
|
+
expect { pulsar.run(full_list_args + %w(--keep-repo)) }
|
15
|
+
.to change { Dir.glob("#{spec_tmp_path}/tmp/conf-repo*").length }.by(1)
|
13
16
|
end
|
14
17
|
|
15
|
-
it
|
16
|
-
Pulsar::ListCommand
|
17
|
-
|
18
|
+
it 'removes the temp directory even if it\'s raised an error' do
|
19
|
+
allow_any_instance_of(Pulsar::ListCommand)
|
20
|
+
.to receive(:list_apps) { fail('error') }
|
18
21
|
|
19
|
-
|
22
|
+
begin
|
23
|
+
pulsar.run(full_list_args)
|
24
|
+
rescue
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(Dir.glob("#{spec_tmp_path}/tmp/conf-repo*")).to be_empty
|
20
29
|
end
|
21
30
|
|
22
|
-
it
|
23
|
-
app_one = Regexp.escape(
|
24
|
-
app_two = Regexp.escape(
|
31
|
+
it 'lists configured apps and stages' do
|
32
|
+
app_one = Regexp.escape('dummy_app'.cyan)
|
33
|
+
app_two = Regexp.escape('other_dummy_app'.cyan)
|
25
34
|
|
26
|
-
stages = [
|
35
|
+
stages = ['custom_stage'.magenta, 'production'.magenta, 'staging'.magenta]
|
27
36
|
escaped_stages = Regexp.escape(stages.join(', '))
|
28
37
|
|
29
38
|
pulsar.run(full_list_args)
|
30
39
|
|
31
|
-
stdout.
|
32
|
-
stdout.
|
40
|
+
expect(stdout).to match(/#{app_one}: #{escaped_stages}/)
|
41
|
+
expect(stdout).to match(/#{app_two}: #{escaped_stages}/)
|
33
42
|
end
|
34
43
|
|
35
|
-
context
|
36
|
-
it
|
37
|
-
|
44
|
+
context 'dotfile options' do
|
45
|
+
it 'reads configuration variables from config file in home' do
|
46
|
+
stub_config(File.join(pulsar.home_path, 'config'), dummy_dotfile_options)
|
38
47
|
|
39
48
|
pulsar.run(full_list_args)
|
40
49
|
|
41
|
-
ENV.to_hash.
|
50
|
+
expect(ENV.to_hash).to include(dummy_dotfile_options)
|
42
51
|
end
|
43
52
|
|
44
|
-
it
|
45
|
-
|
53
|
+
it 'reads configurations from .pulsar file in rack app directory' do
|
54
|
+
stub_config(File.join(dummy_app_path, '.pulsar'), dummy_dotfile_options)
|
46
55
|
|
47
|
-
FileUtils.cd(
|
56
|
+
FileUtils.cd(dummy_app_path) do
|
48
57
|
reload_main_command
|
49
58
|
|
50
59
|
pulsar.run(full_list_args)
|
51
60
|
end
|
52
61
|
|
53
|
-
ENV.to_hash.
|
62
|
+
expect(ENV.to_hash).to include(dummy_dotfile_options)
|
54
63
|
end
|
55
64
|
|
56
|
-
it
|
57
|
-
|
65
|
+
it 'skips lines which cannot parse when reading .pulsar file' do
|
66
|
+
stub_config(
|
67
|
+
File.join(dummy_app_path, '.pulsar'), ['wrong_line', '# comment'])
|
58
68
|
|
59
|
-
FileUtils.cd(
|
69
|
+
FileUtils.cd(dummy_app_path) do
|
60
70
|
reload_main_command
|
61
71
|
|
62
72
|
expect { pulsar.run(full_list_args) }.not_to raise_error
|
63
73
|
end
|
64
74
|
end
|
65
75
|
|
66
|
-
it
|
67
|
-
|
76
|
+
it 'falls back to default config file if it\'s not in the app directory' do
|
77
|
+
stub_config(File.join(pulsar.home_path, 'config'), dummy_dotfile_options)
|
68
78
|
|
69
|
-
|
79
|
+
allow(File)
|
80
|
+
.to receive(:file?)
|
81
|
+
.with("#{File.expand_path(dummy_app_path)}/.pulsar").and_return(false)
|
70
82
|
|
71
|
-
FileUtils.cd(
|
83
|
+
FileUtils.cd(dummy_app_path) do
|
72
84
|
reload_main_command
|
73
85
|
|
74
86
|
pulsar.run(full_list_args)
|
@@ -76,36 +88,40 @@ describe Pulsar::ListCommand do
|
|
76
88
|
end
|
77
89
|
end
|
78
90
|
|
79
|
-
context
|
80
|
-
it
|
91
|
+
context '--conf-repo option' do
|
92
|
+
it 'is required' do
|
81
93
|
expect { pulsar.parse([]) }.to raise_error(Clamp::UsageError)
|
82
94
|
end
|
83
95
|
|
84
|
-
it
|
85
|
-
ENV[
|
86
|
-
expect { pulsar.parse([]) }.not_to raise_error
|
96
|
+
it 'supports environment variable' do
|
97
|
+
ENV['PULSAR_CONF_REPO'] = dummy_conf_path
|
98
|
+
expect { pulsar.parse([]) }.not_to raise_error
|
87
99
|
end
|
88
100
|
|
89
|
-
it
|
90
|
-
expect { pulsar.run(full_list_args) }.not_to raise_error
|
101
|
+
it 'supports directories' do
|
102
|
+
expect { pulsar.run(full_list_args) }.not_to raise_error
|
91
103
|
end
|
92
104
|
end
|
93
105
|
|
94
|
-
context
|
95
|
-
it
|
96
|
-
expect { pulsar.parse(base_args + %w(--
|
106
|
+
context '--home-dir option' do
|
107
|
+
it 'is supported' do
|
108
|
+
expect { pulsar.parse(base_args + %w(--home-dir dummy_tmp)) }
|
109
|
+
.not_to raise_error
|
97
110
|
end
|
98
111
|
|
99
|
-
it
|
100
|
-
|
112
|
+
it 'creates the tmp directory if it doesn\'t exist' do
|
113
|
+
Dir.mktmpdir do |dir|
|
114
|
+
run_options = base_args + ['--home-dir', dir]
|
101
115
|
|
102
|
-
|
116
|
+
expect { pulsar.run(run_options) }.not_to raise_error
|
117
|
+
expect(File.directory?(pulsar.tmp_path)).to be(true)
|
118
|
+
end
|
103
119
|
end
|
104
120
|
end
|
105
121
|
|
106
|
-
context
|
107
|
-
it
|
108
|
-
expect { pulsar.parse(base_args + %w(--keep-capfile)) }.
|
122
|
+
context '--keep-capfile option' do
|
123
|
+
it 'is supported' do
|
124
|
+
expect { pulsar.parse(base_args + %w(--keep-capfile)) }.not_to raise_error
|
109
125
|
end
|
110
126
|
end
|
111
127
|
end
|
@@ -1,310 +1,360 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Pulsar::MainCommand do
|
4
|
-
let(:pulsar) { Pulsar::MainCommand.new(
|
4
|
+
let(:pulsar) { Pulsar::MainCommand.new('') }
|
5
5
|
|
6
6
|
before(:each) { reload_main_command }
|
7
7
|
|
8
|
-
it
|
9
|
-
expect { pulsar.run(full_cap_args + dummy_app) }
|
8
|
+
it 'builds a Capfile file in tmp dir' do
|
9
|
+
expect { pulsar.run(full_cap_args + dummy_app) }
|
10
|
+
.to change { capfile_count }.by(1)
|
10
11
|
end
|
11
12
|
|
12
|
-
it
|
13
|
-
expect { pulsar.run(full_cap_args + %w(--keep-repo) + dummy_app) }
|
13
|
+
it 'copies a the repo over to temp directory' do
|
14
|
+
expect { pulsar.run(full_cap_args + %w(--keep-repo) + dummy_app) }
|
15
|
+
.to change { capfile_count }.by(1)
|
14
16
|
end
|
15
17
|
|
16
|
-
it
|
17
|
-
Pulsar::MainCommand
|
18
|
-
|
18
|
+
it 'removes the temp directory even if it\'s raised an error' do
|
19
|
+
allow_any_instance_of(Pulsar::MainCommand)
|
20
|
+
.to receive(:run_capistrano) { fail('error') }
|
19
21
|
|
20
|
-
|
22
|
+
begin
|
23
|
+
pulsar.run(
|
24
|
+
base_args + ['--home-dir', spec_tmp_path, '--keep-capfile'] + dummy_app)
|
25
|
+
rescue
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(Dir.glob("#{spec_tmp_path}/tmp/conf-repo*")).to be_empty
|
21
30
|
end
|
22
31
|
|
23
|
-
it
|
24
|
-
system("mkdir #{
|
25
|
-
|
32
|
+
it 'copies a the repo when there is a dir with same name' do
|
33
|
+
system("mkdir -p #{spec_tmp_path}/tmp/conf-repo")
|
34
|
+
|
35
|
+
expect { pulsar.run(full_cap_args + %w(--keep-repo) + dummy_app) }
|
36
|
+
.to change { Dir.glob("#{spec_tmp_path}/tmp/conf-repo*").length }.by(1)
|
26
37
|
end
|
27
38
|
|
28
|
-
it
|
29
|
-
FileUtils.cd(
|
39
|
+
it 'uses dirname when inside a rack app directory' do
|
40
|
+
FileUtils.cd(dummy_app_path) do
|
30
41
|
reload_main_command
|
31
42
|
|
32
|
-
expect { pulsar.run(full_cap_args + %w(production)) }
|
43
|
+
expect { pulsar.run(full_cap_args + %w(production)) }
|
44
|
+
.to change { capfile_count }.by(1)
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
36
|
-
context
|
48
|
+
context 'Multiple applications' do
|
37
49
|
let :stage do
|
38
|
-
|
50
|
+
'production'
|
39
51
|
end
|
40
52
|
|
41
53
|
let :comma_separated_list do
|
42
|
-
[
|
54
|
+
['dummy_app,other_dummy_app', stage]
|
43
55
|
end
|
44
56
|
|
45
57
|
let :pattern_list do
|
46
|
-
[
|
58
|
+
['dummy*', stage]
|
47
59
|
end
|
48
60
|
|
49
61
|
let :pattern_match_all do
|
50
|
-
[
|
62
|
+
['*', stage]
|
51
63
|
end
|
52
64
|
|
53
65
|
let :double_pattern do
|
54
|
-
[
|
66
|
+
['dummy*,*app', stage]
|
55
67
|
end
|
56
68
|
|
57
|
-
it
|
58
|
-
expect { pulsar.run(full_cap_args + comma_separated_list) }
|
69
|
+
it 'supports multiple apps via comma separated argument' do
|
70
|
+
expect { pulsar.run(full_cap_args + comma_separated_list) }
|
71
|
+
.to change { capfile_count }.by(2)
|
59
72
|
end
|
60
73
|
|
61
|
-
it
|
62
|
-
expect { pulsar.run(full_cap_args + pattern_list) }
|
74
|
+
it 'supports pattern matching on app names' do
|
75
|
+
expect { pulsar.run(full_cap_args + pattern_list) }
|
76
|
+
.to change { capfile_count }.by(1)
|
63
77
|
end
|
64
78
|
|
65
|
-
it
|
66
|
-
expect { pulsar.run(full_cap_args + pattern_match_all) }
|
79
|
+
it 'matches all apps with *' do
|
80
|
+
expect { pulsar.run(full_cap_args + pattern_match_all) }
|
81
|
+
.to change { capfile_count }.by(2)
|
67
82
|
end
|
68
83
|
|
69
|
-
it
|
70
|
-
expect { pulsar.run(full_cap_args + double_pattern) }
|
84
|
+
it 'matches application only once' do
|
85
|
+
expect { pulsar.run(full_cap_args + double_pattern) }
|
86
|
+
.to change { capfile_count }.by(2)
|
71
87
|
end
|
72
88
|
end
|
73
89
|
|
74
|
-
context
|
75
|
-
it
|
76
|
-
|
90
|
+
context 'dotfile options' do
|
91
|
+
it 'reads configuration variables from config file in home' do
|
92
|
+
stub_config(File.join(pulsar.home_path, 'config'), dummy_dotfile_options)
|
77
93
|
|
78
94
|
pulsar.run(full_cap_args + dummy_app)
|
79
95
|
|
80
|
-
ENV.to_hash.
|
96
|
+
expect(ENV.to_hash).to include(dummy_dotfile_options)
|
81
97
|
end
|
82
98
|
|
83
|
-
it
|
84
|
-
|
99
|
+
it 'reads configurations from .pulsar file in rack app directory' do
|
100
|
+
stub_config(File.join(dummy_app_path, '.pulsar'), dummy_dotfile_options)
|
85
101
|
|
86
|
-
FileUtils.cd(
|
102
|
+
FileUtils.cd(dummy_app_path) do
|
87
103
|
reload_main_command
|
88
104
|
|
89
105
|
pulsar.run(full_cap_args + %w(production))
|
90
106
|
end
|
91
107
|
|
92
|
-
ENV.to_hash.
|
108
|
+
expect(ENV.to_hash).to include(dummy_dotfile_options)
|
93
109
|
end
|
94
110
|
|
95
|
-
it
|
96
|
-
|
111
|
+
it 'skips lines which cannot parse when reading .pulsar file' do
|
112
|
+
stub_config(
|
113
|
+
File.join(dummy_app_path, '.pulsar'), ['wrong_line', '# comment'])
|
97
114
|
|
98
|
-
FileUtils.cd(
|
115
|
+
FileUtils.cd(dummy_app_path) do
|
99
116
|
reload_main_command
|
100
117
|
|
101
118
|
expect { pulsar.run(full_cap_args + %w(production)) }.not_to raise_error
|
102
119
|
end
|
103
120
|
end
|
104
121
|
|
105
|
-
it
|
106
|
-
|
122
|
+
it 'falls back to default config file if it\'s not in the app directory' do
|
123
|
+
stub_config(File.join(spec_tmp_path, 'config'), dummy_dotfile_options)
|
107
124
|
|
108
|
-
|
125
|
+
allow(File)
|
126
|
+
.to receive(:file?)
|
127
|
+
.with("#{File.expand_path(dummy_app_path)}/.pulsar").and_return(false)
|
109
128
|
|
110
|
-
FileUtils.cd(
|
129
|
+
FileUtils.cd(dummy_app_path) do
|
111
130
|
reload_main_command
|
112
131
|
|
113
|
-
pulsar.run(full_cap_args + %w(production))
|
132
|
+
expect { pulsar.run(full_cap_args + %w(production)) }.not_to raise_error
|
114
133
|
end
|
115
134
|
end
|
116
135
|
end
|
117
136
|
|
118
|
-
it
|
119
|
-
expect { pulsar.run(full_cap_args + %w(non_existent_app production)) }
|
137
|
+
it 'errors out if application does not exist in configuration repository' do
|
138
|
+
expect { pulsar.run(full_cap_args + %w(non_existent_app production)) }
|
139
|
+
.to raise_error(ArgumentError)
|
120
140
|
end
|
121
141
|
|
122
|
-
it
|
123
|
-
expect { pulsar.run(full_cap_args + dummy_app(:non_existent_stage)) }
|
142
|
+
it 'errors out if stage does not exist in configuration repository' do
|
143
|
+
expect { pulsar.run(full_cap_args + dummy_app(:non_existent_stage)) }
|
144
|
+
.to raise_error(ArgumentError)
|
124
145
|
end
|
125
146
|
|
126
|
-
context
|
127
|
-
it
|
147
|
+
context 'Capfile' do
|
148
|
+
it 'uses base.rb in staging stage' do
|
128
149
|
pulsar.run(full_cap_args + dummy_app(:staging))
|
129
150
|
|
130
|
-
latest_capfile.
|
151
|
+
expect(latest_capfile).to include('# This is apps/base.rb')
|
131
152
|
end
|
132
153
|
|
133
|
-
it
|
154
|
+
it 'uses base.rb in production stage' do
|
134
155
|
pulsar.run(full_cap_args + dummy_app)
|
135
156
|
|
136
|
-
latest_capfile.
|
157
|
+
expect(latest_capfile).to include('# This is apps/base.rb')
|
137
158
|
end
|
138
159
|
|
139
|
-
it
|
160
|
+
it 'uses defaults.rb in staging stage' do
|
140
161
|
pulsar.run(full_cap_args + dummy_app(:staging))
|
141
162
|
|
142
|
-
latest_capfile.
|
163
|
+
expect(latest_capfile).to include('# This is apps/dummy_app/defaults.rb')
|
143
164
|
end
|
144
165
|
|
145
|
-
it
|
166
|
+
it 'uses defaults.rb in production stage' do
|
146
167
|
pulsar.run(full_cap_args + dummy_app)
|
147
168
|
|
148
|
-
latest_capfile.
|
169
|
+
expect(latest_capfile).to include('# This is apps/dummy_app/defaults.rb')
|
149
170
|
end
|
150
171
|
|
151
|
-
it
|
172
|
+
it 'uses defaults.rb in staging stage only' do
|
152
173
|
pulsar.run(full_cap_args + dummy_app(:staging))
|
153
174
|
|
154
|
-
latest_capfile
|
155
|
-
|
175
|
+
expect(latest_capfile)
|
176
|
+
.to include('# This is apps/dummy_app/staging.rb')
|
177
|
+
expect(latest_capfile)
|
178
|
+
.not_to include('# This is apps/dummy_app/production.rb')
|
156
179
|
end
|
157
180
|
|
158
|
-
it
|
181
|
+
it 'uses defaults.rb in production stage only' do
|
159
182
|
pulsar.run(full_cap_args + dummy_app)
|
160
183
|
|
161
|
-
latest_capfile
|
162
|
-
|
184
|
+
expect(latest_capfile)
|
185
|
+
.to include('# This is apps/dummy_app/production.rb')
|
186
|
+
expect(latest_capfile)
|
187
|
+
.not_to include('# This is apps/dummy_app/staging.rb')
|
163
188
|
end
|
164
189
|
|
165
|
-
it
|
190
|
+
it 'uses custom recipes in staging stage' do
|
166
191
|
pulsar.run(full_cap_args + dummy_app(:staging))
|
167
192
|
|
168
|
-
latest_capfile
|
193
|
+
expect(latest_capfile)
|
194
|
+
.to include('# This is apps/dummy_app/recipes/custom_recipe.rb')
|
169
195
|
end
|
170
196
|
|
171
|
-
it
|
197
|
+
it 'uses custom recipes in production stage' do
|
172
198
|
pulsar.run(full_cap_args + dummy_app)
|
173
199
|
|
174
|
-
latest_capfile
|
200
|
+
expect(latest_capfile)
|
201
|
+
.to include('# This is apps/dummy_app/recipes/custom_recipe.rb')
|
175
202
|
end
|
176
203
|
|
177
|
-
it
|
204
|
+
it 'uses custom staging recipes in staging stage only' do
|
178
205
|
pulsar.run(full_cap_args + dummy_app(:staging))
|
179
206
|
|
180
|
-
latest_capfile
|
181
|
-
|
207
|
+
expect(latest_capfile)
|
208
|
+
.to include('# This is apps/dummy_app/recipes/staging/custom_recipe.rb')
|
209
|
+
expect(latest_capfile)
|
210
|
+
.not_to include(
|
211
|
+
'# This is apps/dummy_app/recipes/production/custom_recipe.rb')
|
182
212
|
end
|
183
213
|
|
184
|
-
it
|
214
|
+
it 'uses custom production recipes in production stage only' do
|
185
215
|
pulsar.run(full_cap_args + dummy_app)
|
186
216
|
|
187
|
-
latest_capfile
|
188
|
-
|
217
|
+
expect(latest_capfile)
|
218
|
+
.to include(
|
219
|
+
'# This is apps/dummy_app/recipes/production/custom_recipe.rb')
|
220
|
+
expect(latest_capfile)
|
221
|
+
.not_to include(
|
222
|
+
'# This is apps/dummy_app/recipes/staging/custom_recipe.rb')
|
189
223
|
end
|
190
224
|
|
191
|
-
it
|
192
|
-
ENV[
|
225
|
+
it 'uses dirname from PULSAR_APP_NAME when inside a rack app directory' do
|
226
|
+
ENV['PULSAR_APP_NAME'] = 'other_dummy_app'
|
193
227
|
|
194
|
-
FileUtils.cd(
|
228
|
+
FileUtils.cd(dummy_app_path) do
|
195
229
|
reload_main_command
|
196
230
|
pulsar.run(full_cap_args + %w(production))
|
197
231
|
end
|
198
232
|
|
199
|
-
latest_capfile
|
200
|
-
|
233
|
+
expect(latest_capfile)
|
234
|
+
.to include('# This is apps/other_dummy_app/defaults.rb')
|
235
|
+
expect(latest_capfile)
|
236
|
+
.to include('# This is apps/other_dummy_app/production.rb')
|
201
237
|
end
|
202
238
|
end
|
203
239
|
|
204
|
-
context
|
240
|
+
context '--version option' do
|
205
241
|
before do
|
206
242
|
begin
|
207
|
-
pulsar.parse([
|
243
|
+
pulsar.parse(['--version'])
|
208
244
|
rescue SystemExit => e
|
209
245
|
@system_exit = e
|
210
246
|
end
|
211
247
|
end
|
212
248
|
|
213
|
-
it
|
214
|
-
stdout.
|
249
|
+
it 'shows version' do
|
250
|
+
expect(stdout).to include(Pulsar::VERSION)
|
215
251
|
end
|
216
252
|
|
217
|
-
it
|
218
|
-
@system_exit.
|
219
|
-
@system_exit.status.
|
253
|
+
it 'exits with a zero status' do
|
254
|
+
expect(@system_exit).not_to be_nil
|
255
|
+
expect(@system_exit.status).to be 0
|
220
256
|
end
|
221
257
|
end
|
222
258
|
|
223
|
-
context
|
224
|
-
it
|
259
|
+
context '--conf-repo option' do
|
260
|
+
it 'is required' do
|
225
261
|
expect { pulsar.parse([]) }.to raise_error(Clamp::UsageError)
|
226
262
|
end
|
227
263
|
|
228
|
-
it
|
229
|
-
ENV[
|
230
|
-
expect { pulsar.parse(dummy_app) }.not_to raise_error
|
264
|
+
it 'supports environment variable' do
|
265
|
+
ENV['PULSAR_CONF_REPO'] = dummy_conf_path
|
266
|
+
expect { pulsar.parse(dummy_app) }.not_to raise_error
|
231
267
|
end
|
232
268
|
|
233
|
-
it
|
234
|
-
expect { pulsar.run(full_cap_args + dummy_app) }.not_to raise_error
|
269
|
+
it 'supports directories' do
|
270
|
+
expect { pulsar.run(full_cap_args + dummy_app) }.not_to raise_error
|
235
271
|
end
|
236
272
|
end
|
237
273
|
|
238
|
-
context
|
239
|
-
it
|
240
|
-
expect { pulsar.parse(base_args + %w(--
|
274
|
+
context '--home-dir option' do
|
275
|
+
it 'is supported' do
|
276
|
+
expect { pulsar.parse(base_args + %w(--home-dir dummy_tmp) + dummy_app) }
|
277
|
+
.not_to raise_error
|
241
278
|
end
|
242
279
|
|
243
|
-
it
|
244
|
-
|
280
|
+
it 'creates the tmp directory if it doesn\'t exist' do
|
281
|
+
Dir.mktmpdir do |dir|
|
282
|
+
run_options = base_args +
|
283
|
+
['--home-dir', dir, '--skip-cap-run'] +
|
284
|
+
dummy_app
|
245
285
|
|
246
|
-
|
286
|
+
expect { pulsar.run(run_options) }.not_to raise_error
|
287
|
+
expect(File.directory?(pulsar.tmp_path)).to be(true)
|
288
|
+
end
|
247
289
|
end
|
248
290
|
end
|
249
291
|
|
250
|
-
context
|
251
|
-
it
|
252
|
-
expect { pulsar.parse(base_args + %w(--keep-capfile) + dummy_app) }
|
292
|
+
context '--keep-capfile option' do
|
293
|
+
it 'is supported' do
|
294
|
+
expect { pulsar.parse(base_args + %w(--keep-capfile) + dummy_app) }
|
295
|
+
.not_to raise_error
|
253
296
|
end
|
254
297
|
end
|
255
298
|
|
256
|
-
context
|
257
|
-
it
|
258
|
-
expect { pulsar.parse(base_args + %w(--skip-cap-run) + dummy_app) }
|
299
|
+
context '--skip-cap-run option' do
|
300
|
+
it 'is supported' do
|
301
|
+
expect { pulsar.parse(base_args + %w(--skip-cap-run) + dummy_app) }
|
302
|
+
.not_to raise_error
|
259
303
|
end
|
260
304
|
end
|
261
305
|
|
262
|
-
context
|
263
|
-
it
|
264
|
-
expect { pulsar.parse(base_args + %w(--keep-repo) + dummy_app) }
|
306
|
+
context '--keep-repo option' do
|
307
|
+
it 'is supported' do
|
308
|
+
expect { pulsar.parse(base_args + %w(--keep-repo) + dummy_app) }
|
309
|
+
.not_to raise_error
|
265
310
|
end
|
266
311
|
end
|
267
312
|
|
268
|
-
context
|
269
|
-
it
|
270
|
-
expect { pulsar.parse(base_args + %w(--log-level debug) + dummy_app) }
|
313
|
+
context '--log-level option' do
|
314
|
+
it 'is supported' do
|
315
|
+
expect { pulsar.parse(base_args + %w(--log-level debug) + dummy_app) }
|
316
|
+
.not_to raise_error
|
271
317
|
end
|
272
318
|
|
273
|
-
it
|
319
|
+
it 'supports Capistrano IMPORTANT' do
|
274
320
|
pulsar.run(full_cap_args + %w(--log-level important) + dummy_app)
|
275
321
|
|
276
|
-
latest_capfile.
|
322
|
+
expect(latest_capfile).to include(
|
323
|
+
'logger.level = logger.level = Capistrano::Logger::IMPORTANT')
|
277
324
|
end
|
278
325
|
|
279
|
-
it
|
326
|
+
it 'supports Capistrano INFO' do
|
280
327
|
pulsar.run(full_cap_args + %w(--log-level info) + dummy_app)
|
281
328
|
|
282
|
-
latest_capfile
|
329
|
+
expect(latest_capfile)
|
330
|
+
.to include('logger.level = logger.level = Capistrano::Logger::INFO')
|
283
331
|
end
|
284
332
|
|
285
|
-
it
|
333
|
+
it 'supports Capistrano DEBUG' do
|
286
334
|
pulsar.run(full_cap_args + %w(--log-level debug) + dummy_app)
|
287
335
|
|
288
|
-
latest_capfile
|
336
|
+
expect(latest_capfile)
|
337
|
+
.to include('logger.level = logger.level = Capistrano::Logger::DEBUG')
|
289
338
|
end
|
290
339
|
|
291
|
-
it
|
340
|
+
it 'supports Capistrano TRACE' do
|
292
341
|
pulsar.run(full_cap_args + %w(--log-level trace) + dummy_app)
|
293
342
|
|
294
|
-
latest_capfile
|
343
|
+
expect(latest_capfile)
|
344
|
+
.to include('logger.level = logger.level = Capistrano::Logger::TRACE')
|
295
345
|
end
|
296
346
|
end
|
297
347
|
|
298
|
-
context
|
299
|
-
it
|
300
|
-
pulsar.tasks_list.
|
348
|
+
context 'TASKS parameter' do
|
349
|
+
it 'defaults to deploy' do
|
350
|
+
expect(pulsar.tasks_list).to eq 'deploy'
|
301
351
|
end
|
302
352
|
|
303
|
-
it
|
304
|
-
ENV[
|
353
|
+
it 'supports environment variable' do
|
354
|
+
ENV['PULSAR_DEFAULT_TASK'] = 'custom:task'
|
305
355
|
pulsar.run(full_cap_args + dummy_app)
|
306
356
|
|
307
|
-
pulsar.tasks_list.
|
357
|
+
expect(pulsar.tasks_list).to eq ['custom:task']
|
308
358
|
end
|
309
359
|
end
|
310
360
|
end
|