mamiya 0.0.1.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +43 -0
- data/Rakefile +6 -0
- data/bin/mamiya +17 -0
- data/config.example.yml +11 -0
- data/docs/sequences/deploy.png +0 -0
- data/docs/sequences/deploy.uml +58 -0
- data/example.rb +74 -0
- data/lib/mamiya.rb +5 -0
- data/lib/mamiya/agent.rb +181 -0
- data/lib/mamiya/agent/actions.rb +12 -0
- data/lib/mamiya/agent/fetcher.rb +137 -0
- data/lib/mamiya/agent/handlers/abstract.rb +20 -0
- data/lib/mamiya/agent/handlers/fetch.rb +68 -0
- data/lib/mamiya/cli.rb +322 -0
- data/lib/mamiya/cli/client.rb +172 -0
- data/lib/mamiya/config.rb +57 -0
- data/lib/mamiya/dsl.rb +192 -0
- data/lib/mamiya/helpers/git.rb +75 -0
- data/lib/mamiya/logger.rb +190 -0
- data/lib/mamiya/master.rb +118 -0
- data/lib/mamiya/master/agent_monitor.rb +146 -0
- data/lib/mamiya/master/agent_monitor_handlers.rb +44 -0
- data/lib/mamiya/master/web.rb +148 -0
- data/lib/mamiya/package.rb +122 -0
- data/lib/mamiya/script.rb +117 -0
- data/lib/mamiya/steps/abstract.rb +19 -0
- data/lib/mamiya/steps/build.rb +72 -0
- data/lib/mamiya/steps/extract.rb +26 -0
- data/lib/mamiya/steps/fetch.rb +24 -0
- data/lib/mamiya/steps/push.rb +34 -0
- data/lib/mamiya/storages.rb +17 -0
- data/lib/mamiya/storages/abstract.rb +48 -0
- data/lib/mamiya/storages/mock.rb +61 -0
- data/lib/mamiya/storages/s3.rb +127 -0
- data/lib/mamiya/util/label_matcher.rb +38 -0
- data/lib/mamiya/version.rb +3 -0
- data/mamiya.gemspec +35 -0
- data/misc/logger_test.rb +12 -0
- data/spec/agent/actions_spec.rb +37 -0
- data/spec/agent/fetcher_spec.rb +199 -0
- data/spec/agent/handlers/fetch_spec.rb +121 -0
- data/spec/agent_spec.rb +255 -0
- data/spec/config_spec.rb +50 -0
- data/spec/dsl_spec.rb +291 -0
- data/spec/fixtures/dsl_test_load.rb +1 -0
- data/spec/fixtures/dsl_test_use.rb +1 -0
- data/spec/fixtures/helpers/foo.rb +1 -0
- data/spec/fixtures/test-package-source/.mamiya.meta.json +1 -0
- data/spec/fixtures/test-package-source/greeting +1 -0
- data/spec/fixtures/test-package.tar.gz +0 -0
- data/spec/fixtures/test.yml +4 -0
- data/spec/logger_spec.rb +68 -0
- data/spec/master/agent_monitor_spec.rb +269 -0
- data/spec/master/web_spec.rb +121 -0
- data/spec/master_spec.rb +94 -0
- data/spec/package_spec.rb +394 -0
- data/spec/script_spec.rb +78 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/steps/build_spec.rb +261 -0
- data/spec/steps/extract_spec.rb +68 -0
- data/spec/steps/fetch_spec.rb +96 -0
- data/spec/steps/push_spec.rb +73 -0
- data/spec/storages/abstract_spec.rb +22 -0
- data/spec/storages/s3_spec.rb +342 -0
- data/spec/storages_spec.rb +33 -0
- data/spec/support/dummy_serf.rb +70 -0
- data/spec/util/label_matcher_spec.rb +85 -0
- metadata +272 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require 'mamiya/storages/mock'
|
6
|
+
require 'mamiya/package'
|
7
|
+
|
8
|
+
require 'mamiya/master/web'
|
9
|
+
|
10
|
+
describe Mamiya::Master::Web do
|
11
|
+
include Rack::Test::Methods
|
12
|
+
|
13
|
+
let!(:tmpdir) { Dir.mktmpdir('maimya-master-web-spec') }
|
14
|
+
after { FileUtils.remove_entry_secure(tmpdir) }
|
15
|
+
|
16
|
+
let(:app) { described_class }
|
17
|
+
|
18
|
+
let(:config_source) do
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:config) do
|
23
|
+
double('config').tap do |c|
|
24
|
+
allow(c).to receive(:[]) do |k|
|
25
|
+
config_source[k]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:master) do
|
31
|
+
double('master', config: config).tap do |m|
|
32
|
+
allow(m).to receive(:storage) do |app|
|
33
|
+
Mamiya::Storages::Mock.new(application: app)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:package) do
|
39
|
+
File.write File.join(tmpdir, 'mypackage.tar.gz'), "\n"
|
40
|
+
File.write File.join(tmpdir, 'mypackage.json'), "#{{meta: 'data'}.to_json}\n"
|
41
|
+
Mamiya::Package.new(File.join(tmpdir, 'mypackage'))
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
described_class.set :environment, :test
|
46
|
+
|
47
|
+
current_session.envs["rack.logger"] = Mamiya::Logger.new
|
48
|
+
current_session.envs["mamiya.master"] = master
|
49
|
+
|
50
|
+
Mamiya::Storages::Mock.new(application: 'myapp').push(package)
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "GET /" do
|
54
|
+
it "returns text" do
|
55
|
+
get '/'
|
56
|
+
|
57
|
+
expect(last_response.status).to eq 200
|
58
|
+
expect(last_response.body).to match(/^mamiya/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "GET /packages/:application" do
|
63
|
+
it "returns package list" do
|
64
|
+
get '/packages/myapp'
|
65
|
+
|
66
|
+
expect(last_response.status).to eq 200
|
67
|
+
expect(last_response.content_type).to eq 'application/json'
|
68
|
+
json = JSON.parse(last_response.body)
|
69
|
+
expect(json['packages']).to eq ['mypackage']
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns empty list with 204 for inexistence app" do
|
73
|
+
get '/packages/noapp'
|
74
|
+
|
75
|
+
expect(last_response.status).to eq 404
|
76
|
+
expect(last_response.content_type).to eq 'application/json'
|
77
|
+
json = JSON.parse(last_response.body)
|
78
|
+
expect(json['packages']).to eq []
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "GET /packages/:application/:package" do
|
83
|
+
it "returns package detail" do
|
84
|
+
get '/packages/myapp/mypackage'
|
85
|
+
|
86
|
+
expect(last_response.status).to eq 200
|
87
|
+
expect(last_response.content_type).to eq 'application/json'
|
88
|
+
json = JSON.parse(last_response.body)
|
89
|
+
expect(json['application']).to eq 'myapp'
|
90
|
+
expect(json['name']).to eq 'mypackage'
|
91
|
+
expect(json['meta']).to eq('meta' => 'data')
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when not exists" do
|
95
|
+
it "returns 404" do
|
96
|
+
get '/packages/myapp/mypkg'
|
97
|
+
|
98
|
+
expect(last_response.status).to eq 404
|
99
|
+
expect(last_response.content_type).to eq 'application/json'
|
100
|
+
expect(JSON.parse(last_response.body)).to eq({})
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "POST /packages/:application/:package/distribute" do
|
106
|
+
it "dispatchs distribute request" do
|
107
|
+
expect(master).to receive(:distribute).with('myapp', 'mypackage')
|
108
|
+
|
109
|
+
post '/packages/myapp/mypackage/distribute'
|
110
|
+
|
111
|
+
expect(last_response.status).to eq 204 # no content
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when package not found" do
|
115
|
+
it "returns 404" do
|
116
|
+
post '/packages/myapp/noexist/distribute'
|
117
|
+
expect(last_response.status).to eq 404
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/spec/master_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'json'
|
5
|
+
require 'villein/event'
|
6
|
+
|
7
|
+
require 'mamiya/agent'
|
8
|
+
require 'mamiya/storages/mock'
|
9
|
+
|
10
|
+
require 'mamiya/master/agent_monitor'
|
11
|
+
require 'mamiya/master'
|
12
|
+
|
13
|
+
require_relative './support/dummy_serf.rb'
|
14
|
+
|
15
|
+
describe Mamiya::Master do
|
16
|
+
let(:serf) { DummySerf.new }
|
17
|
+
let(:agent_monitor) { double('agent_monitor', start!: nil) }
|
18
|
+
|
19
|
+
let(:config) do
|
20
|
+
{
|
21
|
+
serf: {agent: {rpc_addr: '127.0.0.1:17373', bind: '127.0.0.1:17946'}},
|
22
|
+
web: {port: 0, bind: 'localhost'},
|
23
|
+
storage: {type: :mock},
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(Villein::Agent).to receive(:new).and_return(serf)
|
29
|
+
allow(Mamiya::Master::AgentMonitor).to receive(:new).and_return(agent_monitor)
|
30
|
+
end
|
31
|
+
|
32
|
+
subject(:master) { described_class.new(config) }
|
33
|
+
|
34
|
+
it "inherits Mamiya::Agent" do
|
35
|
+
expect(described_class.superclass).to eq Mamiya::Agent
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#distribute" do
|
39
|
+
# let!(:tmpdir) { Dir.mktmpdir('maimya-master-spec') }
|
40
|
+
# after { FileUtils.remove_entry_secure(tmpdir) }
|
41
|
+
|
42
|
+
# let(:package) do
|
43
|
+
# File.write File.join(tmpdir, 'mypackage.tar.gz'), "\n"
|
44
|
+
# File.write File.join(tmpdir, 'mypackage.json'), "#{{meta: 'data'}.to_json}\n"
|
45
|
+
# Mamiya::Package.new(File.join(tmpdir, 'mypackage'))
|
46
|
+
# end
|
47
|
+
|
48
|
+
# before do
|
49
|
+
# Mamiya::Storages::Mock.new(application: 'myapp').push(package)
|
50
|
+
# end
|
51
|
+
|
52
|
+
it "triggers fetch event" do
|
53
|
+
expect(master).to receive(:trigger).with(:fetch, application: 'myapp', package: 'mypackage')
|
54
|
+
|
55
|
+
master.distribute('myapp', 'mypackage')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "starts agent monitor"
|
60
|
+
|
61
|
+
describe "(member join event)" do
|
62
|
+
it "initiates refresh" do
|
63
|
+
master # initiate
|
64
|
+
|
65
|
+
expect(agent_monitor).to receive(:refresh).with(node: ['the-node', 'another-node'])
|
66
|
+
|
67
|
+
serf.trigger("member_join", Villein::Event.new(
|
68
|
+
{"SERF_EVENT" => "member-join"},
|
69
|
+
payload: "the-node\tX.X.X.X\t\tkey=val,a=b\nanother-node\tY.Y.Y.Y\t\tkey=val,a=b\n"
|
70
|
+
))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#run!" do
|
75
|
+
it "starts serf and web" do
|
76
|
+
begin
|
77
|
+
flag = false
|
78
|
+
|
79
|
+
expect_any_instance_of(Rack::Server).to receive(:start)
|
80
|
+
expect(serf).to receive(:start!)
|
81
|
+
expect(serf).to receive(:auto_stop) do
|
82
|
+
flag = true
|
83
|
+
end
|
84
|
+
|
85
|
+
th = Thread.new { master.run! }
|
86
|
+
th.abort_on_exception = true
|
87
|
+
|
88
|
+
10.times { break if flag; sleep 0.1 }
|
89
|
+
ensure
|
90
|
+
th.kill if th && th.alive?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,394 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'pathname'
|
4
|
+
require 'digest/sha2'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require 'mamiya/package'
|
8
|
+
|
9
|
+
describe Mamiya::Package do
|
10
|
+
let!(:tmpdir) { Dir.mktmpdir("mamiya-package-spec") }
|
11
|
+
after { FileUtils.remove_entry_secure tmpdir }
|
12
|
+
|
13
|
+
let(:build_dir) { Pathname.new(tmpdir).join('build') }
|
14
|
+
let(:extract_dir) { Pathname.new(tmpdir).join('extract') }
|
15
|
+
before do
|
16
|
+
build_dir.mkdir
|
17
|
+
extract_dir.mkdir
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:package_path) { File.join(tmpdir, 'test.tar.gz') }
|
21
|
+
let(:meta_path) { package_path.sub(/tar\.gz$/, "json") }
|
22
|
+
|
23
|
+
let(:arg) { package_path }
|
24
|
+
|
25
|
+
subject(:package) {
|
26
|
+
Mamiya::Package.new(arg)
|
27
|
+
}
|
28
|
+
|
29
|
+
describe "#initialize" do
|
30
|
+
context "without file extension" do
|
31
|
+
it "accepts" do
|
32
|
+
expect { described_class.new('foo') }.not_to raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with .tar.gz" do
|
37
|
+
it "accepts" do
|
38
|
+
expect { described_class.new('foo.tar.gz') }.not_to raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with .json" do
|
43
|
+
it "accepts" do
|
44
|
+
expect { described_class.new('foo.json') }.not_to raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#path" do
|
50
|
+
subject { package.path }
|
51
|
+
it { should eq Pathname.new(package_path) }
|
52
|
+
|
53
|
+
context "without file extension" do
|
54
|
+
let(:arg) { 'test' }
|
55
|
+
it { should eq Pathname.new('test.tar.gz') }
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with .tar.gz" do
|
59
|
+
let(:arg) { 'test.tar.gz' }
|
60
|
+
it { should eq Pathname.new('test.tar.gz') }
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with .json" do
|
64
|
+
let(:arg) { 'test.json' }
|
65
|
+
it { should eq Pathname.new('test.tar.gz') }
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with filename containing dot" do
|
69
|
+
let(:arg) { 'a.b' }
|
70
|
+
it { should eq Pathname.new('a.b.tar.gz') }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#meta_path" do
|
75
|
+
subject { package.meta_path }
|
76
|
+
|
77
|
+
context "without file extension" do
|
78
|
+
let(:arg) { 'test' }
|
79
|
+
it { should eq Pathname.new('test.json') }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with .tar.gz" do
|
83
|
+
let(:arg) { 'test.tar.gz' }
|
84
|
+
it { should eq Pathname.new('test.json') }
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with .json" do
|
88
|
+
let(:arg) { 'test.json' }
|
89
|
+
it { should eq Pathname.new('test.json') }
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with filename containing dot" do
|
93
|
+
let(:arg) { 'a.b' }
|
94
|
+
it { should eq Pathname.new('a.b.json') }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#extract_onto!(path)" do
|
99
|
+
subject { package.extract_onto!(extract_dir) }
|
100
|
+
|
101
|
+
context "with package" do
|
102
|
+
before do
|
103
|
+
File.write build_dir.join("greeting"), "hello\n"
|
104
|
+
Dir.chdir(build_dir) {
|
105
|
+
system "tar", "cjf", package_path, '.'
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when directory exists" do
|
110
|
+
it "extracts onto specified directory" do
|
111
|
+
expect {
|
112
|
+
package.extract_onto!(extract_dir)
|
113
|
+
}.to change {
|
114
|
+
extract_dir.join('greeting').exist?
|
115
|
+
}.from(false).to(true)
|
116
|
+
|
117
|
+
expect(extract_dir.join('greeting').read).to eq "hello\n"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when directory not exists" do
|
122
|
+
before do
|
123
|
+
FileUtils.remove_entry_secure extract_dir
|
124
|
+
end
|
125
|
+
|
126
|
+
it "creates directory" do
|
127
|
+
expect {
|
128
|
+
package.extract_onto!(extract_dir)
|
129
|
+
}.to change {
|
130
|
+
extract_dir.exist?
|
131
|
+
}.from(false).to(true)
|
132
|
+
|
133
|
+
expect(extract_dir.join('greeting').read).to eq "hello\n"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "without package" do
|
139
|
+
it "raises error" do
|
140
|
+
expect {
|
141
|
+
package.extract_onto!(extract_dir)
|
142
|
+
}.to raise_error(Mamiya::Package::NotExists)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#valid?" do
|
148
|
+
subject { package.valid? }
|
149
|
+
|
150
|
+
it "verifies signature"
|
151
|
+
|
152
|
+
context "when checksum is correct" do
|
153
|
+
before do
|
154
|
+
File.write(package_path, "test\n")
|
155
|
+
File.write(meta_path, {"checksum" => Digest::SHA2.hexdigest("test\n")}.to_json + "\n")
|
156
|
+
end
|
157
|
+
|
158
|
+
it { should be_true }
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when checksum is incorrect" do
|
162
|
+
before do
|
163
|
+
File.write(package_path, "wrong\n")
|
164
|
+
File.write(meta_path, {"checksum" => Digest::SHA2.hexdigest("text\n")}.to_json + "\n")
|
165
|
+
end
|
166
|
+
|
167
|
+
it { should be_false }
|
168
|
+
end
|
169
|
+
|
170
|
+
context "when package not exists" do
|
171
|
+
it "raises error" do
|
172
|
+
expect { subject }.to raise_error(Mamiya::Package::NotExists)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "when package meta json not exists" do
|
177
|
+
before do
|
178
|
+
File.write package_path, "\n"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "raises error" do
|
182
|
+
expect { subject }.to raise_error(Mamiya::Package::NotExists)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#name" do
|
188
|
+
subject { package.name }
|
189
|
+
|
190
|
+
it { should eq 'test' }
|
191
|
+
|
192
|
+
context "when meta['name'] exists" do
|
193
|
+
before do
|
194
|
+
package.meta['name'] = 'pack'
|
195
|
+
end
|
196
|
+
|
197
|
+
it { should eq 'pack' }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "#application" do
|
202
|
+
subject { package.application }
|
203
|
+
|
204
|
+
it { should eq nil }
|
205
|
+
|
206
|
+
context "when meta['application'] exists" do
|
207
|
+
before do
|
208
|
+
package.meta['application'] = 'app'
|
209
|
+
end
|
210
|
+
|
211
|
+
it { should eq 'app' }
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "#checksum" do
|
216
|
+
subject { package.checksum }
|
217
|
+
|
218
|
+
it { should be_nil }
|
219
|
+
|
220
|
+
context "when package exists" do
|
221
|
+
before do
|
222
|
+
File.write package_path, "text\n"
|
223
|
+
end
|
224
|
+
|
225
|
+
it { should eq Digest::SHA2.hexdigest("text\n") }
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe "#exists?" do
|
230
|
+
subject { package.exists? }
|
231
|
+
|
232
|
+
context "when package exists" do
|
233
|
+
before do
|
234
|
+
File.write package_path, ''
|
235
|
+
end
|
236
|
+
|
237
|
+
it { should be_true }
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when package not exists" do
|
241
|
+
before do
|
242
|
+
File.unlink(package_path) if File.exists?(package_path)
|
243
|
+
end
|
244
|
+
|
245
|
+
it { should be_false }
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe "#sign!" do
|
250
|
+
it "signs package"
|
251
|
+
end
|
252
|
+
|
253
|
+
describe "#build!(build_dir)" do
|
254
|
+
let(:dereference_symlinks) { nil }
|
255
|
+
let(:exclude_from_package) { nil }
|
256
|
+
let(:package_under) { nil }
|
257
|
+
|
258
|
+
let(:build) {
|
259
|
+
kwargs = {}
|
260
|
+
kwargs[:dereference_symlinks] = dereference_symlinks unless dereference_symlinks.nil?
|
261
|
+
kwargs[:exclude_from_package] = exclude_from_package unless exclude_from_package.nil?
|
262
|
+
kwargs[:package_under] = package_under unless package_under.nil?
|
263
|
+
package.build!(
|
264
|
+
build_dir,
|
265
|
+
**kwargs
|
266
|
+
)
|
267
|
+
}
|
268
|
+
|
269
|
+
before do
|
270
|
+
File.write(build_dir.join('greeting'), 'hello')
|
271
|
+
end
|
272
|
+
|
273
|
+
def build_then_extract!
|
274
|
+
build
|
275
|
+
|
276
|
+
expect(Pathname.new(package_path)).not_to be_nil
|
277
|
+
|
278
|
+
system "tar", "xf", package_path, "-C", extract_dir.to_s
|
279
|
+
end
|
280
|
+
|
281
|
+
it "creates a package to path" do
|
282
|
+
expect {
|
283
|
+
build
|
284
|
+
}.to change {
|
285
|
+
File.exist? package_path
|
286
|
+
}.from(false).to(true)
|
287
|
+
end
|
288
|
+
|
289
|
+
it "includes file in build_dir" do
|
290
|
+
build_then_extract!
|
291
|
+
expect(extract_dir.join('greeting').read).to eq 'hello'
|
292
|
+
end
|
293
|
+
|
294
|
+
it "excludes SCM directories" do
|
295
|
+
build_dir.join('.git').mkdir
|
296
|
+
File.write build_dir.join('.git', 'test'), "test\n"
|
297
|
+
build_then_extract!
|
298
|
+
|
299
|
+
expect(extract_dir.join('.git')).not_to be_exist
|
300
|
+
end
|
301
|
+
|
302
|
+
it "includes deploy script itself"
|
303
|
+
|
304
|
+
it "saves meta file" do
|
305
|
+
package.meta = {"a" => 1, "b" => {"c" => ["d", "e"]}}
|
306
|
+
packed_meta = package.meta.dup
|
307
|
+
|
308
|
+
build_then_extract!
|
309
|
+
|
310
|
+
expect(package.meta["checksum"]).to eq Digest::SHA2.file(package_path).hexdigest
|
311
|
+
|
312
|
+
meta_path_in_build = extract_dir.join('.mamiya.meta.json')
|
313
|
+
packed_meta['name'] = package.meta['name']
|
314
|
+
json = JSON.parse(File.read(meta_path_in_build))
|
315
|
+
expect(json).to eq JSON.parse(packed_meta.to_json)
|
316
|
+
|
317
|
+
json = JSON.parse(File.read(meta_path))
|
318
|
+
expect(json).to eq JSON.parse(package.meta.to_json)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "doesn't leave meta file in build_dir" do
|
322
|
+
package.meta = {"a" => 1, "b" => {"c" => ["d", "e"]}}
|
323
|
+
build
|
324
|
+
|
325
|
+
expect(build_dir.join('.mamiya.meta.json')).not_to be_exist
|
326
|
+
end
|
327
|
+
|
328
|
+
context "with exclude_from_package option" do
|
329
|
+
let(:exclude_from_package) { ['foo', 'hoge*'] }
|
330
|
+
|
331
|
+
before do
|
332
|
+
File.write build_dir.join('foo'), "test\n"
|
333
|
+
File.write build_dir.join('hogefuga'), "test\n"
|
334
|
+
|
335
|
+
build_then_extract!
|
336
|
+
end
|
337
|
+
|
338
|
+
it "excludes matched files from package" do
|
339
|
+
expect(extract_dir.join('foo')).not_to be_exist
|
340
|
+
expect(extract_dir.join('hogefuga')).not_to be_exist
|
341
|
+
|
342
|
+
expect(extract_dir.join('greeting').read).to eq 'hello'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
context "with package_under option" do
|
347
|
+
let(:package_under) { 'dir' }
|
348
|
+
|
349
|
+
before do
|
350
|
+
build_dir.join('dir').mkdir
|
351
|
+
|
352
|
+
File.write build_dir.join('root'), "shouldnt-be-included\n"
|
353
|
+
File.write build_dir.join('dir', 'greeting'), "hola\n"
|
354
|
+
|
355
|
+
build_then_extract!
|
356
|
+
end
|
357
|
+
|
358
|
+
it "packages under specified directory" do
|
359
|
+
expect(extract_dir.join('root')).not_to be_exist
|
360
|
+
expect(extract_dir.join('greeting').read).to eq "hola\n"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context "with dereference_symlinks option" do
|
365
|
+
before do
|
366
|
+
File.write build_dir.join('target'), "I am target\n"
|
367
|
+
build_dir.join('alias').make_symlink('target')
|
368
|
+
|
369
|
+
build_then_extract!
|
370
|
+
end
|
371
|
+
|
372
|
+
context "when the option is true" do
|
373
|
+
let(:dereference_symlinks) { true }
|
374
|
+
|
375
|
+
it "dereferences symlinks for package" do
|
376
|
+
expect(extract_dir.join('alias')).to be_exist
|
377
|
+
expect(extract_dir.join('alias')).not_to be_symlink
|
378
|
+
expect(extract_dir.join('alias').read).to eq "I am target\n"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
context "when the option is false" do
|
383
|
+
let(:dereference_symlinks) { false }
|
384
|
+
|
385
|
+
it "doesn't dereference symlinks" do
|
386
|
+
expect(extract_dir.join('alias')).to be_exist
|
387
|
+
expect(extract_dir.join('alias')).to be_symlink
|
388
|
+
realpath = extract_dir.join('alias').realpath.relative_path_from(extract_dir.realpath).to_s
|
389
|
+
expect(realpath).to eq 'target'
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|