dctl_rb 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f9cb75fb8f24b8b22b9f1e226f45da72fef196b334150046acaa8822fd2162a
4
- data.tar.gz: 0a44b4bf225e0840c4bff65bccbd1fcd8eb4e0beb640541672d42cf7375d8381
3
+ metadata.gz: 891e4ebdd5366c0525f1e5d50fddf2fb5351594a1b284580e782b1ab5865d7a1
4
+ data.tar.gz: 6555744900318c5e7b881c34e0ec09702f3980ffa81865ec1801e713293474f2
5
5
  SHA512:
6
- metadata.gz: 48751f5d3c40ee9c6b4b6fc304cc9dc31f34f42b8d6270650ff9f00c7512beb3f1145e9c9fa40726b3f1ff4183bf79464b3b82836eee900c49e91970cf412652
7
- data.tar.gz: ec7073f18dacaa43c6f9593347368cc4e67f0a32920cca8b9915128657dc0eda1205bb156c0628b975018f84553d972838aa993cb920e4ab300b88173702d255
6
+ metadata.gz: 38501937b88ebeb904280fed31f5abbf58856212a538e8695d13c503c528d77a933aeaa10cb5edd7704413ee26d8165997e777afc28d7c7eeaca3eaf411b94cb
7
+ data.tar.gz: c0f7f9419517cea03fe5a4d9357c176952b8580869d826dccd5335901e563048debd2d51494065b577d46d8e014b6dfaf014bcb64b64aa3daa315b0392b3103a
data/.travis.yml CHANGED
@@ -1,8 +1,11 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.16.0
4
+ - 2.4
5
+ - 2.5
6
+ before_install:
7
+ - gem install bundler -v 1.16.0
8
+ - bundle config mirror.https://rubygems.org https://gems.jutonz.com
6
9
  deploy:
7
10
  provider: rubygems
8
11
  api_key:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dctl_rb (0.12.0)
4
+ dctl_rb (0.13.0)
5
5
  config (>= 1, < 2)
6
6
  rainbow (>= 2.2, < 3)
7
7
  rake (~> 12)
@@ -10,7 +10,7 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (5.2.0)
13
+ activesupport (5.2.1)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
@@ -43,14 +43,14 @@ GEM
43
43
  dry-equalizer (~> 0.2)
44
44
  dry-inflector (~> 0.1, >= 0.1.2)
45
45
  dry-logic (~> 0.4, >= 0.4.2)
46
- dry-validation (0.12.1)
46
+ dry-validation (0.12.2)
47
47
  concurrent-ruby (~> 1.0)
48
48
  dry-configurable (~> 0.1, >= 0.1.3)
49
49
  dry-core (~> 0.2, >= 0.2.1)
50
50
  dry-equalizer (~> 0.2)
51
51
  dry-logic (~> 0.4, >= 0.4.0)
52
52
  dry-types (~> 0.13.1)
53
- i18n (1.0.1)
53
+ i18n (1.1.0)
54
54
  concurrent-ruby (~> 1.0)
55
55
  minitest (5.11.3)
56
56
  rainbow (2.2.2)
data/README.md CHANGED
@@ -127,7 +127,20 @@ docker
127
127
  * `project` (required)
128
128
 
129
129
  ### Optional keys
130
- * none yet
130
+ * `custom_commands`
131
+ * This is basically a set of aliases you can add if you happen to be running the same commands again and again
132
+
133
+ For instance, if initially creating your database requires two commands, you can add an alias to make it just one:
134
+ ```yaml
135
+ custom_commands:
136
+ migrate:
137
+ - dctl run --rm psql initdb
138
+ - dctl run --rm app mix ecto.setup
139
+ ```
140
+
141
+ Now you can just run `dctl migrate` and it will run the commands in the order you specified.
142
+
143
+ This just shells out, so you can also add any stuff you'd normally do in bash.
131
144
 
132
145
  ## Development
133
146
 
data/exe/dctl CHANGED
@@ -21,7 +21,6 @@ module Dctl
21
21
  class_option :host, type: :string
22
22
 
23
23
  desc "build", "Build images. Pass image name to build a specific one; otherwise builds all"
24
- option :pull, type: :boolean, desc: "Pull before building (same as docker build --pull)"
25
24
  option :cache_from, type: :string
26
25
  option :cache_from_self, type: :boolean, desc: "Uses the tag being built " \
27
26
  "as the cache source. Useful for rebuilding images where the cache is " \
@@ -48,7 +47,6 @@ module Dctl
48
47
  dockerfile = dctl.image_dockerfile(image)
49
48
 
