# File lib/netrc.rb, line 5 def self.default_path if WINDOWS File.join(ENV['USERPROFILE'].gsub("\\","/"), "_netrc") else File.join(ENV["HOME"], ".netrc") end end
# File lib/netrc.rb, line 25 def self.lex(lines) tokens = [] for line in lines content, comment = line.split(%r(\s*#.*)/) content.each_char do |char| case char when %r\s/ if tokens.last && tokens.last[-1..-1] =~ %r\s/ tokens.last << char else tokens << char end else if tokens.last && tokens.last[-1..-1] =~ %r\S/ tokens.last << char else tokens << char end end end if comment tokens << comment end end tokens end
# File lib/netrc.rb, line 101 def initialize(path, data) @new_item_prefix = '' @path = path @pre, @data = data end
Returns two values, a header and a list of items. Each item is a 7-tuple, containing:
machine keyword (including trailing whitespace+comments)
machine name
login keyword (including surrounding whitespace+comments)
login
password keyword (including surrounding whitespace+comments)
password
trailing chars
This lets us change individual fields, then write out the file with all its original formatting.
# File lib/netrc.rb, line 67 def self.parse(ts) cur, item = [], [] def ts.take if count < 1 raise Error, "unexpected EOF" end shift end def ts.readto l = [] while count > 0 && ! yield(self[0]) l << shift end return l.join end pre = ts.readto{|t| t == "machine"} while ts.count > 0 cur << ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take cur << ts.readto{|t| t == "login"} + ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take cur << ts.readto{|t| t == "password"} + ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take cur << ts.readto{|t| t == "machine"} item << cur cur = [] end [pre, item] end
Reads path and parses it as a .netrc file. If path doesn't exist, returns an empty object.
# File lib/netrc.rb, line 15 def self.read(path=default_path) perm = File.stat(path).mode & 0777 if perm != 0600 && !(WINDOWS) raise Error, "Permission bits for '#{path}' should be 0600, but are "+perm.to_s(8) end new(path, parse(lex(File.readlines(path)))) rescue Errno::ENOENT new(path, parse(lex([]))) end
# File lib/netrc.rb, line 52 def self.skip?(s) s =~ %r^\s/ end
# File lib/netrc.rb, line 109 def [](k) if item = @data.detect {|datum| datum[1] == k} [item[3], item[5]] end end
# File lib/netrc.rb, line 115 def []=(k, info) if item = @data.detect {|datum| datum[1] == k} item[3], item[5] = info else @data << new_item(k, info[0], info[1]) end end
# File lib/netrc.rb, line 123 def count @data.count end
# File lib/netrc.rb, line 127 def delete(key) datum = nil for value in @data if value[1] == key datum = value break end end @data.delete(datum) end
# File lib/netrc.rb, line 138 def each(&block) @data.each(&block) end
# File lib/netrc.rb, line 142 def new_item(m, l, p) [new_item_prefix+"machine ", m, "\n login ", l, "\n password ", p, "\n"] end
# File lib/netrc.rb, line 146 def save File.open(@path, 'w', 0600) {|file| file.print(unparse)} end
# File lib/netrc.rb, line 150 def unparse @pre + @data.map(&:join).join end