vagrant-docker-hosts-manager 0.3.0 → 0.4.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.
@@ -10,281 +10,278 @@ module VagrantDockerHostsManager
10
10
  json: false,
11
11
  dry: false,
12
12
  lang: nil,
13
- no_emoji: false
13
+ no_emoji: false,
14
+ yes: false,
15
+ all: false
14
16
  }
15
17
 
16
- raw_argv = @argv.dup
17
- help_topic = begin
18
- i = raw_argv.index { |x| x =~ /\A(?:help|--help|-h)\z/ }
19
- cand = (i && raw_argv[i + 1]) ? raw_argv[i + 1] : nil
20
- (cand && cand !~ /\A-/) ? cand : nil
21
- rescue StandardError
22
- nil
23
- end
18
+ help_topic = extract_help_topic(@argv)
24
19
 
25
20
  parser = OptionParser.new do |o|
26
21
  o.banner = "Usage: vagrant hosts <apply|remove|view|help|version> [options]"
27
22
  o.on("--json", "Machine-readable JSON output") { opts[:json] = true }
28
23
  o.on("--lang LANG", "Force language (en|fr)") { |v| opts[:lang] = v }
29
24
  o.on("--no-emoji", "Disable emoji in CLI output") { opts[:no_emoji] = true }
30
- o.on("-h", "--help", "Show help") { print_help(@env.ui); return 0 }
25
+ o.on("-y", "--yes", "Auto-confirm destructive operations") { opts[:yes] = true }
26
+ o.on("--all", "--prune", "remove: purge ALL managed blocks (every machine, incl. orphans)") { opts[:all] = true }
31
27
  end
32
28
 
33
29
  argv = parse_options(parser)
34
30
  return 0 unless argv
35
31
 
36
32
  action = argv.shift
37
- env = @env
38
33
 
39
- Util::I18n.setup!(env, forced: opts[:lang])
34
+ Util::I18n.setup!(@env, forced: opts[:lang])
40
35
  Util::I18n.set_json_mode(opts[:json])
41
36
  ENV["VDHM_DRY_RUN"] = "1" if opts[:dry]
42
37
  ENV["VDHM_NO_EMOJI"] = "1" if opts[:no_emoji]
43
38
 
39
+ dispatch(action, argv, opts, help_topic)
40
+ rescue StandardError => e
41
+ Util::Json.emit(action: "command", status: "error", error: e.message)
42
+ UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} #{e.message}") unless opts[:json]
43
+ 1
44
+ end
45
+
46
+ private
47
+
48
+ def dispatch(action, argv, opts, help_topic)
44
49
  case action
