dockerize 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+
3
+ unless defined?(Dockerize::VERSION)
4
+ module Dockerize
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
data/lib/dockerize.rb ADDED
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+ require 'dockerize/version'
3
+
4
+ module Dockerize
5
+ autoload :VERSION, 'dockerize/version'
6
+ autoload :Cli, 'dockerize/cli'
7
+ autoload :Config, 'dockerize/config'
8
+ autoload :Error, 'dockerize/error'
9
+ end
@@ -0,0 +1,94 @@
1
+ # coding: utf-8
2
+
3
+ require 'dockerize/cli'
4
+ require 'dockerize/error'
5
+
6
+ describe Dockerize::Cli do
7
+ let(:config) { Dockerize::Config }
8
+ let(:cli) { Dockerize::Cli }
9
+
10
+ describe 'accepting arguments' do
11
+ it 'explodes if no arguments are provided' do
12
+ expect { run }.to raise_error(
13
+ Dockerize::Error::MissingRequiredArgument
14
+ )
15
+ end
16
+
17
+ it 'does not explode if at least one argument is provided' do
18
+ tmpdir do |tmp|
19
+ expect { run tmp }.to_not raise_error
20
+ end
21
+ end
22
+ end
23
+
24
+ describe 'setting the project directory' do
25
+ let(:pwd) { Dir.pwd }
26
+
27
+ context 'command line arguments are provided' do
28
+ it 'sets the project dir to PWD when a . is specified' do
29
+ run '.'
30
+ config.project_dir.should == pwd
31
+ end
32
+
33
+ it 'sets the project dir to the first argument provided' do
34
+ tmpdir do |tmp|
35
+ run tmp
36
+ config.project_dir.should == tmp
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'parsing templates' do
43
+ let(:filename) { 'foo' }
44
+ let(:template) do
45
+ <<-EOB.gsub(/^ +/, '')
46
+ <% self.filename = '#{filename}' -%>
47
+ <% self.filter = 'Baxter the Dog' -%>
48
+ <% self.foo = 'pasta' -%>
49
+ <% self.executable = true -%>
50
+ This is the first line
51
+
52
+ This is the second line
53
+
54
+ This has some erb interpolation: "<%= foo %>"
55
+ EOB
56
+ end
57
+ let(:parsed_template) do
58
+ <<-EOB.gsub(/^ +/, '')
59
+ This is the first line
60
+
61
+ This is the second line
62
+
63
+ This has some erb interpolation: "pasta"
64
+ EOB
65
+ end
66
+
67
+ it 'writes files from the given templates' do
68
+ tmpdir do |project_dir|
69
+ tmpdir do |template_dir|
70
+ File.open("#{template_dir}/template.erb", 'w+') do |f|
71
+ f.puts template
72
+ end
73
+ run "#{project_dir} --template-dir #{template_dir}"
74
+ expect { cli.send(:handle_templates) }.to change {
75
+ File.exists?("#{project_dir}/#{filename}")
76
+ }
77
+ end
78
+ end
79
+ end
80
+
81
+ it 'writes correct content to the target files' do
82
+ tmpdir do |project_dir|
83
+ tmpdir do |template_dir|
84
+ File.open("#{template_dir}/template.erb", 'w+') do |f|
85
+ f.puts template
86
+ end
87
+ run "#{project_dir} --template-dir #{template_dir}"
88
+ cli.send(:handle_templates)
89
+ File.read("#{project_dir}/#{filename}").should == parsed_template
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,162 @@
1
+ # coding: utf-8
2
+
3
+ require 'tmpdir'
4
+ require 'dockerize/config'
5
+ require 'dockerize/error'
6
+
7
+ describe Dockerize::Config do
8
+ subject(:config) { described_class }
9
+
10
+ describe 'configuring the project directory' do
11
+ it 'specifies a project directory' do
12
+ config.should respond_to(:project_dir=)
13
+ end
14
+
15
+ context 'assigning a project directory' do
16
+ let(:bogus_dir) { '/foobarbaz' }
17
+
18
+ it 'explodes when the project directory does not exist' do
19
+ expect { described_class.project_dir = bogus_dir }.to raise_error(
20
+ Dockerize::Error::NonexistentProjectDirectory
21
+ )
22
+ end
23
+
24
+ it 'explodes when the project directory is not a directory' do
25
+ expect { described_class.project_dir = $PROGRAM_NAME }.to raise_error(
26
+ Dockerize::Error::InvalidProjectDirectory
27
+ )
28
+ end
29
+
30
+ it 'does not explode if the project directory is valid' do
31
+ tmpdir do |tmp|
32
+ expect { described_class.project_dir = tmp }.to_not raise_error
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'accepting options' do
39
+ describe 'dry-run' do
40
+ %w(-d --dry-run).each do |arg|
41
+ it "sets dry-run for #{arg}" do
42
+ run ". #{arg}"
43
+ config.dry_run?.should == true
44
+ end
45
+ end
46
+
47
+ it 'turns dry run off for --no-dry-run' do
48
+ run '. --no-dry-run'
49
+ config.dry_run?.should == false
50
+ end
51
+
52
+ it 'defaults dry run to off' do
53
+ run '.'
54
+ config.dry_run?.should == false
55
+ end
56
+ end
57
+
58
+ describe 'quiet' do
59
+ %w(-q --quiet).each do |arg|
60
+ it "sets quiet for #{arg}" do
61
+ run ". #{arg}"
62
+ config.quiet?.should == true
63
+ end
64
+ end
65
+
66
+ it 'sets no quiet for --no-quiet' do
67
+ run '. --no-quiet'
68
+ config.quiet?.should == false
69
+ end
70
+
71
+ it 'sets no quiet when when specified' do
72
+ run '.'
73
+ config.quiet?.should == false
74
+ end
75
+ end
76
+
77
+ describe 'force' do
78
+ %w(-f --force).each do |arg|
79
+ it "sets force for #{arg}" do
80
+ run ". #{arg}"
81
+ config.force?.should == true
82
+ end
83
+ end
84
+
85
+ it 'sets no force for --no-force' do
86
+ run '. --no-force'
87
+ config.force?.should == false
88
+ end
89
+
90
+ it 'sets no force when when specified' do
91
+ run '.'
92
+ config.force?.should == false
93
+ end
94
+ end
95
+
96
+ describe 'version' do
97
+ let(:version) { Dockerize::VERSION }
98
+
99
+ %w(-v --version).each do |arg|
100
+ it "prints the version with #{arg}" do
101
+ $stderr.should_receive(:puts).with("dockerize #{version}")
102
+ expect { run arg }.to raise_error(SystemExit)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe 'backup' do
108
+ %w(-b --backup).each do |arg|
109
+ it "sets backup for #{arg}" do
110
+ run ". #{arg}"
111
+ config.backup?.should == true
112
+ end
113
+ end
114
+
115
+ it 'sets no backup for --no-backup' do
116
+ run '. --no-backup'
117
+ config.backup?.should == false
118
+ end
119
+
120
+ it 'sets backup by default' do
121
+ run '.'
122
+ config.backup?.should == true
123
+ end
124
+ end
125
+
126
+ describe 'registry' do
127
+ let(:registry) { 'foo' }
128
+
129
+ %w(-r --registry).each do |arg|
130
+ it "sets registry for #{arg}" do
131
+ run ". #{arg} #{registry}"
132
+ config.registry.should == registry
133
+ end
134
+ end
135
+
136
+ it 'sets modcloth registry by default' do
137
+ run '.'
138
+ config.registry.should == 'quay.io/modcloth'
139
+ end
140
+ end
141
+
142
+ describe 'template_dir' do
143
+ it 'sets the default template dir to the top level' do
144
+ run '.'
145
+ config.template_dir.should == "#{top}/templates"
146
+ end
147
+ end
148
+ end
149
+
150
+ describe 'accepting options from the environment' do
151
+ %w(registry template_dir maintainer from).map do |var|
152
+ before(:each) do
153
+ ENV.stub(:[]).with("DOCKERIZE_#{var.upcase}").and_return('foo')
154
+ end
155
+
156
+ it "accepts #{var} from the environment" do
157
+ run '.'
158
+ config.send(var.to_sym).should == 'foo'
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,254 @@
1
+ # coding: utf-8
2
+
3
+ require 'dockerize/document_writer'
4
+ require 'fileutils'
5
+
6
+ describe Dockerize::DocumentWriter do
7
+ let(:writer) { described_class.new }
8
+
9
+ describe 'determining file path to write' do
10
+ context 'no document_name is specified' do
11
+ it 'raises an error' do
12
+ run '.'
13
+ expect { writer.output_target }.to raise_error(
14
+ Dockerize::Error::DocumentNameNotSpecified
15
+ )
16
+ end
17
+ end
18
+
19
+ context 'document name is specified' do
20
+ it 'produces the correct document path' do
21
+ tmpdir do |tmp|
22
+ run tmp
23
+ writer.stub(:document_name).and_return('foo_file')
24
+ writer.output_target.should == "#{tmp}/foo_file"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'determining if the file should be written' do
31
+ let(:filename) { 'foo_file' }
32
+ let(:backup_filename) { 'foo_file.bak' }
33
+ let(:content) { '12345' }
34
+
35
+ before(:each) { writer.stub(:document_name).and_return(filename) }
36
+
37
+ context 'without force' do
38
+ context 'the file already exists' do
39
+ it 'does not modify the existing file' do
40
+ tmpdir do |tmp|
41
+ file_path = "#{tmp}/#{filename}"
42
+ FileUtils.touch(file_path)
43
+ run "#{tmp} --no-force"
44
+ expect { writer.write(content) }.to_not change {
45
+ File::Stat.new(file_path).inspect
46
+ }
47
+ end
48
+ end
49
+
50
+ it 'marks the file as ignored' do
51
+ tmpdir do |tmp|
52
+ file_path = "#{tmp}/#{filename}"
53
+ FileUtils.touch(file_path)
54
+ run "#{tmp} --no-force"
55
+ writer.should_receive(:inform_of_write).with(
56
+ Dockerize::DocumentWriter::IGNORE_WORD
57
+ )
58
+ writer.write(content)
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'the file does not already exist' do
64
+ it 'creates the file' do
65
+ tmpdir do |tmp|
66
+ file_path = "#{tmp}/#{filename}"
67
+ run "#{tmp} --no-force"
68
+ expect { writer.write(content) }.to change {
69
+ File.exists?(file_path)
70
+ }
71
+ end
72
+ end
73
+
74
+ it 'marks the file as created' do
75
+ tmpdir do |tmp|
76
+ run "#{tmp} --no-force"
77
+ writer.should_receive(:inform_of_write).with(
78
+ Dockerize::DocumentWriter::CREATE_WORD
79
+ )
80
+ writer.write(content)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ context 'with force' do
87
+ context 'the file already exists' do
88
+ it 'modifies the file' do
89
+ tmpdir do |tmp|
90
+ file_path = "#{tmp}/#{filename}"
91
+ run "#{tmp} --force"
92
+ FileUtils.touch(file_path)
93
+ expect { writer.write(content) }.to change {
94
+ File::Stat.new(file_path).inspect
95
+ }
96
+ end
97
+ end
98
+
99
+ it 'marks the file as replaced' do
100
+ tmpdir do |tmp|
101
+ run "#{tmp} --force"
102
+ FileUtils.touch("#{tmp}/#{filename}")
103
+ writer.should_receive(:inform_of_write).with(
104
+ Dockerize::DocumentWriter::REPLACE_WORD
105
+ )
106
+ writer.write(content)
107
+ end
108
+ end
109
+
110
+ context 'backup option is specified' do
111
+ it 'creates a backup file' do
112
+ tmpdir do |tmp|
113
+ file_path = "#{tmp}/#{filename}"
114
+ backup_path = "#{tmp}/#{backup_filename}"
115
+ run "#{tmp} --force --backup"
116
+ FileUtils.touch(file_path)
117
+ expect { writer.write(content) }.to change {
118
+ File.exists?(backup_path)
119
+ }
120
+ end
121
+ end
122
+ end
123
+
124
+ context '--no-backup option is specified' do
125
+ it 'does not create create a backup file' do
126
+ tmpdir do |tmp|
127
+ file_path = "#{tmp}/#{filename}"
128
+ backup_path = "#{tmp}/#{backup_filename}"
129
+ run "#{tmp} --force --no-backup"
130
+ FileUtils.touch(file_path)
131
+ expect { writer.write(content) }.to_not change {
132
+ File.exists?(backup_path)
133
+ }
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ context 'the file does not already exist' do
140
+ it 'creates the file' do
141
+ tmpdir do |tmp|
142
+ file_path = "#{tmp}/#{filename}"
143
+ run "#{tmp} --force"
144
+ expect { writer.write(content) }.to change {
145
+ File.exists?(file_path)
146
+ }
147
+ end
148
+ end
149
+
150
+ it 'marks the file as created' do
151
+ tmpdir do |tmp|
152
+ run "#{tmp} --force"
153
+ writer.should_receive(:inform_of_write).with(
154
+ Dockerize::DocumentWriter::CREATE_WORD
155
+ )
156
+ writer.write(content)
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ describe 'writing' do
164
+ let(:filename) { 'foo_file' }
165
+ let(:writer) { described_class.new(filename) }
166
+
167
+ context 'dry run' do
168
+ it 'writes to standard out' do
169
+ tmpdir do |tmp|
170
+ run %W(#{tmp} --dry-run)
171
+ $stdout.should_receive(:print).with('12345')
172
+ writer.write('12345')
173
+ end
174
+ end
175
+
176
+ it 'writes nothing to its file' do
177
+ tmpdir do |tmp|
178
+ run %W(#{tmp} --dry-run)
179
+ writer.write('12345')
180
+ File.exists?("#{tmp}/#{filename}").should == false
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'dry run and quiet' do
186
+ it 'writes nothing to standard out' do
187
+ tmpdir do |tmp|
188
+ run %W(#{tmp} --dry-run --quiet)
189
+ $stdout.should_not_receive(:print)
190
+ writer.write('12345')
191
+ end
192
+ end
193
+
194
+ it 'writes nothing to its file' do
195
+ tmpdir do |tmp|
196
+ run %W(#{tmp} --dry-run --quiet)
197
+ writer.write('12345')
198
+ File.exists?("#{tmp}/#{filename}").should == false
199
+ end
200
+ end
201
+ end
202
+
203
+ context 'normal run' do
204
+ it 'writes nothing to standard out' do
205
+ tmpdir do |tmp|
206
+ run %W(#{tmp} --no-dry-run)
207
+ $stdout.should_not_receive(:print)
208
+ writer.write('12345')
209
+ end
210
+ end
211
+
212
+ it 'writes to its file' do
213
+ tmpdir do |tmp|
214
+ run %W(#{tmp} --no-dry-run)
215
+ writer.write('12345')
216
+ File.size("#{tmp}/#{filename}").should == 5
217
+ end
218
+ end
219
+
220
+ it 'creates the file path leading up to the document' do
221
+ tmpdir do |tmp|
222
+ run tmp
223
+ writer.stub(:document_name).and_return('foo_dir/foo_file')
224
+ writer.write('12345')
225
+ File.directory?("#{tmp}/foo_dir").should == true
226
+ end
227
+ end
228
+ end
229
+
230
+ context 'invalid content is provided' do
231
+ it 'should not create the file' do
232
+ tmpdir do |tmp|
233
+ run tmp
234
+ writer.stub(:document_name).and_return('foo_file')
235
+ expect { writer.write(nil) }.to_not change {
236
+ File.exists?("#{tmp}/foo_file")
237
+ }
238
+ end
239
+ end
240
+
241
+ it 'should print useful output mesages' do
242
+ tmpdir do |tmp|
243
+ run tmp
244
+ writer.stub(:document_name).and_return('foo_file')
245
+ writer.should_receive(:inform_of_write).with(
246
+ writer.send(:invalid_word)
247
+ )
248
+ writer.write(nil)
249
+ end
250
+
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,139 @@
1
+ # coding: utf-8
2
+
3
+ require 'dockerize/template_parser'
4
+
5
+ describe Dockerize::TemplateParser do
6
+ let(:filename) { 'Dockerfile' }
7
+ let(:contents) do
8
+ <<-EOB.gsub(/^ +/, '')
9
+ <% self.filename = '#{filename}' -%>
10
+ <% self.filter = 'Baxter the Dog' -%>
11
+ <% self.foo = 'pasta' -%>
12
+ <% self.executable = true -%>
13
+ This is the first line
14
+
15
+ This is the second line
16
+
17
+ This has some erb interpolation: "<%= foo %>"
18
+ EOB
19
+ end
20
+ let(:non_executable_contents) do
21
+ <<-EOB.gsub(/^ +/, '')
22
+ <% self.filename = '#{filename}' -%>
23
+ <% self.filter = 'Baxter the Dog' -%>
24
+ <% self.foo = 'pasta' -%>
25
+ <% self.executable = false -%>
26
+ This is the first line
27
+
28
+ This is the second line
29
+
30
+ This has some erb interpolation: "<%= foo %>"
31
+ EOB
32
+
33
+ end
34
+ let(:parsed_contents) do
35
+ <<-EOB.gsub(/^ +/, '')
36
+ This is the first line
37
+
38
+ This is the second line
39
+
40
+ This has some erb interpolation: "pasta"
41
+ EOB
42
+ end
43
+
44
+ subject(:parser) { described_class.new(contents) }
45
+ subject(:non_executable_file_parser) do
46
+ described_class.new(non_executable_contents)
47
+ end
48
+
49
+ it 'assigns the contents passed in as the raw text' do
50
+ parser.raw_text.should == contents
51
+ end
52
+
53
+ describe 'retrieving template file contents' do
54
+ context 'parsing the template' do
55
+ it 'retrieves the correct header vars' do
56
+ parser.parsed_erb
57
+ parser.metadata.should == {
58
+ filename: filename,
59
+ filter: 'Baxter the Dog',
60
+ foo: 'pasta',
61
+ executable: true
62
+ }
63
+ end
64
+ end
65
+
66
+ context 'parsing the erb' do
67
+ it 'produces the correct output text' do
68
+ parser.parsed_erb.should == parsed_contents
69
+ end
70
+ end
71
+ end
72
+
73
+ describe 'writing the file' do
74
+ let(:writer) { Dockerize::DocumentWriter.new }
75
+
76
+ it 'creates the file' do
77
+ tmpdir do |tmp|
78
+ run tmp
79
+ expect { parser.write_with writer }.to change {
80
+ File.exists?("#{tmp}/#{filename}")
81
+ }
82
+ end
83
+ end
84
+
85
+ it 'writes the correct contents to the file' do
86
+ tmpdir do |tmp|
87
+ run tmp
88
+ parser.write_with writer
89
+ File.read("#{tmp}/#{filename}").should == parsed_contents
90
+ end
91
+ end
92
+
93
+ context 'the file should be executable' do
94
+ it 'makes the file executable' do
95
+ tmpdir do |tmp|
96
+ run tmp
97
+ parser.write_with writer
98
+ File.executable?("#{tmp}/#{filename}").should == true
99
+ end
100
+ end
101
+ end
102
+
103
+ context 'the file should not be executable' do
104
+ it 'makes the file executable' do
105
+ tmpdir do |tmp|
106
+ run tmp
107
+ non_executable_file_parser.write_with writer
108
+ File.executable?("#{tmp}/#{filename}").should == false
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ describe 'handling invalid templates' do
115
+ let(:invalid_erb) do
116
+ <<-ERB.gsub(/^\s+/, '')
117
+ This is the first line
118
+
119
+ This is the second line
120
+
121
+ This has some erb interpolation: <%= foo #%>
122
+ ERB
123
+ end
124
+
125
+ context 'invalid erb' do
126
+ subject(:invalid_erb_parser) do
127
+ described_class.new(invalid_erb)
128
+ end
129
+
130
+ it 'does not explode when given invalid erb' do
131
+ expect { invalid_erb_parser.parsed_erb }.to_not raise_error
132
+ end
133
+
134
+ it 'returns nil as the parsed content' do
135
+ invalid_erb_parser.parsed_erb.should be_nil
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+
3
+ describe Dockerize do
4
+ subject(:dockerize) { described_class }
5
+
6
+ it 'has a valid version string' do
7
+ dockerize::VERSION.should match(/\d+\.\d+\.\d+/)
8
+ end
9
+ end