pulsar 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/README.md +9 -0
- data/lib/pulsar/commands/init.rb +1 -1
- data/lib/pulsar/commands/list.rb +1 -1
- data/lib/pulsar/commands/main.rb +19 -28
- data/lib/pulsar/generators/init_repo/Gemfile +1 -1
- data/lib/pulsar/generators/init_repo/apps/your_app/recipes/custom_recipe.rb +4 -4
- data/lib/pulsar/helpers/capistrano.rb +2 -2
- data/lib/pulsar/helpers/clamp.rb +45 -4
- data/lib/pulsar/helpers/path.rb +16 -4
- data/lib/pulsar/options/conf_repo.rb +1 -1
- data/lib/pulsar/options/shared.rb +1 -1
- data/lib/pulsar/version.rb +1 -1
- data/pulsar.gemspec +1 -1
- data/spec/pulsar/commands/list_spec.rb +28 -40
- data/spec/pulsar/commands/main_spec.rb +73 -46
- data/spec/pulsar/helpers/capistrano_spec.rb +2 -2
- data/spec/pulsar/helpers/clamp_spec.rb +0 -12
- data/spec/pulsar/helpers/shell_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -4
- data/spec/support/modules/helpers.rb +41 -13
- metadata +19 -35
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65bfc17e611312457af55a59e849357acf7fc6e5
|
4
|
+
data.tar.gz: 4af24027523427551bc5bcdc26dd00134abb3bdd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cf819b8a1a90e5b9c45c453eea30d1d4b1c7d52edc9bc661200daed1ecb5ef88394306d033a3a49e2609d560c545554c534aaf67c4f8ebd2edffd6d9a6186e8d
|
7
|
+
data.tar.gz: cd80a5a0bbd1d325eb9fd8586dc21434c0ef104aa3f5801c0aee494f4c9945c36e3ca758240f5d9ec3f59a7fba5dad6c69c41dd04921b5ec59c288adb8470236
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
2.1.2
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -219,6 +219,15 @@ $ pulsar my_application staging shell
|
|
219
219
|
# Deploy multiple apps by using commas
|
220
220
|
#
|
221
221
|
$ pulsar my_app1,my_app2,my_app3 production
|
222
|
+
|
223
|
+
#
|
224
|
+
# Deploy multiple apps by using pattern matching
|
225
|
+
# (uses Dir.glob)
|
226
|
+
#
|
227
|
+
$ pulsar my_app* production
|
228
|
+
# or
|
229
|
+
$ pulsar *worker staging
|
230
|
+
|
222
231
|
```
|
223
232
|
|
224
233
|
### Running inside a Rack application (e.g. Ruby on Rails application)
|
data/lib/pulsar/commands/init.rb
CHANGED
@@ -3,7 +3,7 @@ module Pulsar
|
|
3
3
|
parameter "CONFIGURATION_PATH", "where to generate your configuration repository"
|
4
4
|
|
5
5
|
def execute
|
6
|
-
|
6
|
+
with_clean_env_and_supported_vars do
|
7
7
|
destination_path = File.expand_path(configuration_path)
|
8
8
|
|
9
9
|
pulsar_cmd_path = File.expand_path(File.dirname(__FILE__))
|
data/lib/pulsar/commands/list.rb
CHANGED
data/lib/pulsar/commands/main.rb
CHANGED
@@ -3,7 +3,7 @@ module Pulsar
|
|
3
3
|
include Pulsar::Helpers::Clamp
|
4
4
|
include Pulsar::Options::Shared
|
5
5
|
include Pulsar::Options::ConfRepo
|
6
|
-
|
6
|
+
|
7
7
|
option [ "-l", "--log-level" ], "LOG LEVEL",
|
8
8
|
"how much output will Capistrano print out. Can be any of: important, info, debug, trace",
|
9
9
|
:default => "important"
|
@@ -13,21 +13,25 @@ module Pulsar
|
|
13
13
|
:default => false
|
14
14
|
|
15
15
|
if !from_application_path?
|
16
|
-
parameter "
|
16
|
+
parameter "APPLICATIONS", "the applications which you would like to deploy. You can pass just one or a comma separated list to deploy multiple applications at once. It supports globbing too."
|
17
17
|
end
|
18
18
|
|
19
19
|
parameter "STAGE", "the stage on which you would like to deploy"
|
20
20
|
|
21
|
-
parameter "[TASKS] ...",
|
21
|
+
parameter "[TASKS] ...",
|
22
|
+
"the arguments and/or options that will be passed to capistrano",
|
23
|
+
:environment_variable => "PULSAR_DEFAULT_TASK",
|
24
|
+
:default => "deploy"
|
22
25
|
|
23
26
|
def execute
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
with_clean_env_and_supported_vars do
|
28
|
+
begin
|
29
|
+
create_tmp_dir
|
30
|
+
fetch_repo
|
31
|
+
bundle_install
|
32
|
+
|
33
|
+
expand_applications.each do |app|
|
29
34
|
validate(app, stage)
|
30
|
-
bundle_install
|
31
35
|
create_capfile
|
32
36
|
build_capfile(app, stage)
|
33
37
|
|
@@ -35,28 +39,15 @@ module Pulsar
|
|
35
39
|
cap_args = [ tasks_list ].flatten.shelljoin
|
36
40
|
run_capistrano(cap_args)
|
37
41
|
end
|
38
|
-
|
39
|
-
|
42
|
+
|
43
|
+
remove_capfile unless keep_capfile?
|
44
|
+
reset_capfile_path!
|
40
45
|
end
|
46
|
+
ensure
|
47
|
+
remove_capfile unless keep_capfile?
|
48
|
+
remove_repo unless keep_repo?
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def find_apps
|
48
|
-
if from_application_path?
|
49
|
-
[ ENV['PULSAR_APP_NAME'] || File.basename(application_path) ]
|
50
|
-
else
|
51
|
-
application.split(',')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def cleanup!
|
56
|
-
remove_capfile unless keep_capfile?
|
57
|
-
remove_repo unless keep_repo?
|
58
|
-
|
59
|
-
reset_for_other_app!
|
60
|
-
end
|
61
52
|
end
|
62
53
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
#
|
2
|
-
# Use this directory to include any file you whish to
|
1
|
+
#
|
2
|
+
# Use this directory to include any file you whish to
|
3
3
|
# include whenever you run this app.
|
4
4
|
#
|
5
|
-
# You don't need to run the include_recipe method.
|
5
|
+
# You don't need to run the include_recipe method.
|
6
6
|
#
|
7
7
|
# The filename can be whatever you want it to be.
|
8
8
|
#
|
9
9
|
# These recipes are considered custom and always appended
|
10
10
|
# to the Capfile of this application.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# production/ and staging/ directories will have recipes
|
13
13
|
# which are automatically included only in such stages.
|
14
14
|
#
|
@@ -27,12 +27,12 @@ module Pulsar
|
|
27
27
|
end
|
28
28
|
|
29
29
|
#
|
30
|
-
# This method can be called directly inside
|
30
|
+
# This method can be called directly inside
|
31
31
|
# capistrano configurations but needs:
|
32
32
|
#
|
33
33
|
# defer { from_application_path? }
|
34
34
|
#
|
35
|
-
# otherwise capistrano will interpret it
|
35
|
+
# otherwise capistrano will interpret it
|
36
36
|
# as a variable and error out
|
37
37
|
#
|
38
38
|
def from_application_path?
|
data/lib/pulsar/helpers/clamp.rb
CHANGED
@@ -52,6 +52,27 @@ module Pulsar
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
def expand_applications
|
56
|
+
if from_application_path?
|
57
|
+
[ ENV['PULSAR_APP_NAME'] || File.basename(application_path) ]
|
58
|
+
else
|
59
|
+
#
|
60
|
+
# Given following applications:
|
61
|
+
# pulsar_repo/
|
62
|
+
# apps/
|
63
|
+
# app1
|
64
|
+
# app2
|
65
|
+
# app3-web
|
66
|
+
# app3-worker
|
67
|
+
# app4
|
68
|
+
# it turns app1,app2,app3* into
|
69
|
+
#
|
70
|
+
# [ app1, app2, app3-web, app3-worker ]
|
71
|
+
#
|
72
|
+
applications.split(',').flat_map { |glob| find_apps_from_pattern(glob) }.uniq
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
55
76
|
def fetch_repo
|
56
77
|
if File.directory?(conf_repo)
|
57
78
|
fetch_directory_repo(conf_repo)
|
@@ -75,6 +96,17 @@ module Pulsar
|
|
75
96
|
run_cmd("git clone #{git_options} #{repo} #{config_path}", :verbose => verbose?)
|
76
97
|
end
|
77
98
|
|
99
|
+
def find_apps_from_pattern(glob)
|
100
|
+
found_apps = []
|
101
|
+
|
102
|
+
Dir.glob(config_app_path("#{glob}/")).each do |path|
|
103
|
+
found_apps << File.basename(path)
|
104
|
+
end
|
105
|
+
|
106
|
+
found_apps << glob if found_apps.empty?
|
107
|
+
found_apps
|
108
|
+
end
|
109
|
+
|
78
110
|
def include_app(app, stage)
|
79
111
|
app_file = config_app_defaults_path(app)
|
80
112
|
stage_file = config_stage_path(app, stage)
|
@@ -134,10 +166,6 @@ module Pulsar
|
|
134
166
|
rm_rf(config_path, :verbose => verbose?)
|
135
167
|
end
|
136
168
|
|
137
|
-
def reset_for_other_app!
|
138
|
-
@capfile_name = @configuration_path = @now = nil
|
139
|
-
end
|
140
|
-
|
141
169
|
def run_capistrano(args)
|
142
170
|
cmd = "bundle exec cap"
|
143
171
|
env = "CONFIG_PATH=#{config_path}"
|
@@ -161,6 +189,10 @@ module Pulsar
|
|
161
189
|
run_cmd(cmd, :verbose => verbose?)
|
162
190
|
end
|
163
191
|
|
192
|
+
def supported_env_vars
|
193
|
+
%w(PULSAR_APP_NAME PULSAR_CONF_REPO PULSAR_DEFAULT_TASK)
|
194
|
+
end
|
195
|
+
|
164
196
|
def stages_for(app)
|
165
197
|
exclude = %w(defaults recipes)
|
166
198
|
|
@@ -177,6 +209,15 @@ module Pulsar
|
|
177
209
|
valid_paths = File.exists?(app_path) && File.exists?(stage_path)
|
178
210
|
raise(ArgumentError, "no pulsar config available for app=#{app}, stage=#{stage}") unless valid_paths
|
179
211
|
end
|
212
|
+
|
213
|
+
def with_clean_env_and_supported_vars
|
214
|
+
vars_from_original_env = ENV.select { |var| supported_env_vars.include?(var) }
|
215
|
+
|
216
|
+
Bundler.with_clean_env do
|
217
|
+
vars_from_original_env.each { |var, val| ENV[var] = val }
|
218
|
+
yield
|
219
|
+
end
|
220
|
+
end
|
180
221
|
end
|
181
222
|
end
|
182
223
|
end
|
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_dir}/capfile-#{deploy_time}"
|
6
6
|
end
|
7
7
|
|
8
8
|
def config_path
|
9
|
-
|
9
|
+
"#{tmp_dir}/conf-repo-#{setup_time}"
|
10
10
|
end
|
11
11
|
|
12
12
|
def config_app_path(app)
|
@@ -37,9 +37,21 @@ module Pulsar
|
|
37
37
|
"#{config_app_path(app)}/#{stage}.rb"
|
38
38
|
end
|
39
39
|
|
40
|
+
def reset_capfile_path!
|
41
|
+
clear_deploy_time
|
42
|
+
end
|
43
|
+
|
40
44
|
private
|
41
|
-
def
|
42
|
-
@
|
45
|
+
def clear_deploy_time
|
46
|
+
@deploy = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def deploy_time
|
50
|
+
@deploy ||= Time.now.strftime("%Y-%m-%d-%H%M%S-s#{rand(9999)}")
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup_time
|
54
|
+
@setup ||= Time.now.strftime("%Y-%m-%d-%H%M%S-s#{rand(9999)}")
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|
@@ -7,7 +7,7 @@ module Pulsar
|
|
7
7
|
:environment_variable => "PULSAR_CONF_REPO",
|
8
8
|
:required => true
|
9
9
|
|
10
|
-
base.option [ "-k", "--keep-capfile" ], :flag,
|
10
|
+
base.option [ "-k", "--keep-capfile" ], :flag,
|
11
11
|
"don't remove the generated capfile in the TMP DIR directory",
|
12
12
|
:default => false
|
13
13
|
|
data/lib/pulsar/version.rb
CHANGED
data/pulsar.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.description = %q{Manage your Capistrano deployments with ease}
|
12
12
|
gem.summary = %q{
|
13
13
|
Pulsar helps with Capistrano configuration management. It uses a repository
|
14
|
-
to store all your precious configurations and recipes to build Capistrano
|
14
|
+
to store all your precious configurations and recipes to build Capistrano
|
15
15
|
deploys on it.
|
16
16
|
}
|
17
17
|
gem.homepage = "http://pulsar.nebulab.it"
|
@@ -22,7 +22,7 @@ describe Pulsar::ListCommand do
|
|
22
22
|
it "lists configured apps and stages" do
|
23
23
|
app_one = Regexp.escape("dummy_app".cyan)
|
24
24
|
app_two = Regexp.escape("other_dummy_app".cyan)
|
25
|
-
|
25
|
+
|
26
26
|
stages = [ "custom_stage".magenta, "production".magenta, "staging".magenta ]
|
27
27
|
escaped_stages = Regexp.escape(stages.join(', '))
|
28
28
|
|
@@ -32,59 +32,47 @@ describe Pulsar::ListCommand do
|
|
32
32
|
stdout.should match(/#{app_two}: #{escaped_stages}/)
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
File.stub(:file?).and_return(true)
|
39
|
-
File.stub(:readlines).with("#{Dir.home}/.pulsar").and_return(env_vars)
|
35
|
+
context "dotfile options" do
|
36
|
+
it "reads configuration variables from .pulsar file in home" do
|
37
|
+
stub_dotfile(Dir.home, dummy_dotfile_options)
|
40
38
|
|
41
|
-
|
39
|
+
pulsar.run(full_list_args)
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
41
|
+
ENV.to_hash.should include(dummy_dotfile_options)
|
42
|
+
end
|
46
43
|
|
47
|
-
|
48
|
-
|
44
|
+
it "reads configuration variables from .pulsar file in rack app directory" do
|
45
|
+
stub_dotfile(dummy_rack_app_path, dummy_dotfile_options)
|
49
46
|
|
50
|
-
|
51
|
-
|
47
|
+
FileUtils.cd(dummy_rack_app_path) do
|
48
|
+
reload_main_command
|
52
49
|
|
53
|
-
|
54
|
-
|
50
|
+
pulsar.run(full_list_args)
|
51
|
+
end
|
55
52
|
|
56
|
-
|
53
|
+
ENV.to_hash.should include(dummy_dotfile_options)
|
57
54
|
end
|
58
55
|
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
it "skips lines which cannot parse when reading .pulsar file" do
|
64
|
-
env_vars = [ "wrong_line", "# comment"]
|
56
|
+
it "skips lines which cannot parse when reading .pulsar file" do
|
57
|
+
stub_dotfile(dummy_rack_app_path, [ "wrong_line", "# comment" ])
|
65
58
|
|
66
|
-
|
67
|
-
|
59
|
+
FileUtils.cd(dummy_rack_app_path) do
|
60
|
+
reload_main_command
|
68
61
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
expect { pulsar.run(full_list_args) }.not_to raise_error
|
62
|
+
expect { pulsar.run(full_list_args) }.not_to raise_error
|
63
|
+
end
|
73
64
|
end
|
74
|
-
end
|
75
65
|
|
76
|
-
|
77
|
-
|
66
|
+
it "falls back to .pulsar file in home directory if it's not in the rack app directory" do
|
67
|
+
stub_dotfile(Dir.home, dummy_dotfile_options)
|
78
68
|
|
79
|
-
|
80
|
-
File.stub(:file?).with("#{File.expand_path(dummy_rack_app_path)}/.pulsar").and_return(false)
|
69
|
+
File.stub(:file?).with("#{File.expand_path(dummy_rack_app_path)}/.pulsar").and_return(false)
|
81
70
|
|
82
|
-
|
71
|
+
FileUtils.cd(dummy_rack_app_path) do
|
72
|
+
reload_main_command
|
83
73
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
pulsar.run(full_list_args)
|
74
|
+
pulsar.run(full_list_args)
|
75
|
+
end
|
88
76
|
end
|
89
77
|
end
|
90
78
|
|
@@ -97,7 +85,7 @@ describe Pulsar::ListCommand do
|
|
97
85
|
ENV["PULSAR_CONF_REPO"] = dummy_conf_path
|
98
86
|
expect { pulsar.parse([]) }.not_to raise_error(Clamp::UsageError)
|
99
87
|
end
|
100
|
-
|
88
|
+
|
101
89
|
it "supports directories" do
|
102
90
|
expect { pulsar.run(full_list_args) }.not_to raise_error(Errno::ENOENT)
|
103
91
|
end
|
@@ -6,11 +6,11 @@ describe Pulsar::MainCommand do
|
|
6
6
|
before(:each) { reload_main_command }
|
7
7
|
|
8
8
|
it "builds a Capfile file in tmp dir" do
|
9
|
-
expect { pulsar.run(full_cap_args + dummy_app) }.to change{
|
9
|
+
expect { pulsar.run(full_cap_args + dummy_app) }.to change{ capfile_count }.by(1)
|
10
10
|
end
|
11
11
|
|
12
12
|
it "copies a the repo over to temp directory" do
|
13
|
-
expect { pulsar.run(full_cap_args + %w(--keep-repo) + dummy_app) }.to change{
|
13
|
+
expect { pulsar.run(full_cap_args + %w(--keep-repo) + dummy_app) }.to change{ capfile_count }.by(1)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "removes the temp directory even if it's raised an error" do
|
@@ -29,75 +29,89 @@ describe Pulsar::MainCommand do
|
|
29
29
|
FileUtils.cd(dummy_rack_app_path) do
|
30
30
|
reload_main_command
|
31
31
|
|
32
|
-
expect { pulsar.run(full_cap_args + %w(production)) }.to change{
|
32
|
+
expect { pulsar.run(full_cap_args + %w(production)) }.to change{ capfile_count }.by(1)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
context "Multiple applications" do
|
37
|
+
let :stage do
|
38
|
+
"production"
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
let :comma_separated_list do
|
42
|
+
[ 'dummy_app,other_dummy_app', stage ]
|
43
|
+
end
|
41
44
|
|
42
|
-
|
43
|
-
|
45
|
+
let :pattern_list do
|
46
|
+
[ 'dummy*', stage ]
|
47
|
+
end
|
44
48
|
|
45
|
-
|
46
|
-
|
49
|
+
let :pattern_match_all do
|
50
|
+
[ '*', stage ]
|
51
|
+
end
|
47
52
|
|
48
|
-
|
53
|
+
let :double_pattern do
|
54
|
+
[ 'dummy*,*app', stage ]
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
|
57
|
+
it "supports multiple apps via comma separated argument" do
|
58
|
+
expect { pulsar.run(full_cap_args + comma_separated_list) }.to change{ capfile_count }.by(2)
|
59
|
+
end
|
52
60
|
|
53
|
-
|
54
|
-
|
55
|
-
|
61
|
+
it "supports pattern matching on app names" do
|
62
|
+
expect { pulsar.run(full_cap_args + pattern_list) }.to change{ capfile_count }.by(1)
|
63
|
+
end
|
56
64
|
|
57
|
-
|
58
|
-
|
65
|
+
it "matches all apps with *" do
|
66
|
+
expect { pulsar.run(full_cap_args + pattern_match_all) }.to change { capfile_count }.by(2)
|
67
|
+
end
|
59
68
|
|
60
|
-
|
61
|
-
|
69
|
+
it "matches application only once" do
|
70
|
+
expect { pulsar.run(full_cap_args + double_pattern) }.to change { capfile_count }.by(2)
|
71
|
+
end
|
72
|
+
end
|
62
73
|
|
63
|
-
|
64
|
-
|
74
|
+
context "dotfile options" do
|
75
|
+
it "reads configuration variables from .pulsar file in home" do
|
76
|
+
stub_dotfile(Dir.home, dummy_dotfile_options)
|
65
77
|
|
66
|
-
pulsar.run(full_cap_args +
|
78
|
+
pulsar.run(full_cap_args + dummy_app)
|
79
|
+
|
80
|
+
ENV.to_hash.should include(dummy_dotfile_options)
|
67
81
|
end
|
68
82
|
|
69
|
-
|
70
|
-
|
83
|
+
it "reads configuration variables from .pulsar file in rack app directory" do
|
84
|
+
stub_dotfile(dummy_rack_app_path, dummy_dotfile_options)
|
71
85
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
86
|
+
FileUtils.cd(dummy_rack_app_path) do
|
87
|
+
reload_main_command
|
75
88
|
|
76
|
-
|
77
|
-
|
89
|
+
pulsar.run(full_cap_args + %w(production))
|
90
|
+
end
|
78
91
|
|
79
|
-
|
80
|
-
|
92
|
+
ENV.to_hash.should include(dummy_dotfile_options)
|
93
|
+
end
|
81
94
|
|
82
|
-
|
83
|
-
|
95
|
+
it "skips lines which cannot parse when reading .pulsar file" do
|
96
|
+
stub_dotfile(dummy_rack_app_path, [ "wrong_line", "# comment"])
|
84
97
|
|
85
|
-
|
86
|
-
|
87
|
-
end
|
98
|
+
FileUtils.cd(dummy_rack_app_path) do
|
99
|
+
reload_main_command
|
88
100
|
|
89
|
-
|
90
|
-
|
101
|
+
expect { pulsar.run(full_cap_args + %w(production)) }.not_to raise_error
|
102
|
+
end
|
103
|
+
end
|
91
104
|
|
92
|
-
|
93
|
-
|
105
|
+
it "falls back to .pulsar file in home directory if it's not in the rack app directory" do
|
106
|
+
stub_dotfile(Dir.home, dummy_dotfile_options)
|
94
107
|
|
95
|
-
|
108
|
+
File.stub(:file?).with("#{File.expand_path(dummy_rack_app_path)}/.pulsar").and_return(false)
|
96
109
|
|
97
|
-
|
98
|
-
|
110
|
+
FileUtils.cd(dummy_rack_app_path) do
|
111
|
+
reload_main_command
|
99
112
|
|
100
|
-
|
113
|
+
pulsar.run(full_cap_args + %w(production))
|
114
|
+
end
|
101
115
|
end
|
102
116
|
end
|
103
117
|
|
@@ -280,4 +294,17 @@ describe Pulsar::MainCommand do
|
|
280
294
|
latest_capfile.should include("logger.level = logger.level = Capistrano::Logger::TRACE")
|
281
295
|
end
|
282
296
|
end
|
297
|
+
|
298
|
+
context "TASKS parameter" do
|
299
|
+
it "defaults to deploy" do
|
300
|
+
pulsar.tasks_list.should == "deploy"
|
301
|
+
end
|
302
|
+
|
303
|
+
it "supports environment variable" do
|
304
|
+
ENV["PULSAR_DEFAULT_TASK"] = "custom:task"
|
305
|
+
pulsar.run(full_cap_args + dummy_app)
|
306
|
+
|
307
|
+
pulsar.tasks_list.should == [ "custom:task" ]
|
308
|
+
end
|
309
|
+
end
|
283
310
|
end
|
@@ -41,7 +41,7 @@ describe Pulsar::Helpers::Capistrano do
|
|
41
41
|
ENV['APP_PATH'] = "/app/path"
|
42
42
|
File.stub(:directory?).and_return(true)
|
43
43
|
File.stub(:exists?).and_return(true)
|
44
|
-
|
44
|
+
|
45
45
|
self.should_receive(:load)
|
46
46
|
|
47
47
|
load_recipes(:app_only => true) { generic :recipe }
|
@@ -57,7 +57,7 @@ describe Pulsar::Helpers::Capistrano do
|
|
57
57
|
|
58
58
|
it "returns false if APP_PATH env variable is not set" do
|
59
59
|
ENV.delete('APP_PATH')
|
60
|
-
|
60
|
+
|
61
61
|
from_application_path?.should be_false
|
62
62
|
end
|
63
63
|
end
|
@@ -50,18 +50,6 @@ describe Pulsar::Helpers::Clamp do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
context "reset_for_other_app!" do
|
54
|
-
it "resets instance variables written by the module" do
|
55
|
-
cap, conf, time = capfile_path, config_path, time_to_deploy
|
56
|
-
|
57
|
-
reset_for_other_app!
|
58
|
-
|
59
|
-
capfile_path.should_not == cap
|
60
|
-
config_path.should_not == conf
|
61
|
-
time_to_deploy.should_not == time
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
53
|
context "run_capistrano" do
|
66
54
|
before do
|
67
55
|
self.stub!(:config_path).and_return(dummy_conf_path)
|
data/spec/spec_helper.rb
CHANGED
@@ -13,7 +13,7 @@ Coveralls.wear!
|
|
13
13
|
|
14
14
|
#
|
15
15
|
# Require all helper modules
|
16
|
-
#
|
16
|
+
#
|
17
17
|
Dir[File.join(File.dirname(__FILE__), 'support/modules/**/*.rb')].each { |f| require f }
|
18
18
|
|
19
19
|
RSpec.configure do |config|
|
@@ -24,9 +24,10 @@ RSpec.configure do |config|
|
|
24
24
|
|
25
25
|
config.before(:each) do
|
26
26
|
Dir.stub(:home).and_return("/fake/home")
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
|
28
|
+
dummy_dotfile_options.keys.each do |variable|
|
29
|
+
ENV.delete(variable.to_s)
|
30
|
+
end
|
30
31
|
end
|
31
32
|
|
32
33
|
config.after(:each) do
|
@@ -3,39 +3,43 @@ module Helpers
|
|
3
3
|
[ "--conf-repo", dummy_conf_path ]
|
4
4
|
end
|
5
5
|
|
6
|
-
def
|
7
|
-
|
6
|
+
def capfile_count
|
7
|
+
Dir.glob("#{tmp_path}/capfile-*").length
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def dummy_app(stage = :production)
|
11
|
+
[ "dummy_app", stage.to_s ]
|
12
12
|
end
|
13
13
|
|
14
14
|
def dummy_conf_path
|
15
15
|
File.join(File.dirname(__FILE__), "..", "dummies", "dummy_conf")
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def dummy_dotfile_options
|
19
|
+
{
|
20
|
+
"PULSAR_APP_NAME" => "dummy_app",
|
21
|
+
"PULSAR_CONF_REPO" => dummy_conf_path,
|
22
|
+
"PULSAR_DEFAULT_TASK" => "capistrano:task"
|
23
|
+
}
|
20
24
|
end
|
21
25
|
|
22
|
-
def
|
23
|
-
"
|
26
|
+
def dummy_rack_app_path
|
27
|
+
File.join(File.dirname(__FILE__), "..", "dummies", "dummy_app")
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
27
|
-
|
30
|
+
def full_cap_args
|
31
|
+
base_args + [ "--tmp-dir", tmp_path, "--keep-capfile", "--skip-cap-run" ]
|
28
32
|
end
|
29
33
|
|
30
|
-
def
|
31
|
-
[ "
|
34
|
+
def full_list_args
|
35
|
+
base_args + [ "--tmp-dir", tmp_path, "--keep-capfile" ]
|
32
36
|
end
|
33
37
|
|
34
38
|
def latest_capfile
|
35
39
|
capfile = File.open(Dir.glob("#{tmp_path}/capfile-*").first)
|
36
40
|
content = capfile.read
|
37
41
|
capfile.close
|
38
|
-
|
42
|
+
|
39
43
|
content
|
40
44
|
end
|
41
45
|
|
@@ -49,4 +53,28 @@ module Helpers
|
|
49
53
|
def stub_bundle_install
|
50
54
|
Pulsar::MainCommand.any_instance.stub(:bundle_install)
|
51
55
|
end
|
56
|
+
|
57
|
+
def stub_dotfile(path, options)
|
58
|
+
extended_path = "#{File.expand_path(path)}/.pulsar"
|
59
|
+
dotfile_lines = []
|
60
|
+
|
61
|
+
options.each do |option, value|
|
62
|
+
if value.nil?
|
63
|
+
dotfile_lines << option
|
64
|
+
else
|
65
|
+
dotfile_lines << "#{option}=\"#{value}\"\n"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
File.stub(:file?).and_return(true)
|
70
|
+
File.stub(:readlines).with(extended_path).and_return(dotfile_lines)
|
71
|
+
end
|
72
|
+
|
73
|
+
def tmp_dir
|
74
|
+
"tmp"
|
75
|
+
end
|
76
|
+
|
77
|
+
def tmp_path(dir=tmp_dir)
|
78
|
+
File.join(File.dirname(__FILE__), "..", dir)
|
79
|
+
end
|
52
80
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pulsar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Alberto Vena
|
@@ -10,60 +9,53 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2014-06-23 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: clamp
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- - ~>
|
18
|
+
- - "~>"
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0.5'
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- - ~>
|
25
|
+
- - "~>"
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: '0.5'
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: bundler
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- - ~>
|
32
|
+
- - "~>"
|
37
33
|
- !ruby/object:Gem::Version
|
38
34
|
version: '1.2'
|
39
35
|
type: :runtime
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
|
-
- - ~>
|
39
|
+
- - "~>"
|
45
40
|
- !ruby/object:Gem::Version
|
46
41
|
version: '1.2'
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
43
|
name: colored
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
45
|
requirements:
|
52
|
-
- - ~>
|
46
|
+
- - "~>"
|
53
47
|
- !ruby/object:Gem::Version
|
54
48
|
version: '1.2'
|
55
49
|
type: :runtime
|
56
50
|
prerelease: false
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
52
|
requirements:
|
60
|
-
- - ~>
|
53
|
+
- - "~>"
|
61
54
|
- !ruby/object:Gem::Version
|
62
55
|
version: '1.2'
|
63
56
|
- !ruby/object:Gem::Dependency
|
64
57
|
name: rake
|
65
58
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
59
|
requirements:
|
68
60
|
- - '='
|
69
61
|
- !ruby/object:Gem::Version
|
@@ -71,7 +63,6 @@ dependencies:
|
|
71
63
|
type: :development
|
72
64
|
prerelease: false
|
73
65
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
66
|
requirements:
|
76
67
|
- - '='
|
77
68
|
- !ruby/object:Gem::Version
|
@@ -79,7 +70,6 @@ dependencies:
|
|
79
70
|
- !ruby/object:Gem::Dependency
|
80
71
|
name: rspec
|
81
72
|
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
73
|
requirements:
|
84
74
|
- - '='
|
85
75
|
- !ruby/object:Gem::Version
|
@@ -87,7 +77,6 @@ dependencies:
|
|
87
77
|
type: :development
|
88
78
|
prerelease: false
|
89
79
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
80
|
requirements:
|
92
81
|
- - '='
|
93
82
|
- !ruby/object:Gem::Version
|
@@ -95,7 +84,6 @@ dependencies:
|
|
95
84
|
- !ruby/object:Gem::Dependency
|
96
85
|
name: rr
|
97
86
|
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
87
|
requirements:
|
100
88
|
- - '='
|
101
89
|
- !ruby/object:Gem::Version
|
@@ -103,7 +91,6 @@ dependencies:
|
|
103
91
|
type: :development
|
104
92
|
prerelease: false
|
105
93
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
94
|
requirements:
|
108
95
|
- - '='
|
109
96
|
- !ruby/object:Gem::Version
|
@@ -111,7 +98,6 @@ dependencies:
|
|
111
98
|
- !ruby/object:Gem::Dependency
|
112
99
|
name: coveralls
|
113
100
|
requirement: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
101
|
requirements:
|
116
102
|
- - '='
|
117
103
|
- !ruby/object:Gem::Version
|
@@ -119,7 +105,6 @@ dependencies:
|
|
119
105
|
type: :development
|
120
106
|
prerelease: false
|
121
107
|
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
108
|
requirements:
|
124
109
|
- - '='
|
125
110
|
- !ruby/object:Gem::Version
|
@@ -133,11 +118,11 @@ executables:
|
|
133
118
|
extensions: []
|
134
119
|
extra_rdoc_files: []
|
135
120
|
files:
|
136
|
-
- .gitignore
|
137
|
-
- .rspec
|
138
|
-
- .ruby-gemset
|
139
|
-
- .ruby-version
|
140
|
-
- .travis.yml
|
121
|
+
- ".gitignore"
|
122
|
+
- ".rspec"
|
123
|
+
- ".ruby-gemset"
|
124
|
+
- ".ruby-version"
|
125
|
+
- ".travis.yml"
|
141
126
|
- Gemfile
|
142
127
|
- LICENSE.txt
|
143
128
|
- README.md
|
@@ -200,29 +185,28 @@ files:
|
|
200
185
|
- spec/support/tmp/.gitkeep
|
201
186
|
homepage: http://pulsar.nebulab.it
|
202
187
|
licenses: []
|
188
|
+
metadata: {}
|
203
189
|
post_install_message:
|
204
190
|
rdoc_options: []
|
205
191
|
require_paths:
|
206
192
|
- lib
|
207
193
|
required_ruby_version: !ruby/object:Gem::Requirement
|
208
|
-
none: false
|
209
194
|
requirements:
|
210
|
-
- -
|
195
|
+
- - ">="
|
211
196
|
- !ruby/object:Gem::Version
|
212
197
|
version: '0'
|
213
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
|
-
none: false
|
215
199
|
requirements:
|
216
|
-
- -
|
200
|
+
- - ">="
|
217
201
|
- !ruby/object:Gem::Version
|
218
202
|
version: '0'
|
219
203
|
requirements: []
|
220
204
|
rubyforge_project:
|
221
|
-
rubygems_version:
|
205
|
+
rubygems_version: 2.2.2
|
222
206
|
signing_key:
|
223
|
-
specification_version:
|
207
|
+
specification_version: 4
|
224
208
|
summary: Pulsar helps with Capistrano configuration management. It uses a repository
|
225
|
-
to store all your precious configurations and recipes to build Capistrano
|
209
|
+
to store all your precious configurations and recipes to build Capistrano deploys
|
226
210
|
on it.
|
227
211
|
test_files:
|
228
212
|
- spec/pulsar/commands/init_spec.rb
|