45
- when nil, "", "help", "--help", "-h"
46
- topic = help_topic || argv.shift
47
- print_help(@env.ui, topic: topic, no_emoji: opts[:no_emoji])
48
- return 0
49
- when "version"
50
- if opts[:json]
51
- Util::Json.emit(action: "version", status: "success", data: { version: VagrantDockerHostsManager::VERSION })
50
+ when nil, "", "help"
51
+ print_help(@env.ui, topic: help_topic || argv.shift, no_emoji: opts[:no_emoji])
52
+ 0
53
+ when "version" then cmd_version(opts)
54
+ when "apply" then cmd_apply(argv, opts)
55
+ when "remove" then cmd_remove(argv, opts)
56
+ when "view" then cmd_view(argv, opts)
57
+ else
58
+ print_help(@env.ui, no_emoji: opts[:no_emoji])
59
+ 0
60
+ end
61
+ end
62
+
63
+ def extract_help_topic(raw_argv)
64
+ i = raw_argv.index { |x| x =~ /\A(?:help|--help|-h)\z/ }
65
+ cand = (i && raw_argv[i + 1]) ? raw_argv[i + 1] : nil
66
+ (cand && cand !~ /\A-/) ? cand : nil
67
+ rescue StandardError
68
+ nil
69
+ end
70
+
71
+ def cmd_version(opts)
72
+ if opts[:json]
73
+ Util::Json.emit(action: "version", status: "success", data: { version: VagrantDockerHostsManager::VERSION })
74
+ else
75
+ emoji = UiHelpers.e(:version, no_emoji: opts[:no_emoji])
76
+ line = ::I18n.t("vdhm.log.version_line",
77
+ default: "vagrant-docker-hosts-manager version %{version}",
78
+ version: VagrantDockerHostsManager::VERSION)
79
+ UiHelpers.say(@env.ui, "#{emoji} #{line}")
80
+ end
81
+ 0
82
+ end
83
+
84
+ def cmd_apply(argv, opts)
85
+ begin
86
+ ip_for_apply, host_for_apply =
87
+ parse_strict_mapping_from_argv!(argv, @env.ui, opts[:no_emoji], json: opts[:json])
88
+ rescue ArgumentError => e
89
+ Util::Json.emit(action: "apply", status: "error", error: e.message) if opts[:json]
90
+ return 1
91
+ end
92
+
93
+ machine = require_target_vm("apply", argv, opts) or return 1
94
+
95
+ if ip_for_apply || host_for_apply
96
+ code = validate_apply_mapping(ip_for_apply, host_for_apply, opts)
97
+ return code if code
98
+ end
99
+
100
+ mid = machine.id || "unknown"
101
+ hoster = Util::HostsFile.new({ machine: machine, ui: @env.ui }, owner_id: mid)
102
+
103
+ entries =
104
+ if ip_for_apply && host_for_apply
105
+ { host_for_apply => ip_for_apply }
52
106
  else
53
- emoji = UiHelpers.e(:version, no_emoji: opts[:no_emoji])
54
- line = ::I18n.t("log.version_line",
55
- default: "vagrant-docker-hosts-manager version %{version}",
56
- version: VagrantDockerHostsManager::VERSION)
57
- UiHelpers.say(@env.ui, "#{emoji} #{line}")
107
+ compute_entries(machine, machine.config.docker_hosts)
58
108
  end
109
+
110
+ if entries.empty?
111
+ say_info(::I18n.t("vdhm.messages.no_entries", default: "No hosts entries configured."), opts)
112
+ Util::Json.emit(action: "apply", status: "noop", data: { reason: "no entries" })
59
113
  return 0
60
114
  end
61
115
 
62
- machine = nil
116
+ return 0 if opts[:dry] && Util::Json.emit(action: "apply", status: "dry-run", data: { entries: entries })
63
117
 
64
- case action
65
- when "apply"
66
- begin
67
- ip_for_apply, host_for_apply =
68
- parse_strict_mapping_from_argv!(argv, @env.ui, opts[:no_emoji], json: opts[:json])
69
- rescue ArgumentError => e
70
- Util::Json.emit(action: "apply", status: "error", error: e.message) if opts[:json]
71
- return 1
72
- end
118
+ hoster.apply(entries)
119
+ Util::Json.emit(action: "apply", status: "success", data: { entries: entries })
120
+ 0
121
+ end
73
122
 
74
- with_target_vms(argv, single_target: true) { |m| machine = m }
75
-
76
- unless machine
77
- UiHelpers.error(
78
- @env.ui,
79
- "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
80
- ::I18n.t(
81
- "errors.no_machine",
82
- default: "No target machine found. Run this inside a Vagrant project or pass a VM name."
83
- )
84
- )
85
- Util::Json.emit(action: "apply", status: "error", error: "No target machine found") if opts[:json]
86
- return 1
87
- end
123
+ def validate_apply_mapping(ip, host, opts)
124
+ unless ip && host
125
+ emit_error(::I18n.t("vdhm.messages.missing_mapping",
126
+ default: "Provide both IP and FQDN (e.g. `vagrant hosts apply 1.2.3.4 example.test`)."), opts)
127
+ return 1
128
+ end
129
+ unless ipv4?(ip)
130
+ emit_error(::I18n.t("vdhm.messages.invalid_ip", default: "Invalid IPv4 address: %{ip}", ip: ip), opts)
131
+ return 1
132
+ end
133
+ unless fqdn?(host)
134
+ emit_error(::I18n.t("vdhm.messages.invalid_host", default: "Invalid host/FQDN: %{host}", host: host), opts)
135
+ return 1
136
+ end
137
+ nil
138
+ end
88
139
 