50
49
  build_opts = %W(-f=#{dockerfile} -t=#{tag})
51
- build_opts << "--pull=true" if options[:pull]
52
50
  build_opts << "--cache-from=#{tag}" if options[:cache_from_self]
53
51
  build_opts << extra_args
54
52
  if options[:cache_from]
@@ -61,7 +59,7 @@ module Dctl
61
59
  build_opts << "--cache-from=#{options[:cache_from]}"
62
60
  end
63
61
 
64
- commands << "#{sudo}docker #{docker_opts} build #{build_opts.join(" ")} ."
62
+ commands << docker_command("build", *build_opts, ".")
65
63
  end
66
64
 
67
65
  stream_output commands.join(" && "), exec: true
@@ -75,7 +73,7 @@ module Dctl
75
73
 
76
74
  images.each do |image|
77
75
  tag = dctl.image_tag(image)
78
- push_cmds << "#{sudo}docker #{docker_opts} push #{tag}"
76
+ push_cmds << docker_command("push", tag)
79
77
  end
80
78
 
81
79
  push_cmd = push_cmds.join " && "
@@ -87,17 +85,17 @@ module Dctl
87
85
  def pull(*images)
88
86
  dctl = Dctl::Main.new env: dctl_env
89
87
  images = dctl.expand_images *images
90
- pull_cmds = []
88
+ pull_commands = []
91
89
 
92
90
  images.each do |image|
93
91
  opts = {}
94
92
  opts[:version] = options[:version] if options[:version]
95
93
  tag = dctl.image_tag(image, opts)
96
- pull_cmds << "#{sudo}docker #{docker_opts} pull #{tag}"
94
+ pull_commands << docker_command("pull", tag)
97
95
  end
98
96
 
99
- pull_cmd = pull_cmds.join " && "
100
- stream_output pull_cmd, exec: true
97
+ pull_command = pull_commands.join " && "
98
+ stream_output pull_command, exec: true
101
99
  end
102
100
 
103
101
  desc "up", "Start your dockerized app server"
@@ -108,13 +106,13 @@ module Dctl
108
106
  FileUtils.rm pidfile if File.exist? pidfile
109
107
 
110
108
  compose_opts = %w(--remove-orphans)
111
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} up #{compose_opts.join(" ")}", exec: true
109
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} up #{compose_opts.join(" ")}", exec: true
112
110
  end
113
111
 
114
112
  desc "down", "Stop one or many containers"
115
113
  def down(*images)
116
114
  dctl = Dctl::Main.new env: dctl_env
117
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} down #{images.join(" ")}", exec: true
115
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} down #{images.join(" ")}", exec: true
118
116
  end
119
117
 
120
118
  desc "rm", "Remove one or many containers"
@@ -122,44 +120,44 @@ module Dctl
122
120
  def rm(*images)
123
121
  dctl = Dctl::Main.new env: dctl_env
124
122
  opts = " --force" if options[:force]
125
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} rm#{opts} #{images.join(" ")}", exec: true
123
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} rm#{opts} #{images.join(" ")}", exec: true
126
124
  end
127
125
 
128
126
  desc "start", "Start one or many containers"
129
127
  def start(*images)
130
128
  dctl = Dctl::Main.new env: dctl_env
131
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} start #{images.join(" ")}", exec: true
129
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} start #{images.join(" ")}", exec: true
132
130
  end
133
131
 
134
132
  desc "stop", "Stop one or many containers"
135
133
  def stop(*images)
136
134
  dctl = Dctl::Main.new env: dctl_env
137
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} stop #{images.join(" ")}", exec: true
135
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} stop #{images.join(" ")}", exec: true
138
136
  end
139
137
 
140
138
  desc "restart", "Restart one or many containers"
141
139
  def restart(*images)
142
140
  dctl = Dctl::Main.new env: dctl_env
143
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} restart #{images.join(" ")}", exec: true
141
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} restart #{images.join(" ")}", exec: true
144
142
  end
145
143
 
146
144
  desc "create", "Bring an image up without starting it"
147
145
  def create(*images)
148
146
  dctl = Dctl::Main.new env: dctl_env
149
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} up --no-start #{images.join(" ")}", exec: true
147
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} up --no-start #{images.join(" ")}", exec: true
150
148
  end
151
149
 
152
150
  desc "run [IMAGE] [COMMAND]", "Run a command on the given image"
153
151
  def runcmd(image, *commands)
154
152
  dctl = Dctl::Main.new env: dctl_env
155
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run #{image} #{commands.join(" ")}", exec: true
153
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run #{image} #{commands.join(" ")}", exec: true
156
154
  end
157
155
 
158
156
  desc "exec [IMAGE] [COMMAND]", "Execute a command on the given _running_ image"
159
157
  map exec: :_exec # avoid overwriting Kernel#exec
160
158
  def _exec(image, *commands)
161
159
  dctl = Dctl::Main.new env: dctl_env
