ssh_key_switcher 1.0.2 → 1.0.4

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: 5c4e430fedd3b88c306adc11aed32f2c3f6cbbf13599fc5a71c9b27d43c913e7
4
- data.tar.gz: 866ea4963674b4266afa0686f642ff52d564d27b9067d24fa52db0922d7702ff
3
+ metadata.gz: 0cb5737abcac6c9d84606bf41e6ee5b0574adb81c06f759082002a605e1510f5
4
+ data.tar.gz: 904c1781a5ea8c727a7aaa4185957ba9987fb90709059b940ce32c3a01214f10
5
5
  SHA512:
6
- metadata.gz: 289a5cb9d9e21b2566ff6b302fc6a8f204cee42879e162d52dcff799089ac864277ef763ac7eea6ee7f433a41d5205ab3485655b26878d5627513b631daeb2d0
7
- data.tar.gz: 9802b57d0a61019a169bfd98719cb596c96a60f8607197c1a97aa56b6a60937516cd000d31d39d9d97499d31a866481e44b82eee363f3b7f9c48981a1f741149
6
+ metadata.gz: 6f0ea37d20e460b051bf425db54ccc1eea1a02502ab7a150b8608a16a8c2f2de35ee33e6af6a0e3fc039604d4915a9d3b587735d0d8f1a534b8b4bc82c408e60
7
+ data.tar.gz: 7c658daae267a438027c3ed4c438b0e72b226830152e1edebfc864529e1ad9a1a5280581573687178081f1c2784f43c6bbbdfd5d16d3f05316ec7bbdbad4e275
data/bin/sks CHANGED
@@ -2,6 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'ssh_key_switcher'
5
- require_relative '../lib/ssh_key_switcher'
6
5
 
7
- SshKeySwitcher::CLI.start
6
+ # Prevent failures from being reported twice.
7
+ Thread.report_on_exception = false
8
+
9
+ begin
10
+ SshKeySwitcher::CLI.start(ARGV)
11
+ rescue StandardError => e
12
+ puts " \e[31mERROR (#{e.class}): #{e.message}\e[0m"
13
+ exit 1
14
+ end
@@ -5,24 +5,11 @@ module SshKeySwitcher
5
5
  class CurrentAgent
6
6
  class << self
7
7
  def fetch_results
8
- results = []
9
- payload = Cmd.exec('ssh-add -l')[0]
10
- payload.each_line { |line| results << line.split[-2..].join(' ') }
11
- results
8
+ Helper.current_active_keys
12
9
  end
13
10
 
14
11
  def display
15
- if fetch_results[0].include?('no identities')
16
- prompt.warn('No active SSH keys')
17
- elsif fetch_results.size == 1
18
- prompt.say('Active SSH key: ')
19
- prompt.ok(fetch_results[0])
20
- else
21
- prompt.say('List of active SSH keys:')
22
- fetch_results.each.with_index(1) do |result, index|
23
- prompt.ok(" #{index}) #{result}")
24
- end
25
- end
12
+ Helper.display_current_ssh_keys(prompt)
26
13
  end
27
14
 
28
15
  private
@@ -5,9 +5,9 @@ module SshKeySwitcher
5
5
  class Delete
6
6
  class << self
7
7
  def display_select
8
- keys = Helper.find_open_ssh_keys
9
- if keys.empty?
10
- prompt.error('No OpenSSH keys found in ~/.ssh')
8
+ files = Helper.find_ssh_keys
9
+ if files.empty?
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
11
  nil
12
12
  else
13
13
  msg = 'Choose the OpenSSH keys to REMOVE. Press [CTRL+C] to exit.'
@@ -55,7 +55,7 @@ module SshKeySwitcher
55
55
 
56
56
  def select_choices(menu, keys)
57
57
  keys.each do |value|
58
- display_text = value.split('/')[-2..].join('/').gsub('.ssh/', '')
58
+ display_text = value.split('/').last(2).join('/').gsub('.ssh/', '')
59
59
  menu.choice display_text, value
60
60
  end
61
61
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SshKeySwitcher
4
+ module Options
5
+ class List
6
+ class << self
7
+ def display
8
+ ssh_keys = Helper.find_ssh_keys
9
+ if ssh_keys.empty?
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
+ nil
12
+ else
13
+ prompt.say('List of OpenSSH keys:')
14
+ Helper.display_list_keys(prompt, ssh_keys, color: :blue)
15
+ end
16
+
17
+ print "\n"
18
+ Helper.display_current_ssh_keys(prompt)
19
+ end
20
+
21
+ private
22
+
23
+ include SshKeySwitcher::Contains
24
+ include SshKeySwitcher::Utils
25
+
26
+ def prompt
27
+ @prompt ||= TTY::Prompt.new(interrupt: :exit)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,7 +5,7 @@ module SshKeySwitcher
5
5
  class Remove