89
- if ip_for_apply || host_for_apply
90
- unless ip_for_apply && host_for_apply
91
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
92
- ::I18n.t("messages.missing_mapping",
93
- default: "Provide both IP and FQDN (e.g. `vagrant hosts apply 1.2.3.4 example.test`)."))
94
- return 1
95
- end
96
- unless ipv4?(ip_for_apply)
97
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
98
- ::I18n.t("messages.invalid_ip", default: "Invalid IPv4 address: %{ip}", ip: ip_for_apply))
99
- return 1
100
- end
101
- unless fqdn?(host_for_apply)
102
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
103
- ::I18n.t("messages.invalid_host", default: "Invalid host/FQDN: %{host}", host: host_for_apply))
104
- return 1
105
- end
106
- end
140
+ def cmd_remove(argv, opts)
141
+ return remove_all_owners(opts) if opts[:all]
107
142
 
108
- cfg = machine.config.docker_hosts
109
- mid = machine.id || "unknown"
110
- hoster = Util::HostsFile.new({ machine: machine, ui: @env.ui }, owner_id: mid)
143
+ remove_key = parse_remove_key_from_argv!(argv)
111
144
 
112
- unless ENV["VDHM_DRY_RUN"] == "1" || hoster.elevated?
113
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
114
- ::I18n.t("errors.not_admin",
115
- default: "Administrator/root privileges required to modify hosts at %{path}.",
116
- path: hoster.printable_path))
117
- return 1
118
- end
145
+ machine = require_target_vm("remove", argv, opts) or return 1
119
146
 
120
- entries = compute_entries(machine, cfg)
121
- entries[host_for_apply] = ip_for_apply if ip_for_apply && host_for_apply
147
+ if remove_key && !(ipv4?(remove_key) || fqdn?(remove_key))
148
+ emit_error(::I18n.t("vdhm.messages.invalid_key", default: "Invalid IP or FQDN: %{key}", key: remove_key), opts)
149
+ UiHelpers.error(@env.ui, " " + ::I18n.t("vdhm.messages.remove_expected_format",
150
+ default: "Expected IPv4 (e.g. 172.28.100.2) or FQDN (e.g. example.test)."))
151
+ Util::Json.emit(action: "remove", status: "error", error: "invalid parameter format") if opts[:json]
152
+ return 1
153
+ end
122
154
 
123
- if entries.empty?
124
- UiHelpers.say(@env.ui, "#{UiHelpers.e(:info, no_emoji: opts[:no_emoji])} " +
125
- ::I18n.t("messages.no_entries", default: "No hosts entries configured."))
126
- Util::Json.emit(action: "apply", status: "noop", data: { reason: "no entries" })
127
- return 0
128
- end
155
+ mid = machine.id || "unknown"
156
+ hoster = Util::HostsFile.new({ machine: machine, ui: @env.ui }, owner_id: mid)
129
157
 
130
- return 0 if opts[:dry] and Util::Json.emit(action: "apply", status: "dry-run", data: { entries: entries })
158
+ return remove_filtered(hoster, remove_key, mid, opts) if remove_key
131
159
 
132
- hoster.apply(entries)
133
- Util::Json.emit(action: "apply", status: "success", data: { entries: entries })
134
- return 0
160
+ remove_all(machine, hoster, mid, opts)
161
+ end
135
162
 
136
- when "remove"
137
- remove_key = parse_remove_key_from_argv!(argv)
138
-
139
- with_target_vms(argv, single_target: true) { |m| machine = m }
140
-
141
- unless machine
142
- UiHelpers.error(
143
- @env.ui,
144
- "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
145
- ::I18n.t(
146
- "errors.no_machine",
147
- default: "No target machine found. Run this inside a Vagrant project or pass a VM name."
148
- )
149
- )
150
- Util::Json.emit(action: "remove", status: "error", error: "No target machine found") if opts[:json]
151
- return 1
152
- end
163
+ def remove_filtered(hoster, remove_key, mid, opts)
164
+ return 0 if opts[:dry] && Util::Json.emit(action: "remove", status: "dry-run",
165
+ data: { owner: mid, key: remove_key })
166
+
167
+ removed = if ipv4?(remove_key)
168
+ hoster.remove_entries!(ips: [remove_key], domains: [])
169
+ else
170
+ hoster.remove_entries!(ips: [], domains: [remove_key])
171
+ end
172
+ Util::Json.emit(action: "remove", status: "success", data: { removed: removed, mode: "filtered" })
173
+ 0
174
+ end
153
175
 
154
- if remove_key && !(ipv4?(remove_key) || fqdn?(remove_key))
155
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
156
- ::I18n.t("messages.invalid_key",
157
- default: "Invalid IP or FQDN: %{key}", key: remove_key))
158
- UiHelpers.error(@env.ui, " " + ::I18n.t("messages.remove_expected_format",
159
- default: "Expected IPv4 (e.g. 172.28.100.2) or FQDN (e.g. example.test)."))
160
- Util::Json.emit(action: "remove", status: "error",
161
- error: "invalid parameter format") if opts[:json]
176
+ def remove_all(machine, hoster, mid, opts)
177
+ return 0 if opts[:dry] && Util::Json.emit(action: "remove", status: "dry-run", data: { owner: mid })
178
+
179
+ vm_label = (machine.name rescue nil) || mid
180
+ unless opts[:yes]
181
+ if opts[:json]
182
+ emit_error(::I18n.t("vdhm.errors.confirmation_required",
183
+ default: "Confirmation required: pass --yes to proceed in --json mode."), opts)
184
+ Util::Json.emit(action: "remove", status: "error", error: "confirmation required")
162
185
  return 1
163
186
  end
187
+ unless confirm_all_removal?(@env.ui, vm_label, no_emoji: opts[:no_emoji])
188
+ say_info(::I18n.t("vdhm.messages.remove_all_cancelled", default: "Cancelled. Nothing removed."), opts)
189
+ Util::Json.emit(action: "remove", status: "cancelled", data: { owner: mid })
190
+ return 0
191
+ end
192
+ end
164
193
 
165
- mid = machine.id || "unknown"
166
- hoster = Util::HostsFile.new({ machine: machine, ui: @env.ui }, owner_id: mid)
194
+ removed_block = hoster.remove!
195
+ Util::Json.emit(action: "remove", status: "success", data: { removed: removed_block })
196
+ 0
197
+ end
198
+
199
+ def remove_all_owners(opts)
200
+ hoster = Util::HostsFile.new({ ui: @env.ui }, owner_id: "any")
201
+ return 0 if opts[:dry] && Util::Json.emit(action: "remove", status: "dry-run", data: { mode: "all" })
167
202
 
168
- unless ENV["VDHM_DRY_RUN"] == "1" || hoster.elevated?
169
- UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} " +
170
- ::I18n.t("errors.not_admin",
171
- default: "Administrator/root privileges required to modify hosts at %{path}.",
172
- path: hoster.printable_path))
203
+ unless opts[:yes]
204
+ if opts[:json]
205
+ emit_error(::I18n.t("vdhm.errors.confirmation_required",
206
+ default: "Confirmation required: pass --yes to proceed in --json mode."), opts)
207
+ Util::Json.emit(action: "remove", status: "error", error: "confirmation required")
173
208
  return 1
174
209
  end
175
-
176
- if remove_key
177
- return 0 if opts[:dry] && Util::Json.emit(action: "remove", status: "dry-run",
178
- data: { owner: mid, key: remove_key })
179
-
180
- removed = if ipv4?(remove_key)
181
- hoster.remove_entries!(ips: [remove_key], domains: [])
182
- else
183
- hoster.remove_entries!(ips: [], domains: [remove_key])
184
- end
185
- Util::Json.emit(action: "remove", status: "success",
186
- data: { removed: removed, mode: "filtered" })
210
+ unless confirm_prune?(@env.ui, no_emoji: opts[:no_emoji])
211
+ say_info(::I18n.t("vdhm.messages.remove_all_cancelled", default: "Cancelled. Nothing removed."), opts)
212
+ Util::Json.emit(action: "remove", status: "cancelled", data: { mode: "all" })
187
213
  return 0