162
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} #{commands.join(" ")}", exec: true
160
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} #{commands.join(" ")}", exec: true
163
161
  end
164
162
 
165
163
  desc "recreate", "Stop, remove, build, create, and start a container"
@@ -176,13 +174,13 @@ module Dctl
176
174
  desc "ps", "List running containers for this environment"
177
175
  def ps
178
176
  dctl = Dctl::Main.new env: dctl_env
179
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} ps", exec: true
177
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} ps", exec: true
180
178
  end
181
179
 
182
- desc "release IMAGE", "Increase the version number for the given image"
183
- def release(image)
180
+ desc "bump IMAGE", "Increase the version number for the given image"
181
+ def bump(image)
184
182
  dctl = Dctl::Main.new env: dctl_env
185
- dctl.release(image)
183
+ dctl.bump(image)
186
184
  end
187
185
 
188
186
  desc "initdb", "Setup initial postgres database"
@@ -190,9 +188,9 @@ module Dctl
190
188
  dctl = Dctl::Main.new env: dctl_env
191
189
  env = dctl_env
192
190
  local_data_dir = File.expand_path "../tmp/psql-#{env}", __FILE__
193
- `#{sudo}rm -r #{local_data_dir}` if File.exists? local_data_dir # todo prompt
191
+ `#{sudo} rm -r #{local_data_dir}` if File.exists? local_data_dir # todo prompt
194
192
 
195
- cmd = "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm psql /bin/bash -c /etc/initdb.sh"
193
+ cmd = "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm psql /bin/bash -c /etc/initdb.sh"
196
194
 
197
195
  stream_output cmd, exec: true
198
196
  end
@@ -201,7 +199,7 @@ module Dctl
201
199
  option :keep, type: :numeric, default: -1, desc: "How many old images to keep around, e.g. \"3\" will keep the current version plus the three next most recent. Use -1 to keep all."
202
200
  def cleanup
203
201
  to_remove = []
204
- to_remove += `#{sudo}docker images --filter dangling=true -q`.split("\n")
202
+ to_remove += `#{docker_command("images", "--filter dangling=true", "-q")}`.split("\n")
205
203
 
206
204
  if options[:keep] != -1
207
205
  keep_last = options[:keep]
@@ -211,8 +209,14 @@ module Dctl
211
209
  keep_after_tag = current_version - keep_last
212
210
 
213
211
  next if keep_after_tag < 0
214
-
215
- cmd = "#{sudo}docker #{docker_opts} images #{dctl.image_tag(image, version: nil)} --filter before=#{dctl.image_tag(image, version: keep_after_tag)} -q"
212
+ cmd = docker_command()
213
+
214
+ cmd = docker_command(
215
+ "images",
216
+ dctl.image_tag(image, version: nil),
217
+ "--filter before=#{dctl.image_tag(image, version: keep_after_tag)}",
218
+ "-q"
219
+ )
216
220
  puts Rainbow(cmd).fg CMD_COLOR
217
221
  stdout, stderr, status = Open3.capture3(cmd)
218
222
  if status.success?
@@ -221,9 +225,13 @@ module Dctl
221
225
  # Specified before filter did not exist on current machine. Loop
222
226
  # through all old images to manually reconstruct.
223
227
  Array(0..keep_after_tag).each do |version|
224
- cmd = "#{sudo}docker images #{dctl.image_tag(image, version: version)} -q"
225
- puts Rainbow(cmd).fg CMD_COLOR
226
- image_id = `#{cmd}`.strip
228
+ command = docker_command(
229
+ "images",
230
+ dctl.image_tag(image, version: version),
231
+ "-q"
232
+ )
233
+ puts Rainbow(command).fg CMD_COLOR
234
+ image_id = `#{command}`.strip
227
235
  to_remove << image_id unless image_id.empty?
228
236
  end
229
237
  end
@@ -235,13 +243,13 @@ module Dctl
235
243
  exit 0
236
244
  end
237
245
 
238
- stream_output "#{sudo}docker rmi -f #{to_remove.join(" ")}", exec: true
246
+ stream_output "#{sudo} docker rmi -f #{to_remove.join(" ")}", exec: true
239
247
  end
240
248
 
241
249
  desc "bash CONTAINER", "Create a new instance of the given image with a bash prompt"
242
250
  def bash(container = "app")
243
251
  dctl = Dctl::Main.new env: dctl_env
244
- cmd = "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm #{container} /bin/bash"
252
+ cmd = "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm #{container} /bin/bash"
245
253
 
246
254
  stream_output cmd, exec: true
247
255
  end
@@ -249,7 +257,7 @@ module Dctl
249
257
  desc "connect CONTAINER", "Connect to a running container."
250
258
  def connect(image = "app")
251
259
  dctl = Dctl::Main.new env: dctl_env
