wellcar 0.0.1

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +38 -0
  6. data/README.markdown +17 -0
  7. data/README.rdoc +6 -0
  8. data/Rakefile +44 -0
  9. data/bin/wellcar +442 -0
  10. data/command_history_example.txt +39 -0
  11. data/lib/wellcar.rb +18 -0
  12. data/lib/wellcar/templates/base.rb +61 -0
  13. data/lib/wellcar/templates/build-production-image.yml.erb +34 -0
  14. data/lib/wellcar/templates/build_production_image.rb +18 -0
  15. data/lib/wellcar/templates/database.yml.erb +20 -0
  16. data/lib/wellcar/templates/database_yaml.rb +20 -0
  17. data/lib/wellcar/templates/docker-compose-init.yml.erb +34 -0
  18. data/lib/wellcar/templates/docker-compose.yml.erb +70 -0
  19. data/lib/wellcar/templates/docker-entrypoint.sh.erb +20 -0
  20. data/lib/wellcar/templates/docker-stack.yml.erb +35 -0
  21. data/lib/wellcar/templates/docker_compose.rb +22 -0
  22. data/lib/wellcar/templates/docker_entrypoint.rb +13 -0
  23. data/lib/wellcar/templates/docker_stack.rb +23 -0
  24. data/lib/wellcar/templates/dockerfile.erb +48 -0
  25. data/lib/wellcar/templates/dockerfile.rb +13 -0
  26. data/lib/wellcar/templates/dockerfile_init.erb +38 -0
  27. data/lib/wellcar/templates/dockerfile_init.rb +18 -0
  28. data/lib/wellcar/templates/dockerignore.erb +10 -0
  29. data/lib/wellcar/templates/dockerignore.rb +12 -0
  30. data/lib/wellcar/templates/env_development_database.erb +3 -0
  31. data/lib/wellcar/templates/env_development_database.rb +13 -0
  32. data/lib/wellcar/templates/env_development_web.erb +1 -0
  33. data/lib/wellcar/templates/env_development_web.rb +14 -0
  34. data/lib/wellcar/templates/env_production_database.erb +3 -0
  35. data/lib/wellcar/templates/env_production_database.rb +14 -0
  36. data/lib/wellcar/templates/env_production_web.erb +5 -0
  37. data/lib/wellcar/templates/env_production_web.rb +14 -0
  38. data/lib/wellcar/templates/reverse_proxy.conf.erb +12 -0
  39. data/lib/wellcar/templates/reverse_proxy_conf.rb +14 -0
  40. data/lib/wellcar/version.rb +3 -0
  41. data/spec/.keep +0 -0
  42. data/spec/spec_helper.rb +101 -0
  43. data/spec/wellcar/templates/build_production_image_spec.rb +55 -0
  44. data/spec/wellcar/templates/database_yaml_spec.rb +27 -0
  45. data/spec/wellcar/templates/docker_compose_spec.rb +34 -0
  46. data/spec/wellcar/templates/docker_entrypoint_spec.rb +32 -0
  47. data/spec/wellcar/templates/docker_stack_spec.rb +37 -0
  48. data/spec/wellcar/templates/dockerfile_init_spec.rb +28 -0
  49. data/spec/wellcar/templates/dockerfile_spec.rb +44 -0
  50. data/spec/wellcar/templates/dockerignore_spec.rb +28 -0
  51. data/spec/wellcar/templates/env_development_database_spec.rb +25 -0
  52. data/spec/wellcar/templates/env_development_web_spec.rb +13 -0
  53. data/spec/wellcar/templates/env_production_database_spec.rb +25 -0
  54. data/spec/wellcar/templates/env_production_web_spec.rb +29 -0
  55. data/spec/wellcar/templates/reverse_proxy_conf_spec.rb +17 -0
  56. data/wellcar.gemspec +22 -0
  57. data/wellcar.rdoc +5 -0
  58. metadata +163 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 41fbc50fae9ac8ae5ee904b21027e31a9c863d5e2fb9c3c3758b7f071cfe2fb1