188
214
  end
215
+ end
189
216
 
190
- return 0 if opts[:dry] && Util::Json.emit(action: "remove", status: "dry-run", data: { owner: mid })
217
+ removed = hoster.remove_all_managed!
218
+ Util::Json.emit(action: "remove", status: "success", data: { removed: removed, mode: "all" })
219
+ 0
220
+ end
191
221
 
192
- vm_label = (machine.name rescue nil) || mid
193
- unless confirm_all_removal?(@env.ui, vm_label, no_emoji: opts[:no_emoji])
194
- UiHelpers.say(@env.ui, "#{UiHelpers.e(:info, no_emoji: opts[:no_emoji])} " +
195
- ::I18n.t("messages.remove_all_cancelled", default: "Cancelled. Nothing removed."))
196
- Util::Json.emit(action: "remove", status: "cancelled", data: { owner: mid })
197
- return 0
198
- end
222
+ def cmd_view(_argv, opts)
223
+ hoster = Util::HostsFile.new({ ui: @env.ui }, owner_id: "any")
224
+ managed_map = hoster.entries_in_blocks(:all)
225
+ pairs = collect_view_pairs({}, managed_map)
199
226
 
200
- removed_block = hoster.remove!
201
- Util::Json.emit(action: "remove", status: "success", data: { removed: removed_block })
227
+ if opts[:json]
228
+ Util::Json.emit(action: "view", status: "success",
229
+ data: { entries: pairs.map { |ip, fqdn| { ip: ip, host: fqdn } } })
202
230
  return 0
231
+ end
203
232
 
204
- when "view"
205
- hoster = Util::HostsFile.new({ ui: @env.ui }, owner_id: "any")
206
- managed_map = hoster.entries_in_blocks(:all)
207
- planned_map = {}
208
-
209
- begin
210
- vm_for_view = nil
211
- with_target_vms(argv.dup, single_target: true) { |m| vm_for_view = m }
212
- if vm_for_view
213
- cfg = vm_for_view.config.docker_hosts
214
- planned_map = compute_entries(vm_for_view, cfg)
215
- end
216
- rescue StandardError
217
- planned_map = {}
218
- end
233
+ if pairs.empty?
234
+ say_info(::I18n.t("vdhm.messages.no_entries", default: "No hosts entries configured."), opts)
235
+ return 0
236
+ end
219
237
 
220
- pairs = []
221
- seen = {}
238
+ say_info(::I18n.t("vdhm.messages.view_managed_header", default: "Managed hosts entries:"), opts)
239
+ pad = pairs.map { |ip, _| ip.length }.max || 0
240
+ pairs.each { |ip, fqdn| UiHelpers.say(@env.ui, " • #{ip.ljust(pad)} -> #{fqdn}") }
241
+ 0
242
+ end
222
243
 
223
- planned_map.each do |fqdn, ip|
224
- next if fqdn.to_s.empty? || ip.to_s.empty?
225
- key = "#{ip}\0#{fqdn}"
226
- next if seen[key]
227
- pairs << [ip.to_s, fqdn.to_s]
228
- seen[key] = true
229
- end
244
+ def collect_view_pairs(planned_map, managed_map)
245
+ pairs = []
246
+ seen = {}
247
+ add = lambda do |ip, fqdn|
248
+ return if fqdn.to_s.empty? || ip.to_s.empty?
230
249
 
231
- managed_map.each do |fqdn, ips|
232
- next if fqdn.to_s.empty?
233
- Array(ips).each do |ip|
234
- next if ip.to_s.empty?
235
- key = "#{ip}\0#{fqdn}"
236
- next if seen[key]
237
- pairs << [ip.to_s, fqdn.to_s]
238
- seen[key] = true
239
- end
240
- end
250
+ key = "#{ip}\0#{fqdn}"
251
+ return if seen[key]
241
252
 