6
6
  class << self
7
7
  def display_select
8
- keys = Helper.find_open_ssh_keys
8
+ keys = Helper.find_ssh_keys
9
9
  if keys.empty?
10
10
  prompt.error('No OpenSSH keys found in ~/.ssh')
11
11
  nil
@@ -56,7 +56,7 @@ module SshKeySwitcher
56
56
 
57
57
  def select_choices(menu, keys)
58
58
  keys.each do |value|
59
- display_text = value.split('/')[-2..].join('/').gsub('.ssh/', '')
59
+ display_text = value.split('/').last(2).join('/').gsub('.ssh/', '')
60
60
  menu.choice display_text, value
61
61
  end
62
62
  end
@@ -5,20 +5,21 @@ module SshKeySwitcher
5
5
  class Select
6
6
  class << self
7
7
  def display_select
8
- ssh_keys = Helper.find_open_ssh_keys
8
+ ssh_keys = Helper.find_ssh_keys
9
9
  if ssh_keys.empty?
10
- prompt.error('No OpenSSH keys found in ~/.ssh')
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
11
  nil
12
12
  else
13
13
  prompt.select('Select an OpenSSH key:', select_options) do |menu|
14
14
  menu.enum '.'
15
15
  select_choices(menu, ssh_keys)
16
16
  end
17
-
18
17
  end
19
18
  end
20
19
 
21
20
  def add(path_open_ssh_key)
21
+ return if path_open_ssh_key.nil?
22
+
22
23
  SshKeySwitcher::Utils::SshAgent.remove_all
23
24
  SshKeySwitcher::Utils::SshAgent.add(path_open_ssh_key)
24
25
  prompt.ok('OpenSSH key added successfully!')
@@ -44,10 +45,10 @@ module SshKeySwitcher
44
45
  }
45
46
  end
46
47
 
47
- def select_choices(menu, keys)
48
- keys.each do |value|
49
- display_text = value.split('/')[-2..].join('/').gsub('.ssh/', '')
50
- menu.choice display_text, value
48
+ def select_choices(menu, ssh_keys)
49
+ ssh_keys.each do |key|
50
+ display_text = Helper.filename(key)
51
+ menu.choice display_text, key
51
52
  end
52
53
  end
53
54
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module SshKeySwitcher
4
4
  module Contains
5
- SSH_DIR = '~/.ssh'
5
+ SSH_DIR = "#{Dir.home}/.ssh"
6
6
  STRING_DETECT_OPENSSH_KEY = 'OPENSSH'
7
7
  SERVER_NAMES = %w[github.com gitlab.com bitbucket.org].freeze
8
8
  end
@@ -7,20 +7,61 @@ module SshKeySwitcher
7
7
 
8
8
  module_function
9
9
 
10
- def find_open_ssh_keys
11
- ssh_folder = File.expand_path(SSH_DIR)
10
+ def find_ssh_keys
11
+ files = fetch_private_ssh_keys_via_header
12
+ files += fetch_private_ssh_keys_via_filename
13
+ files.flatten.uniq.sort
14
+ end
15
+
16
+ def fetch_private_ssh_keys_via_header
17
+ ssh_dir = File.expand_path(SSH_DIR)
18
+ files = Dir.glob("#{ssh_dir}/**/*").select do |file|
19
+ next if File.directory?(file)
20
+
21
+ File.open(file, 'rb') do |f|
22
+ # Read the first 20 bytes from the file
23
+ header = f.read(20)
24
+ header.include?(STRING_DETECT_OPENSSH_KEY)
25
+ end
26
+ end
27
+ end
28
+
29
+ def fetch_private_ssh_keys_via_filename
30
+ ssh_dir = File.expand_path(SSH_DIR)
31
+ Dir.glob("#{ssh_dir}/**/*.pub").map { |file| file.gsub('.pub', '') }
32
+ end
12
33
 
13
- Dir.glob("#{ssh_folder}/*").select { |file| valid_ssh_key?(file) }.sort
34
+ def filename(key)
35
+ key.gsub("#{SSH_DIR}/", '').gsub('.pub', '').strip
36
+ end
37
+
38
+ def current_active_keys
39
+ results = []
40
+ payload = Cmd.exec('ssh-add -l')[0]
41
+ payload.each_line { |line| results << line.split.last(2).join(' ') }
42
+ results
43
+ end
44
+
45
+ def display_current_ssh_keys(prompt, color: :green)
46
+ ssh_keys = Helper.current_active_keys
47
+
48
+ if ssh_keys[0].include?('no identities')
49
+ prompt.warn('No active SSH keys')
50
+ elsif ssh_keys.size == 1
51
+ prompt.say("Active SSH key: #{ssh_keys[0]}", color: color)
52
+ else
53
+ prompt.say('List of active SSH keys:')
54
+ Helper.display_list_keys(prompt, ssh_keys, color: color)
55
+ end
14
56
  end
15
57
 
16
- def valid_ssh_key?(file)
17
- File.open(file, 'rb') do |f|
18
- # Read the first 20 bytes from the file
19
- header = f.read(20)
20
- header.include?(STRING_DETECT_OPENSSH_KEY)
58
+ def display_list_keys(prompt, ssh_keys, color: :blue)
59
+ max_space_size = ssh_keys.size.to_s.size
60
+ ssh_keys.each.with_index(1) do |key, idx|
61
+ space_size = max_space_size - (idx < 10 ? 0 : idx.to_s.size - 1)
62
+ filename = Helper.filename(key)
63
+ prompt.say(format(" %d.%#{space_size}s%s", idx, ' ', filename), color: color)
21
64
  end
22
- rescue StandardError
23
- false
24
65
  end
25
66
  end
26
67
  end
@@ -3,8 +3,8 @@
3
3
  module SshKeySwitcher
4
4
  module Utils
5
5
  class SshAgent
6
- def self.add(key)
7
- Cmd.exec("ssh-add #{key}")
6
+ def self.add(private_key)
7
+ Cmd.exec("ssh-add #{private_key}")
8
8
  end
9
9
 
10
10
  def self.remove_all
@@ -1,3 +1,3 @@
1
1
  module SshKeySwitcher
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -10,6 +10,8 @@ module SshKeySwitcher
10
10
  class Error < StandardError; end
11
11
 
12
12
  class CLI < Thor
13
+ ENV['THOR_SILENCE_DEPRECATION'] = 'true'
14
+
13
15
  desc 'version [-v, --version]', 'Show version'
14
16
  map %w[-v --version] => :version
15
17
  def version
@@ -29,6 +31,12 @@ module SshKeySwitcher
29
31
  SshKeySwitcher::Options::Select.add(path_open_ssh_key)
30
32
  end
31
33
 
34
+ desc 'list [-l, --list]', 'List of OpenSSH key files'
35
+ map %w[-l --list] => :list
36
+ def list
37
+ SshKeySwitcher::Options::List.display
38
+ end
39
+
32
40
  desc 'current [-c, --current]', 'List of active OpenSSH keys'
33
41
  map %w[-c --current] => :current
34
42
  def current
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssh_key_switcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minh Tang Q.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-04 00:00:00.000000000 Z
11
+ date: 2023-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -16,30 +16,29 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3.0
19
+ version: 1.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3.0
26
+ version: 1.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: tty-prompt
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.23.1
33
+ version: 0.23.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.23.1
41
- description: Simple and efficient for managing and switching between OpenSSH keys
42
- seamlessly
40
+ version: 0.23.0
41
+ description:
43
42
  email:
44
43
  - minh.tang1@tomosia.com
45
44
  - vhquocminhit@gmail.com
@@ -53,6 +52,7 @@ files:
53
52
  - lib/ssh_key_switcher.rb
54
53
  - lib/ssh_key_switcher/options/current_agent.rb
55
54
  - lib/ssh_key_switcher/options/delete.rb
55
+ - lib/ssh_key_switcher/options/list.rb
56
56
  - lib/ssh_key_switcher/options/ping.rb
57
57
  - lib/ssh_key_switcher/options/remove.rb
58
58
  - lib/ssh_key_switcher/options/select.rb
@@ -77,15 +77,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: 2.6.0
80
+ version: 2.5.0
81
81
  required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  requirements:
83
83
  - - ">="
84
84
  - !ruby/object:Gem::Version
85
85
  version: '0'
86
86
  requirements: []
87
- rubygems_version: 3.3.20
87
+ rubygems_version: 3.1.4
88
88
  signing_key:
89
89
  specification_version: 4
90
- summary: Simple and efficient for managing and switching between OpenSSH keys seamlessly
90
+ summary: A simple and efficient for managing and switching between OpenSSH keys seamlessly
91
91
  test_files: []