dockerize 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.
@@ -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