242
- if opts[:json]
243
- Util::Json.emit(
244
- action: "view",
245
- status: "success",
246
- data: { entries: pairs.map { |ip, fqdn| { ip: ip, host: fqdn } } }
247
- )
248
- return 0
249
- end
253
+ pairs << [ip.to_s, fqdn.to_s]
254
+ seen[key] = true
255
+ end
250
256
 
251
- emoji_info = UiHelpers.e(:info, no_emoji: opts[:no_emoji])
257
+ planned_map.each { |fqdn, ip| add.call(ip, fqdn) }
258
+ managed_map.each { |fqdn, ips| Array(ips).each { |ip| add.call(ip, fqdn) } }
259
+ pairs
260
+ end
252
261
 
253
- if pairs.empty?
254
- UiHelpers.say(@env.ui, "#{emoji_info} " + ::I18n.t("messages.no_entries",
255
- default: "No hosts entries configured."))
256
- return 0
257
- end
262
+ def require_target_vm(action, argv, opts)
263
+ machine = nil
264
+ with_target_vms(argv, single_target: true) { |m| machine = m }
265
+ return machine if machine
258
266
 
259
- header =
260
- if planned_map.any?
261
- ::I18n.t("messages.view_header", default: "Planned hosts entries:")
262
- else
263
- ::I18n.t("messages.view_managed_header", default: "Managed hosts entries:")
264
- end
265
-
266
- UiHelpers.say(@env.ui, "#{emoji_info} #{header}")
267
- pad = pairs.map { |ip, _| ip.length }.max || 0
268
- pairs.each do |ip, fqdn|
269
- UiHelpers.say(@env.ui, " • #{ip.ljust(pad)} -> #{fqdn}")
270
- end
271
- return 0
267
+ emit_error(::I18n.t("vdhm.errors.no_machine",
268
+ default: "No target machine found. Run this inside a Vagrant project or pass a VM name."), opts)
269
+ Util::Json.emit(action: action, status: "error", error: "No target machine found") if opts[:json]
270
+ nil
271
+ end
272
272
 
273
- else
274
- print_help(@env.ui, no_emoji: opts[:no_emoji])
275
- return 0
276
- end
277
- rescue StandardError => e
278
- Util::Json.emit(action: "command", status: "error", error: e.message)
279
- 1
273
+ def emit_error(message, opts)
274
+ UiHelpers.error(@env.ui, "#{UiHelpers.e(:error, no_emoji: opts[:no_emoji])} #{message}")
280
275
  end
281
276
 
282
- private
277
+ def say_info(message, opts)
278
+ UiHelpers.say(@env.ui, "#{UiHelpers.e(:info, no_emoji: opts[:no_emoji])} #{message}")
279
+ end
283
280
 
284
281
  def confirm_all_removal?(ui, vm_label, no_emoji:)
285
282
  prompt = ::I18n.t(
286
- "messages.confirm_remove_all",
287
- default: "This will remove ALL managed hosts entries for %{vm}. Continue? (yes/No)",
283
+ "vdhm.messages.confirm_remove_all",
284
+ default: "This will remove ALL managed hosts entries for %{vm}. Continue? (y/N)",
288
285
  vm: vm_label.to_s
289
286
  )
290
287
 
@@ -303,6 +300,27 @@ module VagrantDockerHostsManager
303
300
  %w[y yes].include?(answer.strip.downcase)
304
301
  end
305
302
 