252
- stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} /bin/bash", exec: true
260
+ stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} /bin/bash", exec: true
253
261
  end
254
262
 
255
263
  desc "attach CONTAINER", "Connect to a running container."
@@ -258,7 +266,7 @@ module Dctl
258
266
  dctl = Dctl::Main.new env: dctl_env
259
267
  tag = dctl.image_tag(image)
260
268
 
261
- cmd = "#{sudo}docker #{docker_opts} ps --filter ancestor=#{image} -aq | head -n1"
269
+ cmd = "#{sudo} docker #{docker_opts} ps --filter ancestor=#{image} -aq | head -n1"
262
270
  puts cmd
263
271
  container = `#{cmd}`.chomp
264
272
 
@@ -267,7 +275,7 @@ module Dctl
267
275
  exit 1
268
276
  end
269
277
 
270
- stream_output "#{sudo}docker attach #{container}", exec: true
278
+ stream_output "#{sudo} docker attach #{container}", exec: true
271
279
  end
272
280
 
273
281
  desc "version", "Print version"
@@ -298,7 +306,7 @@ module Dctl
298
306
 
299
307
  def sudo
300
308
  return "" if !ENV["DCTL_NOSUDO"].nil?
301
- `uname`.chomp == "Darwin" ? "" : "sudo " # use sudo on linux hosts
309
+ `uname`.chomp == "Darwin" ? "" : "sudo" # use sudo on linux hosts
302
310
  end
303
311
 
304
312
  # Support both --env and DCTL_ENV, but prefer --env if both are present
@@ -306,6 +314,14 @@ module Dctl
306
314
  options[:env] || ENV["DCTL_ENV"] || "dev"
307
315
  end
308
316
 
317
+ def docker_command(*args)
318
+ build_command(sudo, "docker", docker_opts, *args)
319
+ end
320
+
321
+ def build_command(*args)
322
+ args.reject(&:nil?).reject(&:empty?).join(" ")
323
+ end
324
+
309
325
  # Allow passsing additional docker args without us having to implement
310
326
  # each one manually, e.g. `dctl build app -- --pull`
311
327
  def extract_extra_args(images)
@@ -326,10 +342,12 @@ module Dctl
326
342
  host ||= !ENV["DOCKER_HOST"].nil? ? ENV["DOCKER_HOST"] : nil
327
343
  opts << "--host #{host}" if host
328
344
 
329
- opts.join " "
345
+ opts.join(" ")
330
346
  end
331
347
  end
332
348
  end
333
349
  end
334
350
 
351
+ dctl = Dctl::Main.new
352
+ dctl.define_custom_commands(Dctl::Cli)
335
353
  Dctl::Cli.start ARGV
data/lib/dctl/main.rb CHANGED
@@ -2,9 +2,9 @@ module Dctl
2
2
  class Main
3
3
  attr_reader :env, :settings
4
4
 
5
- def initialize(env: "dev")
5
+ def initialize(env: "dev", config: nil)
6
6
  @env = env
7
- load_config!
7
+ load_config!(config)
8
8
  end
9
9
 
10
10
  ##
@@ -51,7 +51,7 @@ module Dctl
51
51
  images
52
52
  end
53
53
 
54
- def release(image)
54
+ def bump(image)
55
55
  check_image(image)
56
56
 
57
57
  parsed = parsed_compose_file
@@ -149,6 +149,18 @@ module Dctl
149
149
  @parsed_compose_file ||= YAML.load_file compose_file_path
150
150
  end
151
151
 
152
+ ##
153
+ # If there are user defined commands in .dctl.yml, dynamically add them to
154
+ # the passed thor CLI so they may be executed.
155
+ def define_custom_commands(klass)
156
+ Array(settings.custom_commands).each do |command, args|
157
+ klass.send(:desc, command, "[Custom Command] #{command}")
158
+ klass.send(:define_method, command, -> do
159
+ Array(args).each { |a| stream_output(a) }
160
+ end)
161
+ end
162
+ end
163
+
152
164
  ##
153
165
  # Ensure the current project's .dctl.yml contains all the requisite keys.
154
166
  def check_settings!
@@ -171,8 +183,8 @@ module Dctl
171
183
  ##
172
184
  # Load the current project's config file, complaining if it does not exist
173
185
  # or is malformed.
174
- def load_config!
175
- Config.load_and_set_settings(config_path)
186
+ def load_config!(custom_config_path = nil)
187
+ Config.load_and_set_settings(custom_config_path || config_path)
176
188
  check_settings!
177
189
 
178
190
  @settings = Settings
data/lib/dctl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dctl
2
- VERSION = "0.12.0"
2
+ VERSION = "0.13.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dctl_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Toniazzo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-11 00:00:00.000000000 Z
11
+ date: 2018-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler