Skip to content

Commit

Permalink
extract SshConfig to a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
mislav committed Apr 17, 2012
1 parent 0a0757f commit 244495f
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 88 deletions.
1 change: 1 addition & 0 deletions lib/hub.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'hub/version'
require 'hub/args'
require 'hub/context'
require 'hub/ssh_config'
require 'hub/json'
require 'hub/commands'
require 'hub/runner'
86 changes: 0 additions & 86 deletions lib/hub/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -513,91 +513,5 @@ def which(cmd)
def command?(name)
!which(name).nil?
end

class SshConfig
CONFIG_FILES = %w(~/.ssh/config /etc/ssh_config /etc/ssh/ssh_config)

def initialize files = nil
@settings = Hash.new {|h,k| h[k] = {} }
Array(files || CONFIG_FILES).each do |path|
file = File.expand_path path
parse_file file if File.exist? file
end
end

# yields if not found
def get_value hostname, key
key = key.to_s.downcase
@settings.each do |pattern, settings|
if pattern.match? hostname and found = settings[key]
return found
end
end
yield
end

class HostPattern
def initialize pattern
@pattern = pattern.to_s.downcase
end

def to_s() @pattern end
def ==(other) other.to_s == self.to_s end

def matcher
@matcher ||=
if '*' == @pattern
Proc.new { true }
elsif @pattern !~ /[?*]/
lambda { |hostname| hostname.to_s.downcase == @pattern }
else
re = self.class.pattern_to_regexp @pattern
lambda { |hostname| re =~ hostname }
end
end

def match? hostname
matcher.call hostname
end

def self.pattern_to_regexp pattern
escaped = Regexp.escape(pattern)
escaped.gsub!('\*', '.*')
escaped.gsub!('\?', '.')
/^#{escaped}$/i
end
end

def parse_file file
host_patterns = [HostPattern.new('*')]

IO.foreach(file) do |line|
case line
when /^\s*(#|$)/ then next
when /^\s*(\S+)\s*=/
key, value = $1, $'
else
key, value = line.strip.split(/\s+/, 2)
end

next if value.nil?
key.downcase!
value = $1 if value =~ /^"(.*)"$/
value.chomp!

if 'host' == key
host_patterns = value.split(/\s+/).map {|p| HostPattern.new p }
else
record_setting key, value, host_patterns
end
end
end

def record_setting key, value, patterns
patterns.each do |pattern|
@settings[pattern][key] ||= value
end
end
end
end
end
91 changes: 91 additions & 0 deletions lib/hub/ssh_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
module Hub
# Reads ssh configuration files and records each setting under its host
# pattern so it can be looked up by hostname.
class SshConfig
CONFIG_FILES = %w(~/.ssh/config /etc/ssh_config /etc/ssh/ssh_config)

def initialize files = nil
@settings = Hash.new {|h,k| h[k] = {} }
Array(files || CONFIG_FILES).each do |path|
file = File.expand_path path
parse_file file if File.exist? file
end
end

# Public: Get a setting as it would apply to a specific hostname.
#
# Yields if not found.
def get_value hostname, key
key = key.to_s.downcase
@settings.each do |pattern, settings|
if pattern.match? hostname and found = settings[key]
return found
end
end
yield
end

class HostPattern
def initialize pattern
@pattern = pattern.to_s.downcase
end

def to_s() @pattern end
def ==(other) other.to_s == self.to_s end

def matcher
@matcher ||=
if '*' == @pattern
Proc.new { true }
elsif @pattern !~ /[?*]/
lambda { |hostname| hostname.to_s.downcase == @pattern }
else
re = self.class.pattern_to_regexp @pattern
lambda { |hostname| re =~ hostname }
end
end

def match? hostname
matcher.call hostname
end

def self.pattern_to_regexp pattern
escaped = Regexp.escape(pattern)
escaped.gsub!('\*', '.*')
escaped.gsub!('\?', '.')
/^#{escaped}$/i
end
end

def parse_file file
host_patterns = [HostPattern.new('*')]

IO.foreach(file) do |line|
case line
when /^\s*(#|$)/ then next
when /^\s*(\S+)\s*=/
key, value = $1, $'
else
key, value = line.strip.split(/\s+/, 2)
end

next if value.nil?
key.downcase!
value = $1 if value =~ /^"(.*)"$/
value.chomp!

if 'host' == key
host_patterns = value.split(/\s+/).map {|p| HostPattern.new p }
else
record_setting key, value, host_patterns
end
end
end

def record_setting key, value, patterns
patterns.each do |pattern|
@settings[pattern][key] ||= value
end
end
end
end
4 changes: 2 additions & 2 deletions test/hub_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def setup
super
COMMANDS.replace %w[open groff]
Hub::Context::PWD.replace '/path/to/hub'
Hub::Context::SshConfig::CONFIG_FILES.replace []
Hub::SshConfig::CONFIG_FILES.replace []

@git_reader = Hub::Context::GitReader.new 'git' do |cache, cmd|
unless cmd.index('config --get alias.') == 0
Expand Down Expand Up @@ -1444,7 +1444,7 @@ def improved_help_text

def with_ssh_config
config_file = File.expand_path '../ssh_config', __FILE__
Hub::Context::SshConfig::CONFIG_FILES.replace [config_file]
Hub::SshConfig::CONFIG_FILES.replace [config_file]
yield
end

Expand Down

0 comments on commit 244495f

Please sign in to comment.