4
+ data.tar.gz: 54b46d33182277c74712784613897efd46500cc198ec21166c72b553784eb43a
5
+ SHA512:
6
+ metadata.gz: 41ca7e4d530f489b8f7c4db42da7b6fc9d31ab6bbce80a0d44c9a7f09a8b4c8598b32affca23b957975b50d7af98e98cda5334a0d31794a89999fec70c694b44
7
+ data.tar.gz: 552e7a7d1db64552c44f272464bd2065ea80d2f148f7f05acfdc5d5002b59bbc650858da498ae1e88628b4091cb5c355b16c24cd911501da3c6beabcff0114cc
@@ -0,0 +1,5 @@
1
+ *swp
2
+ *swo
3
+ .DS_Store
4
+ pkg
5
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ wellcar (0.0.1)
5
+ gli (= 2.19.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.3)
11
+ gli (2.19.0)
12
+ rake (13.0.1)
13
+ rdoc (6.2.1)
14
+ rspec (3.9.0)
15
+ rspec-core (~> 3.9.0)
16
+ rspec-expectations (~> 3.9.0)
17
+ rspec-mocks (~> 3.9.0)
18
+ rspec-core (3.9.2)
19
+ rspec-support (~> 3.9.3)
20
+ rspec-expectations (3.9.2)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.9.0)
23
+ rspec-mocks (3.9.1)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.9.0)
26
+ rspec-support (3.9.3)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ rake
33
+ rdoc
34
+ rspec
35
+ wellcar!
36
+
37
+ BUNDLED WITH
38
+ 2.1.4
@@ -0,0 +1,17 @@
1
+ # Wellcar, to containerize Rails
2
+
3
+ A personal project and reference to both better understand how to use Docker with Rails, and to help automate the set up of a Rails application that is developed and deployed in Docker containers.
4
+
5
+ This is very much an unstable, untested project that is for my own curiosity.
6
+ As such, please look around but do not expect anything to work well, if at all, on your own Rails app.
7
+
8
+ If this project is of interest, [give me a shout on Twitter](https://twitter.com/njpearman).
9
+
10
+ I have published the gem to Rubygems.org, purely to make sure that the name `wellcar` isn't taken by a different library.
11
+
12
+ ## Inspiration
13
+
14
+ `wellcar` is very much a project for me to learn as I work on it.
15
+ As such, please mess around or whatever but do not expect any polish, or even anything to work.
16
+
17
+ [The DIP gem by @bidendi](https://github.com/bibendi/dip) is an inspiration for my tinkering here. Check it out if you're serious about developing and deploying Rails apps in Docker containers!
@@ -0,0 +1,6 @@
1
+ = wellcar
2
+
3
+ Describe your project here
4
+
5
+ :include:wellcar.rdoc
6
+
@@ -0,0 +1,44 @@
1
+ require 'rake/clean'
2
+ require 'rubygems'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ Rake::RDocTask.new do |rd|
8
+ rd.main = "README.rdoc"
9
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
10
+ rd.title = 'Your application title'
11
+ end
12
+
13
+ spec = eval(File.read('wellcar.gemspec'))
14
+
15
+ Gem::PackageTask.new(spec) do |pkg|
16
+ end
17
+ CUKE_RESULTS = 'results.html'
18
+ CLEAN << CUKE_RESULTS
19
+ desc 'Run features'
20
+ Cucumber::Rake::Task.new(:features) do |t|
21
+ opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
22
+ opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
23
+ t.cucumber_opts = opts
24
+ t.fork = false
25
+ end
26
+
27
+ desc 'Run features tagged as work-in-progress (@wip)'
28
+ Cucumber::Rake::Task.new('features:wip') do |t|
29
+ tag_opts = ' --tags ~@pending'
30
+ tag_opts = ' --tags @wip'
31
+ t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
32
+ t.fork = false
33
+ end
34
+
35
+ task :cucumber => :features
36
+ task 'cucumber:wip' => 'features:wip'
37
+ task :wip => 'features:wip'
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new do |t|
40
+ t.libs << "test"
41
+ t.test_files = FileList['test/*_test.rb']
42
+ end
43
+
44
+ task :default => [:test,:features]
@@ -0,0 +1,442 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ begin # XXX: Remove this begin/rescue before distributing your app
4
+ require 'wellcar'
5
+ rescue LoadError => e
6
+ STDERR.puts e.message
7
+ STDERR.puts "In development, you need to use `bundle exec bin/wellcar` to run your app"
8
+ STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
9
+ STDERR.puts "Feel free to remove this message from bin/wellcar now"
10
+ exit 64
11
+ end
12
+
13
+ class CommandBase
14
+ attr_accessor :ruby_version,
15
+ :app_name,
16
+ :use_bundler_2,
17
+ :github_account,
18
+ :domain_name
19
+
20
+ def core_docker_templates
21
+ master_key = File.exist?("config/credentials/production.key") ?
22
+ File.read("config/credentials/production.key") :
23
+ nil
24
+
25
+ [
26
+ Wellcar::Templates::Dockerfile.new(ruby_version, app_name, use_bundler_2),
27
+ Wellcar::Templates::DockerStack.new(app_name, github_account),
28
+ Wellcar::Templates::EnvDevelopmentDatabase.new(app_name),
29
+ Wellcar::Templates::EnvDevelopmentWeb.new,
30
+ Wellcar::Templates::EnvProductionWeb.new(master_key),
31
+ Wellcar::Templates::EnvProductionDatabase.new(app_name),
32
+ Wellcar::Templates::Dockerignore.new,
33
+ Wellcar::Templates::DockerEntrypoint.new,
34
+ Wellcar::Templates::BuildProductionImage.new(app_name, github_account),
35
+ Wellcar::Templates::ReverseProxyConf.new(domain_name)
36
+ ]
37
+ end
38
+
39
+ def create_directories
40
+ FileUtils.mkdir_p "config"
41
+ FileUtils.mkdir_p "bin"
42
+ FileUtils.mkdir_p ".env/development"
43
+ FileUtils.mkdir_p ".env/production"
44
+ end
45
+
46
+ def write_files
47
+ files_before_docker = Dir['*']
48
+
49
+ system "curl -o bin/wait-for https://raw.githubusercontent.com/mrako/wait-for/master/wait-for"
50
+
51
+ docker_files.each(&:write)
52
+ puts "Wellcar created:\n#{Dir['*'] - files_before_docker}\n"
53
+ end
54
+
55
+ def create_wellcar_folder
56
+ return if Dir.exist? ".wellcar"
57
+
58
+ Dir.mkdir ".wellcar"
59
+ FileUtils.touch ".wellcar/.keep"
60
+ end
61
+
62
+ def clean_docker
63
+ # Make sure that no pre-existing containers are running. Although
64
+ # very unlikely, it's worth being thorough. This makes the command
65
+ # slow but for the time being this ensures the containers and images
66
+ # are as expected.
67
+ exit 8 unless system "docker-compose down --remove-orphans"
68
+
69
+ removable_volumes = ["#{app_name}_gem_cache", "#{app_name}_node_modules"]
70
+ volumes_to_remove = %x(docker volume ls --format='{{.Name}}')
71
+ .split("\n") & removable_volumes
72
+
73
+ return if volumes_to_remove.empty?
74
+
75
+ puts "Removing the following volumes: #{volumes_to_remove.join(", ")}"
76
+
77
+ system "docker volume rm #{volumes_to_remove.join(" ")}"
78
+ end
79
+
80
+ def build_development_environment
81
+ exit 128 unless system "docker-compose build web webpack-dev-server database"
82
+ end
83
+ end
84
+
85
+ class NewCommand < CommandBase
86
+ def initialize(app_name, github_account, domain_name)
87
+ self.app_name = app_name
88
+ self.domain_name = domain_name
89
+ self.github_account = github_account
90
+ self.ruby_version = "2.6.6"
91
+ self.use_bundler_2 = true
92
+ end
93
+
94
+ def docker_files
95
+ @files ||= core_docker_templates.push(
96
+ Wellcar::Templates::DockerfileInit.new(ruby_version, app_name),
97
+ Wellcar::Templates::DockerCompose.new(app_name,
98
+ github_account,
99
+ Wellcar::Templates::DockerCompose::INIT_TEMPLATE)
100
+ )
101
+ end
102
+
103
+ def try_full_nuke(nuke)
104
+ if nuke && Dir.exists?(app_name)
105
+ puts "*** Destroying the existing folder #{app_name} ***"
106
+ FileUtils.rm_rf app_name
107
+ elsif Dir.exists? app_name
108
+ puts "Cannot overwrite existing folder #{Dir.pwd}/#{app_name}"
109
+ exit 1
110
+ end
111
+ end
112
+
113
+ def within_app_folder(&block)
114
+ raise NotImplemented if block.nil?
115
+
116
+ Dir.mkdir app_name
117
+
118
+ Dir.chdir(app_name) do
119
+ yield
120
+ end
121
+ end
122
+
123
+ def perform_setup
124
+ # Create app and install webpacker
125
+ exit 16 unless system "docker-compose up --build new_rails"
126
+ exit 32 unless system "docker-compose up --build bundle"
127
+ exit 64 unless system "docker-compose up --build install_webpacker"
128
+ puts "Rails app created; initializing for Docker\n"
129
+ end
130
+
131
+ def tidy_up_setup
132
+ # remove dockerfile.init and docker-compose.yml with initialisation services
133
+ %w(Dockerfile.init docker-compose.yml config/database.yml).each {|f| File.delete(f) if File.file?(f) }
134
+ # Create docker-compose.yml file
135
+ Wellcar::Templates::DockerCompose.new(app_name).write
136
+ Wellcar::Templates::DatabaseYaml.new(app_name).write
137
+ end
138
+
139
+ def call(options, args)
140
+ # Here we want to create a new rails app that is set up with docker.
141
+ # We use `rails new` within a `docker run` command but skip a lot of set up so
142
+ # that further setup steps can be taken later on.
143
+ # What I don't know right now is how steps that are skipped at the start can be
144
+ # initiated in an existing app.
145
+ #
146
+ # My list of pre-requisites for a Rails app are:
147
+ # * RSpec
148
+ # * Webpack + yarn
149
+ # * Rubocop
150
+ # * PostgreSQL
151
+ # * Redis
152
+ # * FactoryBot
153
+ # * Capybara with a real webdriver
154
+ # * Devise
155
+
156
+ try_full_nuke options[:full_nuke]
157
+
158
+ within_app_folder do
159
+ create_wellcar_folder
160
+ create_directories
161
+ write_files
162
+ clean_docker
163
+ perform_setup
164
+ tidy_up_setup
165
+ build_development_environment
166
+ end
167
+
168
+ puts <<-FINISHED
169
+ Your new Rails application "#{app_name}" has been created with Docker!
170
+
171
+ Don't forget to commit everything to git.
172
+
173
+ You can use wellcar to interact with the Docker containers and the Rails application as you develop your app.
174
+
175
+ Run `wellcar` for help with commands.
176
+ FINISHED
177
+ end
178
+ end
179
+
180
+ class DockCommand < CommandBase
181
+ def initialize(github_account, domain_name)
182
+ self.github_account = github_account
183
+ self.domain_name = domain_name
184
+ end
185
+
186
+ def interpret_app_name
187
+ app_name = File.read("./config/application.rb")
188
+ .split("\n")
189
+ .select {|line| line =~ /^module / }
190
+ .first
191
+ &.split
192
+ &.last
193
+ &.downcase
194
+
195
+ return app_name unless app_name.nil?
196
+
197
+ puts "Cannot determine app name from config/application.rb. wellcar expects to find one module in this file named for the application."
198
+ exit 5
199
+ end
200
+
201
+ def interpret_ruby_version
202
+ File.file?(".ruby_version") ?
203
+ File.read(".ruby_version").split.first :
204
+ "2.6.6"
205
+ end
206
+
207
+ def interpret_bundler_2
208
+ b2 = File.file?("Gemfile.lock") &&
209
+ File.read("Gemfile.lock").split("BUNDLED WITH")&.last.strip >= "2.0.0"
210
+ puts "Install bundler 2? #{b2}"
211
+ b2
212
+ end
213
+
214
+ def determine_variables
215
+ self.app_name = interpret_app_name
216
+ self.ruby_version = interpret_ruby_version
217
+ self.use_bundler_2 = interpret_bundler_2
218
+ end
219
+
220
+ def prepare_templates
221
+ docker_files
222
+ end
223
+
224
+ def docker_files
225
+ @files ||= core_docker_templates.push(Wellcar::Templates::DockerCompose.new(app_name, github_account))
226
+ end
227
+
228
+ def check_existing_files(force_new)
229
+ files_exist = docker_files.select {|file| file.exist? }.any?
230
+ if force_new && files_exist
231
+ puts "--force-new set. Overwriting **all** existing docker files."
232
+
233
+ if Dir.exist? ".env"
234
+ label = Time.new.strftime("%Y%m%d%H%M%S")
235
+ puts ".env will be backed up to .wellcar/env-#{label}"
236
+ destination = ".wellcar/env-#{label}"
237
+ FileUtils.copy_entry ".env", destination
238
+ exit unless Dir.exist? destination
239
+ end
240
+ elsif files_exist
241
+ puts "Found existing docker files. Please check your app source tree before trying to dockerise this app with wellcar again."
242
+ exit 3
243
+ end
244
+ end
245
+
246
+ def update_database_config
247
+ Wellcar::Templates::DatabaseYaml.new(app_name).update
248
+ puts <<-DB
249
+ ... updated development settings for database.yml.
250
+ Now using dockerised PostgreSQL server. Previous config saved as config/database.pre_docker.yml
251
+ DB
252
+ end
253
+
254
+ # This does not currently work, as it is called before bundle is available. I'm debating how
255
+ # to include this "gem tidying" aspect of adding Docker to an existing project.
256
+ def tidy_gemfile
257
+ %w(sqlite3 figaro dotenv).each {|gem| system "docker-compose run --rm bin/bundle remove #{gem}" }
258
+ system "docker-compose run --rm bin/bundle add pg" unless system("docker-compose run --rm bin/bundle info pg")
259
+ end
260
+
261
+ def call(options, args)
262
+ create_wellcar_folder
263
+ determine_variables
264
+ prepare_templates
265
+ check_existing_files options[:"force-new"]
266
+ create_directories
267
+ write_files
268
+ update_database_config
269
+ clean_docker
270
+ # This assumes bin/bundle is available, which will not be the case.
271
+ # The gem set up done in this call should be part of a Dockerfile, but needs
272
+ # a script to manage some conditional logic.
273
+ # tidy_gemfile
274
+ build_development_environment
275
+
276
+ puts <<-DONE
277
+ Your Rails app has been dockerised!
278
+
279
+ You can use wellcar to interact with the Docker containers and the Rails application as you develop your app.
280
+
281
+ Run `wellcar` for help with commands.
282
+ DONE
283
+ end
284
+ end
285
+
286
+ class App
287
+ extend GLI::App
288
+
289
+ program_desc 'Wellcar makes development of dockerised Rails apps easier'
290
+
291
+ version Wellcar::VERSION
292
+
293
+ subcommand_option_handling :normal
294
+ arguments :strict
295
+
296
+ desc 'Creates a new docked Rails app'
297
+ arg 'name'
298
+ command :new do |c|
299
+ c.desc "Force-delete if folder matching <name> exists"
300
+ c.switch "full-nuke"
301
+
302
+ c.flag [:d, :domain],
303
+ desc: "Used to set a domain name in configuration files, e.g. nginx config",
304
+ default: ""
305
+
306
+ c.flag "github-account",
307
+ required: true,
308
+ desc: "Sets the GitHub account used in building Docker image paths (which assumes images are hosted as GitHub Packages)"
309
+ c.action do |global_options, options, args|
310
+ NewCommand.new(args[0], options['github-account'], options[:domain]).call options, args
311
+ end
312
+ end
313
+
314
+ desc 'Adds docker config to an existing Rails application'
315
+ command :dock do |c|
316
+ c.switch "force-new",
317
+ desc: 'Forces all existing docker files to be overwritten and images to be rebuilt'
318
+
319
+ c.flag [:d, :domain],
320
+ desc: "Used to set a domain name in configuration files, e.g. nginx config",
321
+ default: ""
322
+
323
+ c.flag "github-account",
324
+ desc: "Sets the GitHub account used in building Docker image paths (which assumes images are hosted as GitHub Packages)",
325
+ required: true
326
+
327
+ c.action do |global_options, options, args|
328
+ DockCommand.new(options['github-account'], options[:domain]).call options, args
329
+ end
330
+ end
331
+
332
+ desc 'Builds an image for production and deploys to a named remote server'
333
+ command :deploy do |c|
334
+ # Build the production image
335
+ # Save the image locally
336
+ # Set DOCKER_HOST to connect to remote server
337
+ # Copy onto remote host to load into docker on remote host
338
+ # Perhaps like:
339
+ # docker save mycontainerimage |\
340
+ # gzip |\
341
+ # ssh root@203.0.113.1 'gunzip | docker load'
342
+ # Or:
343
+ # docker save <image-name> | gzip | scp -J <creds>:<destination>
344
+ # Run docker stack deploy -c docker-stack.yml <app_name>
345
+ # Delete image on remote host?
346
+ end
347
+
348
+ desc 'Checks that a named remote server can run the production build'
349
+ command :check_server do |c|
350
+ c.action do |global_options, options, args|
351
+ # Removes old versions of Docker
352
+ # sudo apt-get remove docker docker-engine docker.io containerd runc
353
+ # Assumes an Ubuntu server
354
+ # Update repo
355
+ # sudo apt-get update
356
+ # Install required libraries
357
+ # sudo apt-get install \
358
+ # sudo apt-get install \
359
+ # apt-transport-https \
360
+ # ca-certificates \
361
+ # curl \
362
+ # gnupg-agent \
363
+ # software-properties-common
364
+ # Add Docker repo public key
365
+ # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
366
+ # Check the key visually matches 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
367
+ # sudo apt-key fingerprint 0EBFCD88
368
+ # Add the repository that matches the Ubuntu distro
369
+ # sudo add-apt-repository \
370
+ # "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
371
+ # $(lsb_release -cs) \
372
+ # stable"
373
+ # Update again
374
+ # sudo apt-get update
375
+ # Install Docker engine
376
+ # sudo apt-get install docker-ce docker-ce-cli containerd.io
377
+ # Test Docker is installed properly
378
+ # sudo docker run --rm hello-world
379
+ # sudo docker images --all --format='{{.ID}} {{.Name}}'|\
380
+ # grep hello-world|\
381
+ # cut -d ' ' -f 1|\
382
+ # xargs docker rmi
383
+ # Add user to docker group
384
+ # sudo usermod -a -G docker <username>
385
+ end
386
+ end
387
+
388
+ desc 'Runs bundle within a container'
389
+ arg_name 'Pass commands through to bundler. Note that to pass args to bundler, use `--` followed by the args, e.g. `wellcar bundle -- --help '
390
+ command :bundle do |c|
391
+ c.desc 'Set the container name to run bundle in'
392
+ c.default_value 'web'
393
+ c.arg_name 'name'
394
+ c.flag [:c, :container]
395
+
396
+ c.action do |global_options,options,args|
397
+ container = options[:c]
398
+ command = "COMPOSE_FILE=#{global_options[:c]} docker-compose run #{container} bundle "
399
+ command << args * ' '
400
+
401
+ puts "Full command: #{command}"
402
+ system command
403
+
404
+ if $?.exitstatus != 0
405
+ puts "Unable to call bundle in #{container} successfully"
406
+ else
407
+ puts "bundle command ran in #{container}#{args.any? ? " with #{args}" : ""}"
408
+ end
409
+ end
410
+ end
411
+
412
+ desc 'Rebuilds containers'
413
+ arg_name 'command'
414
+ command :build do |c|
415
+ c.action do |global_options, options, args|
416
+ system("COMPOSE_FILE=#{global_options[:c]} docker-compose build")
417
+ end
418
+ end
419
+
420
+ pre do |global,command,options,args|
421
+ # Pre logic here
422
+ # Return true to proceed; false to abort and not call the
423
+ # chosen command
424
+ # Use skips_pre before a command to skip this block
425
+ # on that command only
426
+ true
427
+ end
428
+
429
+ post do |global,command,options,args|
430
+ # Post logic here
431
+ # Use skips_post before a command to skip this
432
+ # block on that command only
433
+ end
434
+
435
+ on_error do |exception|
436
+ # Error logic here
437
+ # return false to skip default error handling
438
+ true
439
+ end
440
+ end
441
+
442
+ exit App.run(ARGV)