303
+ def confirm_prune?(ui, no_emoji:)
304
+ prompt = ::I18n.t(
305
+ "vdhm.messages.confirm_prune",
306
+ default: "This will remove ALL managed hosts blocks from EVERY machine (orphans included). Continue? (y/N)"
307
+ )
308
+
309
+ line = "#{UiHelpers.e(:question, no_emoji: no_emoji)} #{prompt} "
310
+
311
+ begin
312
+ $stdout.print(line)
313
+ $stdout.flush
314
+ answer = ($stdin.gets || "").to_s
315
+ rescue StandardError
316
+ answer = ""
317
+ ensure
318
+ $stdout.puts ""
319
+ end
320
+
321
+ %w[y yes].include?(answer.strip.downcase)
322
+ end
323
+
306
324
  def parse_strict_mapping_from_argv!(argv, ui, no_emoji, json: false)
307
325
  return [nil, nil] if argv.empty?
308
326
 
@@ -310,13 +328,13 @@ module VagrantDockerHostsManager
310
328
  cand_ip, cand_host = argv[0], argv[1]
311
329
 
312
330
  unless ipv4?(cand_ip)
313
- msg = ::I18n.t("messages.invalid_ip", default: "Invalid IPv4 address: %{ip}", ip: cand_ip)
331
+ msg = ::I18n.t("vdhm.messages.invalid_ip", default: "Invalid IPv4 address: %{ip}", ip: cand_ip)
314
332
  UiHelpers.error(ui, "#{UiHelpers.e(:error, no_emoji: no_emoji)} #{msg}")
315
333
  raise ArgumentError, msg
316
334
  end
317
335
 
318
336
  unless fqdn?(cand_host)
319
- msg = ::I18n.t("messages.invalid_host", default: "Invalid host/FQDN: %{host}", host: cand_host)
337
+ msg = ::I18n.t("vdhm.messages.invalid_host", default: "Invalid host/FQDN: %{host}", host: cand_host)
320
338
  UiHelpers.error(ui, "#{UiHelpers.e(:error, no_emoji: no_emoji)} #{msg}")
321
339
  raise ArgumentError, msg
322
340
  end
@@ -326,7 +344,7 @@ module VagrantDockerHostsManager
326
344
  end
327
345
 
328
346
  if ipv4?(argv[0])
