dctl_rb 0.12.0 → 0.13.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.
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