cany 0.0.2 → 0.1.0
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/CHANGELOG.md +38 -0
- data/Gemfile +12 -0
- data/Guardfile +20 -0
- data/Rakefile +11 -0
- data/lib/cany.rb +88 -19
- data/lib/cany/dependency.rb +70 -0
- data/lib/cany/dpkg/builder.rb +4 -16
- data/lib/cany/dpkg/creator.rb +39 -29
- data/lib/cany/dpkg/deb_helper_recipe.rb +105 -20
- data/lib/cany/errors.rb +62 -0
- data/lib/cany/mixins/depend_mixin.rb +22 -0
- data/lib/cany/recipe.rb +182 -11
- data/lib/cany/recipes/bundler.rb +28 -5
- data/lib/cany/recipes/bundler/gem.rb +50 -0
- data/lib/cany/recipes/bundler/gem_db.rb +27 -0
- data/lib/cany/recipes/rails.rb +19 -2
- data/lib/cany/recipes/sidekiq.rb +38 -0
- data/lib/cany/recipes/thin.rb +24 -18
- data/lib/cany/recipes/unicorn.rb +16 -0
- data/lib/cany/recipes/web_server.rb +5 -19
- data/lib/cany/specification.rb +49 -1
- data/lib/cany/specification/dsl.rb +23 -3
- data/lib/cany/version.rb +2 -2
- data/spec/cany/dependency_spec.rb +120 -0
- data/spec/cany/dpkg/builder_spec.rb +38 -0
- data/spec/{dpkg → cany/dpkg}/creator_spec.rb +26 -2
- data/spec/cany/dpkg/deb_helper_recipe_spec.rb +91 -0
- data/spec/cany/recipe_spec.rb +213 -0
- data/spec/cany/recipes/bundler/gem_spec.rb +46 -0
- data/spec/cany/recipes/bundler_spec.rb +29 -0
- data/spec/cany/recipes/rails_spec.rb +28 -0
- data/spec/cany/recipes/sidekiq_spec.rb +52 -0
- data/spec/cany/specification_spec.rb +113 -1
- data/spec/spec_helper.rb +31 -4
- metadata +29 -6
- data/spec/dpkg/builder_spec.rb +0 -53
@@ -20,6 +20,11 @@ describe Cany::Dpkg::Creator do
|
|
20
20
|
end
|
21
21
|
let(:run) { Cany::Dpkg::Creator.new(spec).run *(@run_args || []) }
|
22
22
|
|
23
|
+
it 'should set the system recipe' do
|
24
|
+
expect(spec).to receive(:system_recipe=).with(kind_of(Cany::Dpkg::DebHelperRecipe)).and_call_original
|
25
|
+
run
|
26
|
+
end
|
27
|
+
|
23
28
|
context 'debian directory' do
|
24
29
|
subject { File.join dir, 'debian' }
|
25
30
|
|
@@ -45,7 +50,7 @@ describe Cany::Dpkg::Creator do
|
|
45
50
|
it do
|
46
51
|
run
|
47
52
|
expect(subject).to be_a_file
|
48
|
-
expect(subject).to have_the_content '
|
53
|
+
expect(subject).to have_the_content '9'
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -128,7 +133,10 @@ describe Cany::Dpkg::Creator do
|
|
128
133
|
end
|
129
134
|
|
130
135
|
it 'should add extra deps in specific gems are used' do
|
131
|
-
FileUtils.copy File.expand_path('
|
136
|
+
FileUtils.copy File.expand_path('../../../fixtures/testgem.lock', __FILE__), File.join(dir, 'Gemfile.lock')
|
137
|
+
spec.setup do
|
138
|
+
use :bundler
|
139
|
+
end
|
132
140
|
run
|
133
141
|
expect(subject.paragraphs.size).to eq 2
|
134
142
|
source =
|
@@ -200,6 +208,22 @@ describe Cany::Dpkg::Creator do
|
|
200
208
|
expect(subject).to include "\truby1.9.1 -S cany dpkg-builder $@"
|
201
209
|
expect(subject).to include "\truby1.9.1 -cS cany >/dev/null || ruby1.9.1 -S gem install --no-ri --no-rdoc --install-dir debian/gems --bindir debian/bin $${CANY_GEM:-cany}"
|
202
210
|
end
|
211
|
+
|
212
|
+
it 'should contain cany version constraint' do
|
213
|
+
expect(Cany::VERSION).to receive(:to_s).and_return('0.1').at_least(:once)
|
214
|
+
spec.setup { require_cany '~> 0.1' }
|
215
|
+
run
|
216
|
+
|
217
|
+
should match /gem install.+ \$\${CANY_GEM:-cany}.+--version "~> 0\.1"/
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should allow pre cany versions if the contraint contain characters' do
|
221
|
+
expect(Cany::VERSION).to receive(:to_s).and_return('0.1.rc2').at_least(:once)
|
222
|
+
spec.setup { require_cany '~> 0.1.rc1' }
|
223
|
+
run
|
224
|
+
|
225
|
+
should match /gem install.+ \$\${CANY_GEM:-cany}.+--version "~> 0\.1\.rc1" --prerelease/
|
226
|
+
end
|
203
227
|
end
|
204
228
|
|
205
229
|
context 'changelog file' do
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cany::Dpkg::DebHelperRecipe do
|
4
|
+
let!(:dir) { Dir.mktmpdir }
|
5
|
+
before do
|
6
|
+
Dir.mkdir File.join(dir, 'debian')
|
7
|
+
@old_path = Dir.pwd
|
8
|
+
Dir.chdir(dir)
|
9
|
+
end
|
10
|
+
after do
|
11
|
+
Dir.chdir @old_path
|
12
|
+
FileUtils.remove_entry dir
|
13
|
+
end
|
14
|
+
let(:spec) do
|
15
|
+
s = Cany::Specification.new do
|
16
|
+
name 'test'
|
17
|
+
description 'Your RSpec Upstart-Scripts'
|
18
|
+
end
|
19
|
+
s.base_dir = dir
|
20
|
+
s
|
21
|
+
end
|
22
|
+
let(:recipe) { described_class.new spec }
|
23
|
+
subject { recipe }
|
24
|
+
|
25
|
+
describe '#binary' do
|
26
|
+
it 'should install services' do
|
27
|
+
should receive(:install_services)
|
28
|
+
subject.binary
|
29
|
+
end
|
30
|
+
it 'should install base service' do
|
31
|
+
should receive(:install_base_service)
|
32
|
+
subject.binary
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#install_services' do
|
37
|
+
before do
|
38
|
+
recipe.install_service :service, %w(hans args1), user: 'www-data', group: 'www-data'
|
39
|
+
recipe.install_services
|
40
|
+
end
|
41
|
+
subject { File.read File.join(dir, 'debian', 'test.test-service.upstart') }
|
42
|
+
|
43
|
+
it 'should create files' do
|
44
|
+
should eq <<EOF
|
45
|
+
description "Your RSpec Upstart-Scripts - service"
|
46
|
+
|
47
|
+
start on started test
|
48
|
+
stop on stopping test
|
49
|
+
|
50
|
+
respawn
|
51
|
+
respawn limit 10 5
|
52
|
+
umask 022
|
53
|
+
|
54
|
+
chdir /usr/share/test
|
55
|
+
|
56
|
+
setuid www-data
|
57
|
+
setgid www-data
|
58
|
+
|
59
|
+
exec hans args1
|
60
|
+
EOF
|
61
|
+
expect(@executed_programs).to match_array [['dh_installinit', '--name', 'test-service']]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#install_base_services' do
|
66
|
+
before do
|
67
|
+
recipe.configure :service_pre_scripts, mkdir_run: "mkdir /var/run/#{spec.name}", chown_run: "chown www-data /var/run/#{spec.name}"
|
68
|
+
Dir.chdir(dir) { recipe.install_base_service }
|
69
|
+
end
|
70
|
+
subject { File.read File.join(dir, 'debian', 'test.upstart') }
|
71
|
+
it 'should create files' do
|
72
|
+
should eq <<EOF
|
73
|
+
description "Your RSpec Upstart-Scripts"
|
74
|
+
|
75
|
+
start on filesystem or runlevel [2345]
|
76
|
+
stop on runlevel [!2345]
|
77
|
+
|
78
|
+
respawn
|
79
|
+
respawn limit 10 5
|
80
|
+
umask 022
|
81
|
+
|
82
|
+
pre-start script
|
83
|
+
mkdir /var/run/test
|
84
|
+
chown www-data /var/run/test
|
85
|
+
end script
|
86
|
+
|
87
|
+
exec sleep 1d
|
88
|
+
EOF
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cany::Recipe do
|
4
|
+
let(:spec) do
|
5
|
+
Cany::Specification.new do
|
6
|
+
name 'test-spec'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
let(:recipe) { Cany::Recipe.new(spec) }
|
10
|
+
let(:test_recipe) { TestRecipe.new(spec) }
|
11
|
+
|
12
|
+
describe '#exec' do
|
13
|
+
it 'should execute system command' do
|
14
|
+
expect(recipe).to receive(:system).with('a', 'b', 'c').and_return true
|
15
|
+
recipe.exec_('a', 'b', 'c')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should flatten the passed arguments' do
|
19
|
+
expect(recipe).to receive(:system).with('a', 'b', 'c').and_return true
|
20
|
+
recipe.exec_(%w(a b c))
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should flatten the passed arguments #2' do
|
24
|
+
expect(recipe).to receive(:system).with('a', 'b', 'c', 'd', 'e', 'f').and_return true
|
25
|
+
recipe.exec_('a', %w(b c), 'd', ['e', 'f'])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should raise an exception on failed program execution' do
|
29
|
+
expect { recipe.exec_ 'false' }.to raise_exception Cany::CommandExecutionFailed, /Could not execute.*false/
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should raise an exception on failed program execution with args' do
|
33
|
+
expect { recipe.exec_ %w(false 4) }.to raise_exception Cany::CommandExecutionFailed, /Could not execute.*false 4/
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'hook handling' do
|
38
|
+
it 'should raise an error on an unknown hooks' do
|
39
|
+
expect { recipe.run_hook :test, :after }.to raise_exception Cany::UnknownHook, /Unknown hook.*test/
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should handle hooks without defined block' do
|
43
|
+
test_recipe.run_hook :test_hook, :after
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should passed block for hook' do
|
47
|
+
expect(Cany).to receive(:hook_executed)
|
48
|
+
spec.setup do
|
49
|
+
use :test_recipe do
|
50
|
+
before :test_hook do
|
51
|
+
Cany.hook_executed
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
spec.recipes[0].run_hook :test_hook, :before
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'hook should be limited to recipe' do
|
59
|
+
expect do
|
60
|
+
spec.setup do
|
61
|
+
use :bundler do
|
62
|
+
before :test_hook do
|
63
|
+
Dummy.hook_executed
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end.to raise_exception Cany::UnknownHook, /Unknown hook.*test_hook/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'recipe configure options' do
|
72
|
+
let(:option_name) { :test_conf }
|
73
|
+
subject { test_recipe.option option_name }
|
74
|
+
|
75
|
+
context 'with an undefined config' do
|
76
|
+
let(:option_name) { :unknown_option }
|
77
|
+
it 'should raise an exception' do
|
78
|
+
expect { subject }.to raise_exception Cany::UnknownOption, /Unknown option .*unknown_option/
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'with a defined config' do
|
83
|
+
let(:recipe2) { Cany::Recipe.new(spec) }
|
84
|
+
it 'should be initialized with {} per default' do
|
85
|
+
expect(subject).to eq Hash.new
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'should be configurable' do
|
89
|
+
before do
|
90
|
+
test_recipe.configure :test_conf, env: 'production'
|
91
|
+
end
|
92
|
+
it { expect(subject).to eq(env: 'production') }
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'options should be merged between multiple calls' do
|
96
|
+
before do
|
97
|
+
test_recipe.configure :test_conf, env: 'production'
|
98
|
+
test_recipe.configure :test_conf, env2: 'hans'
|
99
|
+
end
|
100
|
+
it { expect(subject).to eq(env: 'production', env2: 'hans') }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#recipe' do
|
106
|
+
let(:other_recipe) { :test_recipe }
|
107
|
+
subject { recipe.recipe other_recipe }
|
108
|
+
context 'to access other loaded recipe' do
|
109
|
+
before { spec.setup { use :test_recipe } }
|
110
|
+
it 'should return the recipe instance from this specification' do
|
111
|
+
expect(subject).to be spec.recipes.first
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'to access an unloaded recipe' do
|
116
|
+
it 'should raise an exception' do
|
117
|
+
expect { subject }.to raise_exception Cany::UnloadedRecipe, /[Rr]ecipe.+test_recipe.+no.+loaded/
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'to access an unknown recipe' do
|
122
|
+
let(:other_recipe) { :unknown_recipe }
|
123
|
+
it 'should raise an exception' do
|
124
|
+
expect { subject }.to raise_exception Cany::UnknownRecipe, /[Rr]ecipe.+unknown_recipe.+not.+registered./
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#depend' do
|
130
|
+
subject { spec.dependencies }
|
131
|
+
|
132
|
+
context 'without any call' do
|
133
|
+
it 'it should be empty' do
|
134
|
+
should eq []
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'with a single string' do
|
139
|
+
subject { super().first }
|
140
|
+
|
141
|
+
context 'without other options' do
|
142
|
+
before { recipe.depend 'hans-otto-lib' }
|
143
|
+
it 'should converted into a runtime dependency object' do
|
144
|
+
should be_instance_of Cany::Dependency
|
145
|
+
should be_runtime
|
146
|
+
should_not be_build
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'with situation option' do
|
151
|
+
before { recipe.depend 'hans-otto-lib', situation: :build }
|
152
|
+
it 'should converted into a runtime dependency object' do
|
153
|
+
should be_instance_of Cany::Dependency
|
154
|
+
should_not be_runtime
|
155
|
+
should be_build
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'with a version option' do
|
160
|
+
before { recipe.depend 'hans-otto', version: '>= 4' }
|
161
|
+
it 'should be convert' do
|
162
|
+
should be_instance_of Cany::Dependency
|
163
|
+
expect(subject.determine(:a, :b)).to match_array [['hans-otto', '>= 4']]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
context 'with a dependency object' do
|
168
|
+
let(:dep) { Cany::Dependency.new }
|
169
|
+
subject { super().first }
|
170
|
+
before { recipe.depend dep }
|
171
|
+
it 'should be passed without modification' do
|
172
|
+
should eq dep
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context '#name' do
|
178
|
+
context 'on an unregistered recipe' do
|
179
|
+
subject { recipe.name }
|
180
|
+
it 'should raise a NoMethodError' do
|
181
|
+
expect { subject }.to raise_exception NoMethodError
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'on a registered recipe' do
|
186
|
+
subject { test_recipe.name }
|
187
|
+
it 'should return its registered name' do
|
188
|
+
should eq :test_recipe
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context '#install_service' do
|
194
|
+
let(:name) { :test }
|
195
|
+
let(:command) { :command }
|
196
|
+
let(:opts) { {} }
|
197
|
+
subject { recipe.install_service name, command, opts }
|
198
|
+
|
199
|
+
context 'on recipe without loaded system recipe' do
|
200
|
+
it 'should raise an exception' do
|
201
|
+
expect { subject }.to raise_exception Cany::NoSystemRecipe
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'with loaded deb helper recipe' do
|
206
|
+
before { spec.system_recipe = Cany::Dpkg::DebHelperRecipe.new spec }
|
207
|
+
it 'should pass call to system recipe' do
|
208
|
+
expect_any_instance_of(Cany::Dpkg::DebHelperRecipe).to receive(:install_service).with(name, command, opts)
|
209
|
+
subject
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cany::Recipes::Bundler::Gem do
|
4
|
+
let(:gem_name) { :bundler }
|
5
|
+
subject { described_class.get gem_name }
|
6
|
+
context '#get' do
|
7
|
+
it 'should return always the same instance per gem' do
|
8
|
+
should be_instance_of described_class
|
9
|
+
expect(subject).to eq described_class.get gem_name
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return different instances for different gems' do
|
13
|
+
should_not eq described_class.get :bundler2
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'returned gem instance' do
|
17
|
+
context '\s gem_name' do
|
18
|
+
subject { super().name }
|
19
|
+
it { eq gem_name }
|
20
|
+
end
|
21
|
+
|
22
|
+
context '\' dependencies' do
|
23
|
+
subject { super().dependencies }
|
24
|
+
it 'should be empty per default' do
|
25
|
+
should match_array []
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#specify' do
|
32
|
+
subject { super().dependencies.first }
|
33
|
+
let(:default) { subject.determine(:a, :b).first }
|
34
|
+
context 'with added dependencies' do
|
35
|
+
before do
|
36
|
+
described_class.specify gem_name do
|
37
|
+
depend 'hans_otto'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
it 'should added as runtime dependencies' do
|
41
|
+
should be_runtime
|
42
|
+
expect(default).to match_array [ 'hans_otto', nil]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cany::Recipes::Bundler do
|
4
|
+
let(:spec) do
|
5
|
+
Cany::Specification.new do
|
6
|
+
name 'test'
|
7
|
+
use :bundler
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:recipe) { spec.recipes[0] }
|
11
|
+
before { recipe.prepare }
|
12
|
+
|
13
|
+
context 'wrapper-script' do
|
14
|
+
subject { recipe.wrapper_script }
|
15
|
+
context 'without additional env variables' do
|
16
|
+
it 'should contain GEM_PATH to find bundler' do
|
17
|
+
expect(subject).to include('export GEM_PATH="bundler"')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with additional env variables' do
|
22
|
+
before { recipe.configure :env_vars, RAILS_ENV: 'production' }
|
23
|
+
it 'should contain all environment variables' do
|
24
|
+
expect(subject).to include('export GEM_PATH="bundler"')
|
25
|
+
expect(subject).to include('export RAILS_ENV="production"')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cany::Recipes::Rails do
|
4
|
+
describe 'DSL' do
|
5
|
+
let(:spec) do
|
6
|
+
Cany::Specification.new do
|
7
|
+
name 'test'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:recipe) { spec.recipes[0] }
|
11
|
+
|
12
|
+
it 'should compile assets by default' do
|
13
|
+
spec.setup do
|
14
|
+
use :rails
|
15
|
+
end
|
16
|
+
expect(recipe.compile_assets).to eq true
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be able to disable assets compilation' do
|
20
|
+
spec.setup do
|
21
|
+
use :rails do
|
22
|
+
compile_assets false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
expect(recipe.compile_assets).to eq false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|