329
- msg = ::I18n.t("messages.missing_mapping",
347
+ msg = ::I18n.t("vdhm.messages.missing_mapping",
330
348
  default: "Provide both IP and FQDN (e.g. `vagrant hosts apply 1.2.3.4 example.test`).")
331
349
  UiHelpers.error(ui, "#{UiHelpers.e(:error, no_emoji: no_emoji)} #{msg}")
332
350
  raise ArgumentError, msg
@@ -347,17 +365,6 @@ module VagrantDockerHostsManager
347
365
  s.split(".").all? { |lab| lab =~ /\A[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\z/ }
348
366
  end
349
367
 
350
- def parse_mapping_from_argv!(argv)
351
- return [nil, nil] if argv.length < 2
352
- cand_ip, cand_host = argv[0], argv[1]
353
- if ipv4?(cand_ip) && cand_host !~ /\A-/
354
- argv.shift(2)
355
- [cand_ip, cand_host]
356
- else
357
- [nil, nil]
358
- end
359
- end
360
-
361
368
  def parse_remove_key_from_argv!(argv)
362
369
  return nil if argv.empty?
363
370
  cand = argv[0]
@@ -391,47 +398,47 @@ module VagrantDockerHostsManager
391
398
  return print_topic_help(ui, topic.to_s.downcase.strip, no_emoji: no_emoji) if topic && !topic.to_s.strip.empty?
392
399
 
393
400
  emoji_info = UiHelpers.e(:info, no_emoji: no_emoji)
394
- title = ::I18n.t("help.title", default: "Vagrant Docker Hosts Manager")
401
+ title = ::I18n.t("vdhm.help.title", default: "Vagrant Docker Hosts Manager")
395
402
  UiHelpers.say(ui, "#{emoji_info} #{title}")
396
403
 
397
- UiHelpers.say(ui, ::I18n.t("help.usage",
404
+ UiHelpers.say(ui, ::I18n.t("vdhm.help.usage",
398
405
  default: "Usage: vagrant hosts <apply|remove|view|help|version> [options]"))
399
406
  UiHelpers.say(ui, "")
400
407
 
401
- UiHelpers.say(ui, ::I18n.t("help.commands_header", default: "Commands:"))
402
- cmds = ::I18n.t("help.commands", default: {})
408
+ UiHelpers.say(ui, ::I18n.t("vdhm.help.commands_header", default: "Commands:"))
409
+ cmds = ::I18n.t("vdhm.help.commands", default: {})
403
410
  cmds = {} unless cmds.is_a?(Hash)
404
411
  cmds.each_value { |line| UiHelpers.say(ui, " #{line}") }
405
412
 
406
413
  UiHelpers.say(ui, "")
407
- UiHelpers.say(ui, ::I18n.t("help.options_header", default: "Options:"))
408
- optsh = ::I18n.t("help.options", default: {})
414
+ UiHelpers.say(ui, ::I18n.t("vdhm.help.options_header", default: "Options:"))
415
+ optsh = ::I18n.t("vdhm.help.options", default: {})
409
416
  optsh = {} unless optsh.is_a?(Hash)
410
417
  optsh.each_value { |line| UiHelpers.say(ui, " #{line}") }
411
418
 
412
- topics = (::I18n.t("help.topic", default: {}).is_a?(Hash) ? ::I18n.t("help.topic").keys.map(&:to_s) : [])
419
+ topics = (::I18n.t("vdhm.help.topic", default: {}).is_a?(Hash) ? ::I18n.t("vdhm.help.topic").keys.map(&:to_s) : [])
413
420
  topics = %w[apply remove view version help] if topics.empty?
414
421
 
415
422
  UiHelpers.say(ui, "")
416
- UiHelpers.say(ui, ::I18n.t("help.topics_header", default: "Help topics:"))
423
+ UiHelpers.say(ui, ::I18n.t("vdhm.help.topics_header", default: "Help topics:"))
417
424
  UiHelpers.say(ui, " vagrant hosts help <#{topics.join('|')}>")
418
425
  end
419
426
 
420
427
  def print_topic_help(ui, topic, no_emoji: false)
421
- base = "help.topic.#{topic}"
428
+ base = "vdhm.help.topic.#{topic}"
422
429
  wrench = UiHelpers.e(:info, no_emoji: no_emoji)
423
430
 
424
- title = ::I18n.t("#{base}.title", default: topic)
425
- usage = ::I18n.t("#{base}.usage", default: nil)
426
- desc = ::I18n.t("#{base}.description", default: nil)
427
- opts_hash = ::I18n.t("#{base}.options", default: {})
428
- examples = ::I18n.t("#{base}.examples", default: [])
429
-
430
- t_head = ::I18n.t("help.topic_header", default: "Help: vagrant hosts %{topic}", topic: topic)
431
- t_usage = ::I18n.t("help.usage_label", default: "Usage:")
432
- t_desc = ::I18n.t("help.description_label", default: "Description:")
433
- t_opts = ::I18n.t("help.options_label", default: "Options:")
434
- t_exs = ::I18n.t("help.examples_label", default: "Examples:")
431
+ title = ::I18n.t("vdhm.#{base}.title", default: topic)
432
+ usage = ::I18n.t("vdhm.#{base}.usage", default: nil)
433
+ desc = ::I18n.t("vdhm.#{base}.description", default: nil)
434
+ opts_hash = ::I18n.t("vdhm.#{base}.options", default: {})
435
+ examples = ::I18n.t("vdhm.#{base}.examples", default: [])
436
+
437
+ t_head = ::I18n.t("vdhm.help.topic_header", default: "Help: vagrant hosts %{topic}", topic: topic)
438
+ t_usage = ::I18n.t("vdhm.help.usage_label", default: "Usage:")
439
+ t_desc = ::I18n.t("vdhm.help.description_label", default: "Description:")
440
+ t_opts = ::I18n.t("vdhm.help.options_label", default: "Options:")
441
+ t_exs = ::I18n.t("vdhm.help.examples_label", default: "Examples:")
435
442
 
436
443
  UiHelpers.say(ui, "#{wrench} #{t_head}")
437
444