ruby_yacht 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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +27 -0
  3. data/.gitignore +4 -0
  4. data/.rdoc_options +29 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +1156 -0
  7. data/.travis.yml +4 -0
  8. data/Gemfile +3 -0
  9. data/Gemfile.lock +44 -0
  10. data/LICENSE +8 -0
  11. data/README.md +216 -0
  12. data/doc/CONTRIBUTING.md +12 -0
  13. data/doc/TODO.md +28 -0
  14. data/doc/configuration_sample.rb +87 -0
  15. data/lib/ruby_yacht/dsl/app.rb +59 -0
  16. data/lib/ruby_yacht/dsl/configuration.rb +55 -0
  17. data/lib/ruby_yacht/dsl/database.rb +57 -0
  18. data/lib/ruby_yacht/dsl/dns_server.rb +38 -0
  19. data/lib/ruby_yacht/dsl/dsl.rb +252 -0
  20. data/lib/ruby_yacht/dsl/project.rb +140 -0
  21. data/lib/ruby_yacht/dsl.rb +6 -0
  22. data/lib/ruby_yacht/images/app/Dockerfile.erb +32 -0
  23. data/lib/ruby_yacht/images/app/checkout.rb +7 -0
  24. data/lib/ruby_yacht/images/app/startup.rb +17 -0
  25. data/lib/ruby_yacht/images/app/update_database_config.rb +45 -0
  26. data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +23 -0
  27. data/lib/ruby_yacht/images/app-dependencies/install_gems.rb +12 -0
  28. data/lib/ruby_yacht/images/database/Dockerfile.erb +26 -0
  29. data/lib/ruby_yacht/images/database/load_seeds.rb +42 -0
  30. data/lib/ruby_yacht/images/database/setup.rb +19 -0
  31. data/lib/ruby_yacht/images/database/setup_database.sql.erb +12 -0
  32. data/lib/ruby_yacht/images/deploy/Dockerfile.erb +2 -0
  33. data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -0
  34. data/lib/ruby_yacht/images/web/add_app.rb +12 -0
  35. data/lib/ruby_yacht/images/web/add_project.rb +14 -0
  36. data/lib/ruby_yacht/images/web/app_config.erb +11 -0
  37. data/lib/ruby_yacht/images/web/index.html.erb +10 -0
  38. data/lib/ruby_yacht/images/web/index_config.erb +12 -0
  39. data/lib/ruby_yacht/images/web/setup.rb +22 -0
  40. data/lib/ruby_yacht/runner/build.rb +21 -0
  41. data/lib/ruby_yacht/runner/build_images.rb +82 -0
  42. data/lib/ruby_yacht/runner/checkout.rb +68 -0
  43. data/lib/ruby_yacht/runner/command.rb +161 -0
  44. data/lib/ruby_yacht/runner/help.rb +55 -0
  45. data/lib/ruby_yacht/runner/implode.rb +33 -0
  46. data/lib/ruby_yacht/runner/run_containers.rb +105 -0
  47. data/lib/ruby_yacht/runner/runner.rb +42 -0
  48. data/lib/ruby_yacht/runner/services.rb +79 -0
  49. data/lib/ruby_yacht/runner/shell.rb +66 -0
  50. data/lib/ruby_yacht/runner/update_hosts.rb +72 -0
  51. data/lib/ruby_yacht/runner.rb +18 -0
  52. data/lib/ruby_yacht.rb +6 -0
  53. data/ruby_yacht.gemspec +18 -0
  54. data/spec/docker/Dockerfile +5 -0
  55. data/spec/docker/build.bash +10 -0
  56. data/spec/dsl/app_spec.rb +47 -0
  57. data/spec/dsl/configuration_spec.rb +64 -0
  58. data/spec/dsl/database_spec.rb +75 -0
  59. data/spec/dsl/dns_server_spec.rb +25 -0
  60. data/spec/dsl/dsl_spec.rb +298 -0
  61. data/spec/dsl/project_spec.rb +266 -0
  62. data/spec/fixtures/app-dependencies-dockerfile +25 -0
  63. data/spec/fixtures/database-dockerfile +31 -0
  64. data/spec/fixtures/deploy-dockerfile +2 -0
  65. data/spec/fixtures/mars-dockerfile +32 -0
  66. data/spec/fixtures/multi-project-web-dockerfile +35 -0
  67. data/spec/fixtures/web-dockerfile +27 -0
  68. data/spec/runner/build_images_spec.rb +164 -0
  69. data/spec/runner/build_spec.rb +86 -0
  70. data/spec/runner/checkout_spec.rb +128 -0
  71. data/spec/runner/command_spec.rb +94 -0
  72. data/spec/runner/help_spec.rb +73 -0
  73. data/spec/runner/implode_spec.rb +62 -0
  74. data/spec/runner/run_containers_spec.rb +141 -0
  75. data/spec/runner/runner_spec.rb +117 -0
  76. data/spec/runner/services_spec.rb +135 -0
  77. data/spec/runner/shell_spec.rb +123 -0
  78. data/spec/runner/update_hosts_spec.rb +163 -0
  79. data/spec/spec_helper.rb +10 -0
  80. data/spec/support/docker_stubbing.rb +93 -0
  81. data/spec/support/test_project.rb +56 -0
  82. metadata +193 -0
