vagrant-ssh-config-manager 0.8.3 → 1.0.0.alpha

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.bundle/config +1 -1
  3. data/.gitignore +2 -1
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +62 -0
  6. data/Gemfile +11 -9
  7. data/README.md +2 -2
  8. data/Rakefile +10 -8
  9. data/TESTING.md +82 -0
  10. data/lib/vagrant/ssh/config/manager.rb +5 -0
  11. data/lib/vagrant_ssh_config_manager/action/destroy.rb +82 -0
  12. data/lib/vagrant_ssh_config_manager/action/halt.rb +66 -0
  13. data/lib/vagrant_ssh_config_manager/action/provision.rb +81 -0
  14. data/lib/vagrant_ssh_config_manager/action/reload.rb +105 -0
  15. data/lib/vagrant_ssh_config_manager/action/up.rb +98 -0
  16. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/config.rb +45 -49
  17. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/file_locker.rb +35 -37
  18. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/file_manager.rb +90 -80
  19. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/include_manager.rb +54 -53
  20. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/plugin.rb +15 -13
  21. data/lib/vagrant_ssh_config_manager/ssh_config_manager.rb +1152 -0
  22. data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/ssh_info_extractor.rb +129 -141
  23. data/lib/vagrant_ssh_config_manager/version.rb +7 -0
  24. data/lib/{vagrant-ssh-config-manager.rb → vagrant_ssh_config_manager.rb} +15 -12
  25. data/test-all.sh +11 -0
  26. data/test-integration.sh +4 -0
  27. data/test-unit.sh +4 -0
  28. data/vagrant-ssh-config-manager.gemspec +25 -21
  29. metadata +28 -18
  30. data/lib/vagrant-ssh-config-manager/action/destroy.rb +0 -84
  31. data/lib/vagrant-ssh-config-manager/action/halt.rb +0 -68
  32. data/lib/vagrant-ssh-config-manager/action/provision.rb +0 -82
  33. data/lib/vagrant-ssh-config-manager/action/reload.rb +0 -106
  34. data/lib/vagrant-ssh-config-manager/action/up.rb +0 -99
  35. data/lib/vagrant-ssh-config-manager/ssh_config_manager.rb +0 -2150
  36. data/lib/vagrant-ssh-config-manager/version.rb +0 -5
@@ -1,48 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module SshConfigManager
3
5
  class SshInfoExtractor
4
6
  def initialize(machine)
5
7
  @machine = machine
6
- @logger = Log4r::Logger.new("vagrant::plugins::ssh_config_manager::ssh_info_extractor")
8
+ @logger = Log4r::Logger.new('vagrant::plugins::ssh_config_manager::ssh_info_extractor')
7
9
  end
8
10
 
9
11
  # Extract SSH information from Vagrant's internal APIs
10
12
  # This replicates what 'vagrant ssh-config' does but using internal methods
11
13
  def extract_ssh_info
12
- begin
13
- ssh_info = @machine.ssh_info
14
- return nil if ssh_info.nil?
14
+ ssh_info = @machine.ssh_info
15
+ return nil if ssh_info.nil?
15
16
 
16
- # Additional validation for SSH info completeness
17
- return nil unless valid_ssh_info?(ssh_info)
17
+ # Additional validation for SSH info completeness
18
+ return nil unless valid_ssh_info?(ssh_info)
18
19
 
19
- # Get the SSH configuration similar to what vagrant ssh-config provides
20
- config = build_ssh_config(ssh_info)
21
-
22
- @logger.info("Extracted SSH info for machine: #{@machine.name}") if @logger
23
- config
24
- rescue Vagrant::Errors::SSHNotReady => e
25
- @logger.debug("SSH not ready for machine #{@machine.name}: #{e.message}") if @logger
26
- nil
27
- rescue Vagrant::Errors::SSHUnavailable => e
28
- @logger.debug("SSH unavailable for machine #{@machine.name}: #{e.message}") if @logger
29
- nil
30
- rescue => e
31
- @logger.warn("Failed to extract SSH info for machine #{@machine.name}: #{e.message}") if @logger
32
- nil
33
- end
20
+ # Get the SSH configuration similar to what vagrant ssh-config provides
21
+ config = build_ssh_config(ssh_info)
22
+
23
+ @logger&.info("Extracted SSH info for machine: #{@machine.name}")
24
+ config
25
+ rescue Vagrant::Errors::SSHNotReady => e
26
+ @logger&.debug("SSH not ready for machine #{@machine.name}: #{e.message}")
27
+ nil
28
+ rescue Vagrant::Errors::SSHUnavailable => e
29
+ @logger&.debug("SSH unavailable for machine #{@machine.name}: #{e.message}")
30
+ nil
31
+ rescue StandardError => e
32
+ @logger&.warn("Failed to extract SSH info for machine #{@machine.name}: #{e.message}")
33
+ nil
34
34
  end
35
35
 
36
36
  # Check if the machine supports SSH with comprehensive validation
37
37
  def ssh_capable?
38
38
  # Simplified check - if machine is running and has SSH info, assume SSH is available
39
- @machine &&
40
- @machine.state &&
41
- @machine.state.id == :running &&
42
- @machine.ssh_info &&
43
- ssh_communicator?
44
- rescue => e
45
- @logger.debug("SSH capability check failed: #{e.message}") if @logger
39
+ @machine&.state &&
40
+ @machine.state.id == :running &&
41
+ @machine.ssh_info &&
42
+ ssh_communicator?
43
+ rescue StandardError => e
44
+ @logger&.debug("SSH capability check failed: #{e.message}")
46
45
  false
47
46
  end
48
47
 
@@ -51,18 +50,18 @@ module VagrantPlugins
51
50
  # Basic checks
52
51
  return false unless @machine
53
52
  return false unless @machine.communicate_ready?
54
-
53
+
55
54
  # Check if machine state supports SSH
56
55
  return false unless machine_state_supports_ssh?
57
-
56
+
58
57
  # Check if communicator is SSH-based
59
58
  return false unless ssh_communicator?
60
-
59
+
61
60
  # Check if provider supports SSH
62
61
  return false unless provider_supports_ssh?
63
-
62
+
64
63
  true
65
- rescue => e
64
+ rescue StandardError => e
66
65
  @logger.debug("Machine SSH support check failed: #{e.message}")
67
66
  false
68
67
  end
@@ -73,11 +72,11 @@ module VagrantPlugins
73
72
  def machine_state_supports_ssh?
74
73
  state = @machine.state
75
74
  return false unless state
76
-
75
+
77
76
  # Common states that support SSH
78
- ssh_ready_states = [:running, :up, :active, :created]
77
+ ssh_ready_states = %i[running up active created]
79
78
  ssh_ready_states.include?(state.id)
80
- rescue
79
+ rescue StandardError
81
80
  false
82
81
  end
83
82
 
@@ -85,7 +84,7 @@ module VagrantPlugins
85
84
  def ssh_communicator?
86
85
  communicator = @machine.config.vm.communicator
87
86
  communicator.nil? || communicator == :ssh
88
- rescue
87
+ rescue StandardError
89
88
  # Default to assuming SSH if we can't determine
90
89
  true
91
90
  end
@@ -94,22 +93,22 @@ module VagrantPlugins
94
93
  def provider_supports_ssh?
95
94
  provider_name = @machine.provider_name
96
95
  return true unless provider_name
97
-
96
+
98
97
  # List of providers known to support SSH
99
- ssh_providers = [
100
- :virtualbox, :vmware_desktop, :vmware_fusion, :vmware_workstation,
101
- :libvirt, :kvm, :qemu, :parallels, :hyper_v, :lxc, :docker,
102
- :aws, :azure, :google, :digitalocean, :linode, :vultr
98
+ ssh_providers = %i[
99
+ virtualbox vmware_desktop vmware_fusion vmware_workstation
100
+ libvirt kvm qemu parallels hyper_v lxc docker
101
+ aws azure google digitalocean linode vultr
103
102
  ]
104
-
103
+
105
104
  # Providers known to NOT support SSH
106
105
  non_ssh_providers = [:winrm]
107
-
106
+
108
107
  return false if non_ssh_providers.include?(provider_name)
109
-
108
+
110
109
  # If it's a known SSH provider or unknown (assume SSH), return true
111
110
  ssh_providers.include?(provider_name) || !non_ssh_providers.include?(provider_name)
112
- rescue
111
+ rescue StandardError
113
112
  # Default to assuming SSH support if we can't determine
114
113
  true
115
114
  end
@@ -119,85 +118,58 @@ module VagrantPlugins
119
118
  return false if ssh_info.nil?
120
119
  return false if ssh_info[:host].nil? || ssh_info[:host].to_s.strip.empty?
121
120
  return false if ssh_info[:port].nil? || ssh_info[:port].to_i <= 0
122
-
121
+
123
122
  # Username is not strictly required (can default to 'vagrant')
124
123
  # but if present, it shouldn't be empty
125
- if ssh_info[:username]
126
- return false if ssh_info[:username].to_s.strip.empty?
127
- end
128
-
124
+ return false if ssh_info[:username] && ssh_info[:username].to_s.strip.empty?
125
+
129
126
  true
130
- rescue
127
+ rescue StandardError
131
128
  false
132
129
  end
133
130
 
134
131
  # Enhanced SSH info extraction with edge case handling
135
132
  def extract_ssh_info_safe
136
133
  return nil unless machine_supports_ssh?
137
-
134
+
138
135
  retries = 0
139
136
  max_retries = 3
140
137
  retry_delay = 1
141
-
138
+
142
139
  begin
143
140
  ssh_info = @machine.ssh_info
144
141
  return nil unless valid_ssh_info?(ssh_info)
145
-
142
+
146
143
  build_ssh_config(ssh_info)
147
144
  rescue Vagrant::Errors::SSHNotReady => e
148
145
  retries += 1
149
146
  if retries <= max_retries
150
147
  @logger.debug("SSH not ready, retrying in #{retry_delay}s (attempt #{retries}/#{max_retries})")
151
148
  sleep(retry_delay)
152
- retry_delay *= 2 # Exponential backoff
149
+ retry_delay *= 2 # Exponential backoff
153
150
  retry
154
151
  else
155
152
  @logger.debug("SSH still not ready after #{max_retries} attempts")
156
153
  nil
157
154
  end
158
- rescue => e
155
+ rescue StandardError => e
159
156
  @logger.warn("SSH info extraction failed: #{e.message}")
160
157
  nil
161
158
  end
162
159
  end
163
160
 
164
- # Safe host name generation with fallbacks
165
- def generate_host_name
166
- begin
167
- # Generate a unique host name based on project directory and machine name
168
- project_name = File.basename(@machine.env.root_path)
169
- machine_name = @machine.name.to_s
170
-
171
- # Sanitize names for SSH config
172
- project_name = sanitize_name(project_name)
173
- machine_name = sanitize_name(machine_name)
174
-
175
- host_name = "#{project_name}-#{machine_name}"
176
-
177
- # Ensure the host name is not empty after sanitization
178
- if host_name.strip.empty? || host_name == '-'
179
- host_name = "vagrant-#{@machine.id || 'unknown'}"
180
- end
181
-
182
- host_name
183
- rescue => e
184
- @logger.debug("Host name generation failed: #{e.message}")
185
- "vagrant-#{@machine.name || 'unknown'}"
186
- end
187
- end
188
-
189
161
  # Normalize SSH config data to ensure consistency
190
162
  def normalize_ssh_config(config)
191
163
  normalized = {}
192
-
164
+
193
165
  config.each do |key, value|
194
166
  # Normalize key names to proper SSH config format
195
167
  normalized_key = normalize_config_key(key)
196
168
  normalized_value = normalize_config_value(key, value)
197
-
169
+
198
170
  normalized[normalized_key] = normalized_value if normalized_value
199
171
  end
200
-
172
+
201
173
  normalized
202
174
  end
203
175
 
@@ -205,11 +177,11 @@ module VagrantPlugins
205
177
  def parse_ssh_config_entry(entry_text)
206
178
  config = {}
207
179
  current_host = nil
208
-
180
+
209
181
  entry_text.split("\n").each do |line|
210
182
  line = line.strip
211
183
  next if line.empty? || line.start_with?('#')
212
-
184
+
213
185
  if line.start_with?('Host ')
214
186
  current_host = line.sub(/^Host\s+/, '').strip
215
187
  config['Host'] = current_host
@@ -218,18 +190,18 @@ module VagrantPlugins
218
190
  config[key.strip] = value.strip
219
191
  end
220
192
  end
221
-
193
+
222
194
  config
223
195
  end
224
196
 
225
197
  # Convert normalized config back to SSH config file format
226
198
  def to_ssh_config_format(config)
227
199
  lines = []
228
-
200
+
229
201
  # Host entry always comes first
230
202
  if config['Host']
231
203
  lines << "Host #{config['Host']}"
232
-
204
+
233
205
  # Add other entries in a logical order
234
206
  ssh_option_order = %w[
235
207
  HostName User Port IdentityFile IdentitiesOnly
@@ -237,25 +209,22 @@ module VagrantPlugins
237
209
  LogLevel ProxyCommand Compression CompressionLevel
238
210
  ConnectTimeout ForwardAgent ForwardX11
239
211
  ]
240
-
212
+
241
213
  ssh_option_order.each do |key|
242
- if config[key]
243
- lines << " #{key} #{config[key]}"
244
- end
214
+ lines << " #{key} #{config[key]}" if config[key]
245
215
  end
246
-
216
+
247
217
  # Add any remaining options not in the predefined order
248
218
  config.each do |key, value|
249
219
  next if key == 'Host' || ssh_option_order.include?(key)
220
+
250
221
  lines << " #{key} #{value}"
251
222
  end
252
223
  end
253
-
224
+
254
225
  lines.join("\n")
255
226
  end
256
227
 
257
- private
258
-
259
228
  def build_ssh_config(ssh_info)
260
229
  config = {
261
230
  'Host' => generate_host_name,
@@ -267,23 +236,23 @@ module VagrantPlugins
267
236
  # Add SSH key information
268
237
  if ssh_info[:private_key_path] && !ssh_info[:private_key_path].empty?
269
238
  # Use the first private key if multiple are provided
270
- key_path = ssh_info[:private_key_path].is_a?(Array) ?
271
- ssh_info[:private_key_path].first :
272
- ssh_info[:private_key_path]
239
+ key_path = if ssh_info[:private_key_path].is_a?(Array)
240
+ ssh_info[:private_key_path].first
241
+ else
242
+ ssh_info[:private_key_path]
243
+ end
273
244
  config['IdentityFile'] = key_path
274
245
  config['IdentitiesOnly'] = 'yes'
275
246
  end
276
247
 
277
248
  # Add common SSH options for Vagrant VMs
278
249
  config['StrictHostKeyChecking'] = 'no'
279
- config['UserKnownHostsFile'] = '/dev/null'
250
+ config['UserKnownHostsFile'] = File::NULL
280
251
  config['PasswordAuthentication'] = 'no'
281
252
  config['LogLevel'] = 'FATAL'
282
253
 
283
254
  # Add proxy command if using a proxy
284
- if ssh_info[:proxy_command]
285
- config['ProxyCommand'] = ssh_info[:proxy_command]
286
- end
255
+ config['ProxyCommand'] = ssh_info[:proxy_command] if ssh_info[:proxy_command]
287
256
 
288
257
  # Add comprehensive SSH options from the machine config
289
258
  add_comprehensive_ssh_options(config, ssh_info)
@@ -294,69 +263,88 @@ module VagrantPlugins
294
263
 
295
264
  # Add comprehensive SSH options support
296
265
  def add_comprehensive_ssh_options(config, ssh_info)
297
- return unless ssh_info[:config] && ssh_info[:config].ssh
298
-
266
+ return unless ssh_info[:config]&.ssh
267
+
299
268
  ssh_config = ssh_info[:config].ssh
300
-
269
+
301
270
  # Connection options
302
- config['Compression'] = ssh_config.compression ? 'yes' : 'no' if ssh_config.compression != nil
271
+ config['Compression'] = ssh_config.compression ? 'yes' : 'no' unless ssh_config.compression.nil?
303
272
  config['CompressionLevel'] = ssh_config.compression_level.to_s if ssh_config.compression_level
304
273
  config['ConnectTimeout'] = ssh_config.connect_timeout.to_s if ssh_config.connect_timeout
305
274
  config['ConnectionAttempts'] = ssh_config.connection_attempts.to_s if ssh_config.connection_attempts
306
275
  config['ServerAliveInterval'] = ssh_config.server_alive_interval.to_s if ssh_config.server_alive_interval
307
276
  config['ServerAliveCountMax'] = ssh_config.server_alive_count_max.to_s if ssh_config.server_alive_count_max
308
-
277
+
309
278
  # Authentication options
310
- config['ForwardAgent'] = ssh_config.forward_agent ? 'yes' : 'no' if ssh_config.forward_agent != nil
311
- config['PubkeyAuthentication'] = ssh_config.pubkey_authentication ? 'yes' : 'no' if ssh_config.pubkey_authentication != nil
312
- config['PreferredAuthentications'] = ssh_config.preferred_authentications if ssh_config.preferred_authentications
313
-
279
+ config['ForwardAgent'] = ssh_config.forward_agent ? 'yes' : 'no' unless ssh_config.forward_agent.nil?
280
+ unless ssh_config.pubkey_authentication.nil?
281
+ config['PubkeyAuthentication'] =
282
+ ssh_config.pubkey_authentication ? 'yes' : 'no'
283
+ end
284
+ if ssh_config.preferred_authentications
285
+ config['PreferredAuthentications'] =
286
+ ssh_config.preferred_authentications
287
+ end
288
+
314
289
  # Forwarding options
315
- config['ForwardX11'] = ssh_config.forward_x11 ? 'yes' : 'no' if ssh_config.forward_x11 != nil
316
- config['ForwardX11Trusted'] = ssh_config.forward_x11_trusted ? 'yes' : 'no' if ssh_config.forward_x11_trusted != nil
317
-
290
+ config['ForwardX11'] = ssh_config.forward_x11 ? 'yes' : 'no' unless ssh_config.forward_x11.nil?
291
+ unless ssh_config.forward_x11_trusted.nil?
292
+ config['ForwardX11Trusted'] =
293
+ ssh_config.forward_x11_trusted ? 'yes' : 'no'
294
+ end
295
+
318
296
  # Security options
319
- config['StrictHostKeyChecking'] = ssh_config.verify_host_key ? 'yes' : 'no' if ssh_config.verify_host_key != nil
320
- config['CheckHostIP'] = ssh_config.check_host_ip ? 'yes' : 'no' if ssh_config.check_host_ip != nil
321
-
297
+ unless ssh_config.verify_host_key.nil?
298
+ config['StrictHostKeyChecking'] =
299
+ ssh_config.verify_host_key ? 'yes' : 'no'
300
+ end
301
+ config['CheckHostIP'] = ssh_config.check_host_ip ? 'yes' : 'no' unless ssh_config.check_host_ip.nil?
302
+
322
303
  # Protocol options
323
304
  config['Protocol'] = ssh_config.protocol if ssh_config.protocol
324
305
  config['Ciphers'] = ssh_config.ciphers.join(',') if ssh_config.ciphers && !ssh_config.ciphers.empty?
325
306
  config['MACs'] = ssh_config.macs.join(',') if ssh_config.macs && !ssh_config.macs.empty?
326
- config['KexAlgorithms'] = ssh_config.kex_algorithms.join(',') if ssh_config.kex_algorithms && !ssh_config.kex_algorithms.empty?
327
-
307
+ if ssh_config.kex_algorithms && !ssh_config.kex_algorithms.empty?
308
+ config['KexAlgorithms'] =
309
+ ssh_config.kex_algorithms.join(',')
310
+ end
311
+
328
312
  # Terminal options
329
- config['RequestTTY'] = ssh_config.pty ? 'yes' : 'no' if ssh_config.pty != nil
313
+ config['RequestTTY'] = ssh_config.pty ? 'yes' : 'no' unless ssh_config.pty.nil?
330
314
  config['RemoteCommand'] = ssh_config.remote_command if ssh_config.remote_command
331
-
315
+
332
316
  # File and directory options
333
317
  config['ControlMaster'] = ssh_config.control_master if ssh_config.control_master
334
318
  config['ControlPath'] = ssh_config.control_path if ssh_config.control_path
335
319
  config['ControlPersist'] = ssh_config.control_persist.to_s if ssh_config.control_persist
336
-
320
+
337
321
  # Logging options
338
322
  config['LogLevel'] = ssh_config.log_level.to_s.upcase if ssh_config.log_level
339
323
  config['SyslogFacility'] = ssh_config.syslog_facility if ssh_config.syslog_facility
340
-
324
+
341
325
  # Banner and environment
342
326
  config['Banner'] = ssh_config.banner if ssh_config.banner
343
327
  config['SendEnv'] = ssh_config.send_env.join(' ') if ssh_config.send_env && !ssh_config.send_env.empty?
344
- config['SetEnv'] = ssh_config.set_env.map { |k, v| "#{k}=#{v}" }.join(' ') if ssh_config.set_env && !ssh_config.set_env.empty?
345
-
328
+ if ssh_config.set_env && !ssh_config.set_env.empty?
329
+ config['SetEnv'] = ssh_config.set_env.map do |k, v|
330
+ "#{k}=#{v}"
331
+ end.join(' ')
332
+ end
333
+
346
334
  # Keep alive options
347
- config['TCPKeepAlive'] = ssh_config.tcp_keep_alive ? 'yes' : 'no' if ssh_config.tcp_keep_alive != nil
348
-
335
+ config['TCPKeepAlive'] = ssh_config.tcp_keep_alive ? 'yes' : 'no' unless ssh_config.tcp_keep_alive.nil?
336
+
349
337
  # Escape character
350
338
  config['EscapeChar'] = ssh_config.escape_char if ssh_config.escape_char
351
-
339
+
352
340
  # Gateway options
353
341
  config['ProxyJump'] = ssh_config.proxy_jump if ssh_config.proxy_jump
354
-
342
+
355
343
  # Add any custom options that might be defined
356
- if ssh_config.respond_to?(:extra_options) && ssh_config.extra_options
357
- ssh_config.extra_options.each do |key, value|
358
- config[key.to_s] = value.to_s
359
- end
344
+ return unless ssh_config.respond_to?(:extra_options) && ssh_config.extra_options
345
+
346
+ ssh_config.extra_options.each do |key, value|
347
+ config[key.to_s] = value.to_s
360
348
  end
361
349
  end
362
350
 
@@ -364,11 +352,11 @@ module VagrantPlugins
364
352
  # Generate a unique host name based on project directory and machine name
365
353
  project_name = File.basename(@machine.env.root_path)
366
354
  machine_name = @machine.name.to_s
367
-
355
+
368
356
  # Sanitize names for SSH config
369
357
  project_name = sanitize_name(project_name)
370
358
  machine_name = sanitize_name(machine_name)
371
-
359
+
372
360
  "#{project_name}-#{machine_name}"
373
361
  end
374
362
 
@@ -409,18 +397,18 @@ module VagrantPlugins
409
397
  'forward_x11' => 'ForwardX11',
410
398
  'forwardx11' => 'ForwardX11'
411
399
  }
412
-
400
+
413
401
  key_str = key.to_s.downcase
414
402
  key_mappings[key_str] || key.to_s
415
403
  end
416
404
 
417
405
  def normalize_config_value(key, value)
418
406
  return nil if value.nil? || value.to_s.strip.empty?
419
-
407
+
420
408
  case key.to_s.downcase
421
409
  when 'port'
422
410
  value.to_i.to_s
423
- when 'compression', 'identitiesonly', 'stricthostkeychecking',
411
+ when 'compression', 'identitiesonly', 'stricthostkeychecking',
424
412
  'passwordauthentication', 'forwardagent', 'forwardx11'
425
413
  # Normalize boolean-like values
426
414
  case value.to_s.downcase
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module SshConfigManager
5
+ VERSION = '1.0.0.alpha'
6
+ end
7
+ end
@@ -1,30 +1,33 @@
1
- require "vagrant-ssh-config-manager/version"
2
- require "vagrant-ssh-config-manager/plugin"
1
+ # frozen_string_literal: true
3
2
 
3
+ require 'vagrant_ssh_config_manager/version'
4
+ require 'vagrant_ssh_config_manager/plugin'
5
+
6
+ # Main entrypoint module for SSH Config Manager plugin
4
7
  module VagrantPlugins
5
8
  module SshConfigManager
6
9
  # Main plugin entry point
7
10
  # This file is loaded when the plugin is activated
8
-
11
+
9
12
  # Lazy load other components only when needed
10
13
  def self.require_file_manager
11
- require "vagrant-ssh-config-manager/file_manager" unless defined?(FileManager)
14
+ require 'vagrant_ssh_config_manager/file_manager' unless defined?(FileManager)
12
15
  end
13
-
16
+
14
17
  def self.require_include_manager
15
- require "vagrant-ssh-config-manager/include_manager" unless defined?(IncludeManager)
18
+ require 'vagrant_ssh_config_manager/include_manager' unless defined?(IncludeManager)
16
19
  end
17
-
20
+
18
21
  def self.require_ssh_info_extractor
19
- require "vagrant-ssh-config-manager/ssh_info_extractor" unless defined?(SshInfoExtractor)
22
+ require 'vagrant_ssh_config_manager/ssh_info_extractor' unless defined?(SshInfoExtractor)
20
23
  end
21
-
24
+
22
25
  def self.require_file_locker
23
- require "vagrant-ssh-config-manager/file_locker" unless defined?(FileLocker)
26
+ require 'vagrant_ssh_config_manager/file_locker' unless defined?(FileLocker)
24
27
  end
25
-
28
+
26
29
  def self.require_config
27
- require "vagrant-ssh-config-manager/config" unless defined?(Config)
30
+ require 'vagrant_ssh_config_manager/config' unless defined?(Config)
28
31
  end
29
32
  end
30
33
  end
data/test-all.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+ # Run all tests
3
+ echo "🎯 Running Whole Test Suite..."
4
+ echo ""
5
+ echo "📦 Unit Tests (Fast, Mocked):"
6
+ bundle exec rspec spec/unit/ --format progress
7
+ echo ""
8
+ echo "🔗 Integration Tests (Real APIs):"
9
+ bundle exec rspec spec/integration/ --format progress
10
+ echo ""
11
+ echo "✅ Testing complete!"
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ # Run integration tests only (real APIs)
3
+ echo "🔧 Running Integration Tests..."
4
+ bundle exec rspec spec/integration/ --format documentation
data/test-unit.sh ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ # Run unit tests only (fast, isolated)
3
+ echo "🚀 Running Unit Tests..."
4
+ bundle exec rspec spec/unit/ --format documentation
@@ -1,39 +1,43 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "vagrant-ssh-config-manager/version"
5
+ require 'vagrant_ssh_config_manager/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "vagrant-ssh-config-manager"
8
+ spec.name = 'vagrant-ssh-config-manager'
7
9
  spec.version = VagrantPlugins::SshConfigManager::VERSION
8
- spec.authors = ["Marek Ruzicka"]
9
- spec.email = ["marek.ruzicka@glide.sk"]
10
+ spec.authors = ['Marek Ruzicka']
11
+ spec.email = ['marek.ruzicka@glide.sk']
10
12
 
11
- spec.summary = "Vagrant plugin that automatically manages SSH configurations"
12
- spec.description = "A Vagrant plugin that automatically manages SSH configurations. Creates and maintains SSH config entries when VMs are started and cleans them up when VMs are destroyed, with environment isolation and file locking support."
13
- spec.homepage = "https://github.com/marekruzicka/vagrant-ssh-config-manager"
14
- spec.license = "MIT"
13
+ spec.summary = 'Vagrant plugin that automatically manages SSH configurations'
14
+ spec.description = 'A Vagrant plugin that automatically manages SSH configurations. Creates and maintains SSH config entries when VMs are started and cleans them up when VMs are destroyed, with environment isolation and file locking support.'
15
+ spec.homepage = 'https://github.com/marekruzicka/vagrant-ssh-config-manager'
16
+ spec.license = 'MIT'
15
17
 
16
- spec.metadata["documentation_uri"] = "https://rubydoc.info/github/marekruzicka/vagrant-ssh-config-manager/main"
17
- spec.metadata["source_code_uri"] = "https://github.com/marekruzicka/vagrant-ssh-config-manager"
18
- spec.metadata["changelog_uri"] = "https://github.com/marekruzicka/vagrant-ssh-config-manager/blob/main/CHANGELOG.md"
18
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/github/marekruzicka/vagrant-ssh-config-manager/main'
19
+ spec.metadata['source_code_uri'] = 'https://github.com/marekruzicka/vagrant-ssh-config-manager'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/marekruzicka/vagrant-ssh-config-manager/blob/main/CHANGELOG.md'
19
21
 
20
22
  # Specify which files should be added to the gem when it is released.
21
23
  # The `git ls-files -z` loads the files in the RubyGems gemspec, but not Git submodules.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|tasks|.github|.ai)/}) }
24
26
  end
25
- spec.require_paths = ["lib"]
27
+ # Include the direct entrypoint under vagrant/ssh/config in case it's not tracked
28
+ spec.files << 'lib/vagrant/ssh/config/manager.rb'
29
+ spec.require_paths = ['lib']
26
30
 
27
31
  # Development dependencies
28
- spec.add_development_dependency "bundler", "~> 2.0"
29
- spec.add_development_dependency "rake", "~> 13.0"
30
- spec.add_development_dependency "rspec", "~> 3.0"
31
- spec.add_development_dependency "rspec-mocks", "~> 3.0"
32
- spec.add_development_dependency "simplecov", "~> 0.21"
32
+ spec.add_development_dependency 'bundler', '~> 2.0'
33
+ spec.add_development_dependency 'rake', '~> 13.0'
34
+ spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'rspec-mocks', '~> 3.0'
36
+ spec.add_development_dependency 'simplecov', '~> 0.21'
33
37
 
34
38
  # Ensure compatibility with supported Ruby versions
35
- spec.required_ruby_version = ">= 2.6.0"
39
+ spec.required_ruby_version = '>= 3.0.0'
36
40
 
37
41
  # Plugin metadata for Vagrant
38
- spec.metadata["vagrant_plugin"] = "true"
42
+ spec.metadata['vagrant_plugin'] = 'true'
39
43
  end