@@ -0,0 +1,27 @@
1
+ FROM nginx
2
+
3
+ RUN apt-get update
4
+ RUN apt-get upgrade -y
5
+ RUN apt-get install -y ruby
6
+
7
+ RUN mkdir -p /var/docker
8
+
9
+ COPY add_project.rb /var/docker/add_project.rb
10
+ COPY add_app.rb /var/docker/add_app.rb
11
+ COPY index.html.erb /var/docker/index.html.erb
12
+ COPY index_config.erb /var/docker/index_config.erb
13
+ COPY app_config.erb /var/docker/app_config.erb
14
+
15
+
16
+
17
+ RUN ruby /var/docker/add_project.rb apollo apollo.test.com mars,saturn
18
+
19
+ RUN ruby /var/docker/add_app.rb apollo apollo.test.com mars 8080
20
+
21
+ RUN ruby /var/docker/add_app.rb apollo apollo.test.com saturn 8080
22
+
23
+
24
+
25
+ RUN rm -r /var/docker
26
+ RUN apt-get remove -y ruby
27
+ RUN apt-get autoremove -y
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::BuildImages do
4
+ include DockerCommandSpec
5
+
6
+ describe "command information" do
7
+ specify { expect(described_class.command).to eq 'build_images' }
8
+ specify { expect(described_class.description).to eq 'Build images for your environment' }
9
+ end
10
+
11
+ describe "running" do
12
+ it "builds all the images for the project" do
13
+ docker.fail_unexpected_commands!
14
+ docker.expect "network create apollo 2> /dev/null"
15
+ docker.expect "build -t apollo-app-dependencies tmp"
16
+ docker.expect "build -t apollo-mars tmp"
17
+ docker.expect "build -t apollo-saturn tmp"
18
+ docker.expect "build -t apollo-web tmp"
19
+ subject.run
20
+ end
21
+
22
+ it "generates the dockerfile for the app dependencies" do
23
+ docker.expect("build -t apollo-app-dependencies tmp") do
24
+ files = Dir[File.join("tmp", "*")].sort
25
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/install_gems.rb']
26
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
27
+ expected = File.read(File.join('spec', 'fixtures', 'app-dependencies-dockerfile'))
28
+ expect(dockerfile).to eq expected
29
+ end
30
+ subject.run
31
+ end
32
+
33
+ it "generates the dockerfiles for the apps" do
34
+ docker.expect("build -t apollo-mars tmp") do
35
+ files = Dir[File.join("tmp", "*")].sort
36
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/checkout.rb', 'tmp/startup.rb', 'tmp/update_database_config.rb']
37
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
38
+ expected = File.read(File.join('spec', 'fixtures', 'mars-dockerfile'))
39
+ expect(dockerfile).to eq expected
40
+ end
41
+ subject.run
42
+ end
43
+
44
+ it "generates the dockerfiles for the web server" do
45
+ docker.expect "build -t apollo-web tmp" do
46
+ files = Dir[File.join("tmp", "*")].sort
47
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/add_app.rb', 'tmp/add_project.rb', 'tmp/app_config.erb', 'tmp/index.html.erb', 'tmp/index_config.erb', 'tmp/setup.rb']
48
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
49
+ expected = File.read(File.join('spec', 'fixtures', 'web-dockerfile'))
50
+ expect(dockerfile).to eq expected
51
+ end
52
+ subject.run
53
+ end
54
+
55
+ it "returns true" do
56
+ expect(subject.run).to be_truthy
57
+ end
58
+
59
+ context "with a local database" do
60
+ before do
61
+ RubyYacht.configuration.projects[0].database.host = 'localhost'
62
+ end
63
+
64
+ it "builds the database" do
65
+ docker.expect("build -t apollo-database tmp") do
66
+ files = Dir[File.join("tmp", "*")].sort
67
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/load_seeds.rb', 'tmp/setup.rb', 'tmp/setup_database.sql.erb']
68
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
69
+ expected = File.read(File.join('spec', 'fixtures', 'database-dockerfile'))
70
+ expect(dockerfile).to eq expected
71
+ end
72
+ subject.run
73
+ end
74
+
75
+ it "returns true" do
76
+ expect(subject.run).to be_truthy
77
+ end
78
+ end
79
+
80
+ context "with an id_rsa key" do
81
+ let(:id_file_path) { File.join(ENV['HOME'], '.ssh', 'id_rsa') }
82
+ let(:missing_id_file) { !File.exist?(id_file_path) }
83
+ before do
84
+ if missing_id_file
85
+ FileUtils.mkdir_p(File.dirname(id_file_path))
86
+ File.open(id_file_path, 'w') do |file|
87
+ file.write('test')
88
+ end
89
+ end
90
+ end
91
+
92
+ it "copies the id_rsa key to the app-dependencies container" do
93
+ docker.expect "build -t apollo-app-dependencies tmp" do
94
+ files = Dir[File.join("tmp", "*")].sort
95
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/id_rsa', 'tmp/install_gems.rb']
96
+ expect(File.read('tmp/id_rsa')).to eq File.read(id_file_path)
97
+ end
98
+
99
+ subject.run
100
+ end
101
+
102
+ it "returns true" do
103
+ expect(subject.run).to be_truthy
104
+ end
105
+
106
+ after do
107
+ if missing_id_file
108
+ FileUtils.rm(id_file_path)
109
+ end
110
+ end
111
+ end
112
+
113
+ context "with a deploy container" do
114
+ before do
115
+ RubyYacht.configuration.projects.first.create_deploy_container = true
116
+ end
117
+
118
+ it "creates the deploy container" do
119
+ docker.expect("build -t apollo-deploy tmp") do
120
+ files = Dir[File.join("tmp", "*")].sort
121
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb']
122
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
123
+ expected = File.read(File.join('spec', 'fixtures', 'deploy-dockerfile'))
124
+ expect(dockerfile).to eq expected
125
+ end
126
+ subject.run
127
+ end
128
+ end
129
+
130
+ context "with multiple projects" do
131
+ before do
132
+ RubyYacht.configure_second_test_project
133
+ end
134
+
135
+ it "builds the containers for both projects" do
136
+ docker.fail_unexpected_commands!
137
+ docker.expect "network create apollo 2> /dev/null"
138
+ docker.expect "build -t apollo-app-dependencies tmp"
139
+ docker.expect "build -t apollo-mars tmp"
140
+ docker.expect "build -t apollo-saturn tmp"
141
+ docker.expect "build -t jupiter-app-dependencies tmp"
142
+ docker.expect "build -t jupiter-venus tmp"
143
+ docker.expect "build -t jupiter-saturn tmp"
144
+ docker.expect "build -t apollo-web tmp"
145
+ subject.run
146
+ end
147
+
148
+ it "generates one dockerfile for the web server with both projects" do
149
+ docker.expect "build -t apollo-web tmp" do
150
+ files = Dir[File.join("tmp", "*")].sort
151
+ expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/add_app.rb', 'tmp/add_project.rb', 'tmp/app_config.erb', 'tmp/index.html.erb', 'tmp/index_config.erb', 'tmp/setup.rb']
152
+ dockerfile = File.read(File.join('tmp', 'Dockerfile'))
153
+ expected = File.read(File.join('spec', 'fixtures', 'multi-project-web-dockerfile'))
154
+ expect(dockerfile).to eq expected
155
+ end
156
+ subject.run
157
+ end
158
+
159
+ it "returns true" do
160
+ expect(subject.run).to be_truthy
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Build do
4
+ include DockerCommandSpec
5
+
6
+ describe "command information" do
7
+ specify { expect(described_class.command).to eq 'build' }
8
+ specify { expect(described_class.description).to eq 'Build images and run containers' }
9
+ end
10
+
11
+ describe "run behavior" do
12
+ let(:commands) { [double, double, double] }
13
+
14
+ before do
15
+ allow(RubyYacht::Runner::BuildImages).to receive(:new).and_return commands[0]
16
+ allow(RubyYacht::Runner::RunContainers).to receive(:new).and_return commands[1]
17
+ allow(RubyYacht::Runner::UpdateHosts).to receive(:new).and_return commands[2]
18
+
19
+ commands.each { |command| allow(command).to receive(:run).and_return(true) }
20
+ end
21
+
22
+ context "with successes from all commands" do
23
+ it "builds the images, runs the containers, and update the hosts" do
24
+ subject.run
25
+ expect(commands[0]).to have_received(:run)
26
+ expect(commands[1]).to have_received(:run)
27
+ expect(commands[2]).to have_received(:run)
28
+ end
29
+
30
+ it "returns true" do
31
+ expect(subject.run).to be_truthy
32
+ end
33
+ end
34
+
35
+ context "with an error building the images" do
36
+ before do
37
+ allow(commands[0]).to receive(:run).and_return false
38
+ end
39
+
40
+ it "builds the images, but does not runs the containers or update the hosts" do
41
+ subject.run
42
+ expect(commands[0]).to have_received(:run)
43
+ expect(commands[1]).not_to have_received(:run)
44
+ expect(commands[2]).not_to have_received(:run)
45
+ end
46
+
47
+ it "returns false" do
48
+ expect(subject.run).to be_falsey
49
+ end
50
+ end
51
+
52
+ context "an error running containers" do
53
+ before do
54
+ allow(commands[1]).to receive(:run).and_return false
55
+ end
56
+
57
+ it "builds the images and runs the containers, but does not update the hosts" do
58
+ subject.run
59
+ expect(commands[0]).to have_received(:run)
60
+ expect(commands[1]).to have_received(:run)
61
+ expect(commands[2]).not_to have_received(:run)
62
+ end
63
+
64
+ it "returns false" do
65
+ expect(subject.run).to be_falsey
66
+ end
67
+ end
68
+
69
+ context "with an error updating hosts" do
70
+ before do
71
+ allow(commands[2]).to receive(:run).and_return false
72
+ end
73
+
74
+ it "builds the images, runs the containers, and update the hosts" do
75
+ subject.run
76
+ expect(commands[0]).to have_received(:run)
77
+ expect(commands[1]).to have_received(:run)
78
+ expect(commands[2]).to have_received(:run)
79
+ end
80
+
81
+ it "returns true" do
82
+ expect(subject.run).to be_falsey
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Checkout do
4
+ include DockerCommandSpec
5
+
6
+ describe "command information" do
7
+ specify { expect(described_class.command).to eq 'checkout' }
8
+ specify { expect(described_class.description).to eq 'Check out a new branch for an app' }
9
+
10
+ describe "command-line parsing" do
11
+ let(:options) { subject.option_parser }
12
+ it "gives a summary in the banner" do
13
+ expect(options.banner).to eq "Usage: rspec checkout [options] [APP] [BRANCH]"
14
+ end
15
+
16
+ it "explains the options in the summary" do
17
+ expect(options.summarize).to eq [
18
+ "Options:\n",
19
+ " -p, --project PROJECT The project with the app we are checking out the branch in. Default: apollo\n"
20
+ ]
21
+ end
22
+
23
+ it "sets the project name from the command line" do
24
+ RubyYacht.configure_second_test_project
25
+ arguments = %w(-p jupiter venus issue1234)
26
+ subject.option_parser.parse!(arguments)
27
+ expect(subject.project_name).to eq :jupiter
28
+ expect(arguments).to eq %w(venus issue1234)
29
+ end
30
+
31
+ it "takes the app and checkout from the command line" do
32
+ subject.parse_positional_arguments(['venus', 'issue1234'])
33
+ expect(subject.app).to eq 'venus'
34
+ expect(subject.branch).to eq 'issue1234'
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "run behavior" do
40
+ before do
41
+ subject.app = 'saturn'
42
+ subject.branch = 'issue1234'
43
+ end
44
+
45
+ it "runs the commands to check out the branch and update the app" do
46
+ docker.fail_unexpected_commands!
47
+ docker.expect "exec apollo-saturn bash -c 'cd /var/code; git fetch; git checkout .; git checkout issue1234; git pull'"
48
+ docker.expect "exec apollo-saturn bash -c '/var/docker/update_database_config.rb; rake db:migrate'"
49
+ docker.expect "restart apollo-saturn"
50
+ subject.run
51
+ end
52
+
53
+ it "returns true" do
54
+ expect(subject.run).to be_truthy
55
+ end
56
+
57
+ context "with an explicit project" do
58
+ before do
59
+ RubyYacht.configure_second_test_project
60
+ subject.project_name = :jupiter
61
+ end
62
+
63
+ it "runs the command in that project" do
64
+ subject.app = 'venus'
65
+ docker.fail_unexpected_commands!
66
+ docker.expect "exec jupiter-venus bash -c 'cd /var/code; git fetch; git checkout .; git checkout issue1234; git pull'"
67
+ docker.expect "exec jupiter-venus bash -c '/var/docker/update_database_config.rb; rake db:migrate'"
68
+ docker.expect "restart jupiter-venus"
69
+ subject.run
70
+ end
71
+
72
+ it "returns true" do
73
+ expect(subject.run).to be_truthy
74
+ end
75
+ end
76
+
77
+ context "with an invalid project" do
78
+ before do
79
+ subject.project_name = :foo
80
+ end
81
+
82
+ it "logs an error" do
83
+ subject.run
84
+ expect(@log_entries).to eq ['There is no project named foo']
85
+ end
86
+
87
+ it "returns false" do
88
+ expect(subject.run).to be_falsey
89
+ end
90
+ end
91
+
92
+ context "with no app" do
93
+ before do
94
+ subject.app = nil
95
+ end
96
+
97
+ it "logs an error" do
98
+ subject.run
99
+ expect(@log_entries).to eq [
100
+ "You must provide an app name",
101
+ "Run rspec help checkout for more information"
102
+ ]
103
+ end
104
+
105
+ it "returns false" do
106
+ expect(subject.run).to be_falsey
107
+ end
108
+ end
109
+
110
+ context "with no branch" do
111
+ before do
112
+ subject.branch = nil
113
+ end
114
+
115
+ it "logs an error" do
116
+ subject.run
117
+ expect(@log_entries).to eq [
118
+ "You must provide a branch",
119
+ "Run rspec help checkout for more information"
120
+ ]
121
+ end
122
+
123
+ it "returns false" do
124
+ expect(subject.run).to be_falsey
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Command do
4
+ class SampleCommand < RubyYacht::Runner::Command
5
+ def self.command; 'sample_command'; end
6
+ def self.description; 'Provides a sample command for testing'; end
7
+ end
8
+
9
+ describe "command information" do
10
+ specify { expect { described_class.command }.to raise_error "Command not defined for RubyYacht::Runner::Command" }
11
+ specify { expect { described_class.description }.to raise_error "Description not defined for RubyYacht::Runner::Command" }
12
+
13
+ describe "option_parser" do
14
+ it "takes the usage from the command information" do
15
+ expect(SampleCommand.new.option_parser.banner).to eq "Usage: rspec sample_command\n\nProvides a sample command for testing"
16
+ end
17
+
18
+ it "does not have anything beyond the banner" do
19
+ parser = SampleCommand.new.option_parser
20
+ expect(parser.to_s).to eq parser.banner + "\n"
21
+ end
22
+ end
23
+
24
+ describe "parse_positional_arguments" do
25
+ it "does not modify the arguments" do
26
+ arguments = %w(foo bar)
27
+ subject.parse_positional_arguments(arguments)
28
+ expect(arguments).to eq %w(foo bar)
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "run behavior" do
34
+ it "raises an error" do
35
+ expect { subject.run }.to raise_error "Run method not defined for #{subject}"
36
+ end
37
+ end
38
+
39
+ describe "helpers" do
40
+ describe "short_script_name" do
41
+ it "is the name of the invoked command" do
42
+ expect(described_class.short_script_name).to eq "rspec"
43
+ end
44
+ end
45
+
46
+ describe "projects" do
47
+ it "provides the full list of projects" do
48
+ RubyYacht.configure_test_project
49
+ RubyYacht.configure_second_test_project
50
+ expect(subject.projects.collect(&:name)).to eq [:apollo, :jupiter]
51
+ end
52
+ end
53
+
54
+ describe "get_machine_info" do
55
+ it "gets the property from docker" do
56
+ allow(subject).to receive(:backtick).with("docker-machine inspect default -f {{System.Name}}").and_return("Jimmy\n")
57
+ expect(subject.get_machine_info('System.Name')).to eq 'Jimmy'
58
+ end
59
+ end
60
+
61
+ describe "logs" do
62
+ it "logs the message to stdout" do
63
+ allow($stdout).to receive(:puts)
64
+ subject.log('Test Message')
65
+ expect($stdout).to have_received(:puts).with('Test Message')
66
+ end
67
+ end
68
+
69
+ describe "docker" do
70
+ it "sends the command to docker" do
71
+ allow(subject).to receive(:system)
72
+ subject.docker "run hello-world"
73
+ expect(subject).to have_received(:system).with('docker run hello-world')
74
+ end
75
+ end
76
+
77
+ describe "system" do
78
+ it "executes the command" do
79
+ subject.system 'echo test > tmp/test'
80
+ expect(File.read('tmp/test')).to eq "test\n"
81
+ FileUtils.rm('tmp/test')
82
+ end
83
+ end
84
+
85
+ describe "backtick" do
86
+ it "returns the result of executing the command" do
87
+ File.open('tmp/test', 'w') { |f| f.write('test contents') }
88
+ value = subject.backtick('cat tmp/test')
89
+ expect(value).to eq 'test contents'
90
+ FileUtils.rm('tmp/test')
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Help do
4
+ include DockerCommandSpec
5
+
6
+ describe "command information" do
7
+ specify { expect(described_class.command).to eq 'help' }
8
+ specify { expect(described_class.description).to eq 'Get information on available commands' }
9
+
10
+ describe "option_parser" do
11
+ it "provides the usage information" do
12
+ options = subject.option_parser
13
+ expect(options.banner).to eq "Usage: rspec help [command]\n\nGet information on available commands"
14
+ end
15
+ end
16
+
17
+ describe "parse_positional_arguments" do
18
+ it "takes the command from the arguments" do
19
+ subject.parse_positional_arguments(%w(checkout foo))
20
+ expect(subject.command).to eq 'checkout'
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "run behavior" do
26
+ context "with no command" do
27
+ it "prints the available commands" do
28
+ subject.run
29
+ expected = ["Available commands: \n\n"]
30
+ expected += RubyYacht::Runner.commands.map { |c| "#{c.name}: #{c.description}" }
31
+ expected << "\nRun rspec help [command] for more information on a command"
32
+ expect(@log_entries).to eq expected
33
+ end
34
+
35
+ it "returns true" do
36
+ expect(subject.run).to be_truthy
37
+ end
38
+ end
39
+
40
+ context "with a command" do
41
+ before do
42
+ subject.command = 'checkout'
43
+ end
44
+
45
+ it "prints the usage information for the command" do
46
+ subject.run
47
+ expect(@log_entries).to eq [RubyYacht::Runner::Checkout.new.option_parser.to_s]
48
+ end
49
+
50
+ it "returns true" do
51
+ expect(subject.run).to be_truthy
52
+ end
53
+ end
54
+
55
+ context "with an invalid command" do
56
+ before do
57
+ subject.command = 'foo'
58
+ end
59
+
60
+ it "prints an error" do
61
+ subject.run
62
+ expect(@log_entries).to eq [
63
+ "Command not available: foo",
64
+ "Run rspec help for more options"
65
+ ]
66
+ end
67
+
68
+ it "returns false" do
69
+ expect(subject.run).to be_falsey
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Implode do
4
+ include DockerCommandSpec
5
+
6
+ describe "command information" do
7
+ specify { expect(described_class.command).to eq 'implode' }
8
+ specify { expect(described_class.description).to eq 'Destroy your local environment' }
9
+ end
10
+
11
+ describe "run behavior" do
12
+ before do
13
+ allow(subject).to receive(:backtick).with('docker ps -a | grep apollo').and_return("123 up apollo-mars\n456 up apollo-saturn\n789 apollo-venus")
14
+ allow(subject).to receive(:backtick).with('docker images | grep apollo').and_return("apollo-app-dependencies 1GB\napollo-mars 1GB")
15
+ allow(subject).to receive(:backtick).with('docker ps -a | grep jupiter').and_return("abc up jupiter-saturn")
16
+ allow(subject).to receive(:backtick).with('docker images | grep jupiter').and_return("jupiter-app-dependencies 1GB\njupiter-mars 1GB")
17
+
18
+ allow(subject).to receive(:backtick).with('docker images -q --filter dangling=true').and_return("111\n222")
19
+ end
20
+
21
+ it "removes all the containers and images" do
22
+ docker.fail_unexpected_commands!
23
+ docker.expect 'rm -f 123'
24
+ docker.expect 'rm -f 456'
25
+ docker.expect 'rm -f 789'
26
+ docker.expect 'rmi apollo-app-dependencies'
27
+ docker.expect 'rmi apollo-mars'
28
+ docker.expect 'rmi 111'
29
+ docker.expect 'rmi 222'
30
+ subject.run
31
+ end
32
+
33
+ it "returns true" do
34
+ expect(subject.run).to be_truthy
35
+ end
36
+
37
+ context "with a second project" do
38
+ before do
39
+ RubyYacht.configure_second_test_project
40
+ end
41
+
42
+ it "removes containers and images for both projects" do
43
+ docker.fail_unexpected_commands!
44
+ docker.expect 'rm -f 123'
45
+ docker.expect 'rm -f 456'
46
+ docker.expect 'rm -f 789'
47
+ docker.expect 'rmi apollo-app-dependencies'
48
+ docker.expect 'rmi apollo-mars'
49
+ docker.expect 'rm -f abc'
50
+ docker.expect 'rmi jupiter-app-dependencies'
51
+ docker.expect 'rmi jupiter-mars'
52
+ docker.expect 'rmi 111'
53
+ docker.expect 'rmi 222'
54
+ subject.run
55
+ end
56
+
57
+ it "returns true" do
58
+ expect(subject.run).to be_truthy
59
+ end
60
+ end
61
+ end
62
+ end