Skip to content

Commit

Permalink
a Hosts class can now write changes to hosts file
Browse files Browse the repository at this point in the history
  • Loading branch information
jerodsanto committed Jan 13, 2009
1 parent cb32d51 commit c5c98bf
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 67 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1 +1,2 @@
.DS_Store
test/hosts
5 changes: 0 additions & 5 deletions hosts

This file was deleted.

73 changes: 43 additions & 30 deletions lib/hoster/hosts.rb
@@ -1,53 +1,62 @@
class Hosts

attr_reader :entries

def initialize(hosts_path = "/etc/hosts")
@hosts_file = File.new(hosts_path,"r+")
@entries = extract_entries(hosts_path)
@hosts_path = hosts_path
@entries = extract_entries
end
def raw_data
@hosts_file.read

def dump
File.open(@hosts_path,"r") { |f| f.read }
end

def add(host, ip_address = "127.0.0.1")
@entries[ip_address] << host
end

def remove(host, ip_address)
@entries[ip_address].delete_if { |x| x == host }
end

def finalize_changes!
lines = @hosts_file.readlines

def write_changes!
@entries.each do |entry|
exists_in_file = false
lines.each_with_index do |line,index|
if line.match(/#{entry.first}/)
exists_in_file = true
lines[index] = "#{entry.first} #{entry.last.join(' ')}\n"
append_this = true
entry_exists = false

File.open(@hosts_path,"r+") do |file|
lines = file.readlines
lines.each_with_index do |line,index|
if line =~ /#{entry.first}/
if entry_exists
lines.delete_at(index)
else
lines[index] = "#{entry.first} #{entry.last.join(' ')}\n"
# update the state of this entry
append_this = false
entry_exists = true
end
end
end
if append_this
# append entry to end of @hosts_file
end
# write out actual changes
file.pos = 0
file.print lines
file.truncate(file.pos)
end
if !exists_in_file
# append entry to end of @hosts_file
end
# write out actual changes
@hosts_file.pos = 0
@hosts_file.print lines
@hosts_file.truncate(@hosts_file.pos)
end
end

private
def extract_entries(hosts_path)

def extract_entries
entries = Hash.new
@hosts_file.each do |line|
if line.match(/^(\d+\.\d+\.\d+\.\d) (.*)/)
File.open(@hosts_path,"r").each do |line|
if line =~ /^(\d+\.\d+\.\d+\.\d) (.*)/
ip_address = $1
hosts_list = $2.split(' ')

if entries.has_key?(ip_address)
hosts_list.each do |host|
entries[ip_address] << host
Expand All @@ -59,5 +68,9 @@ def extract_entries(hosts_path)
end
entries
end


def condense!
File.open(@hosts_path,"r+")
end

end
64 changes: 32 additions & 32 deletions test/test_hoster.rb
Expand Up @@ -3,82 +3,82 @@
require 'test/unit'
require 'shoulda'

TestContent = <<CONTENT
BaseFile = <<CONTENT
127.0.0.1 localhost
127.0.1.1 localhost
192.168.1.1 router.com router
192.168.1.2 localhost
127.0.0.1 test.com
192.168.1.2 local.host
CONTENT

ModifiedFile = <<CONTENT
127.0.0.1 localhost test.com test.dev
127.0.1.1 localhost
192.168.1.1 router router.org
192.168.1.2 localhost local.host
CONTENT

class TestHoster < Test::Unit::TestCase
context "Reading and parsing hosts file" do
setup do
File.open("hosts","w") do |file|
file.puts TestContent
File.open("test/hosts","w") do |file|
file.puts BaseFile
end
@hoster = Hosts.new("hosts")
@hoster = Hosts.new("test/hosts")
end

should "create an object that stores a Hash" do
assert_kind_of Hash, @hoster.entries
end

should "assign ip addresses as hash keys" do
assert @hoster.entries.has_key?("127.0.0.1")
end

should "store a hosts array as hash values" do
assert_kind_of Array, @hoster.entries.values.first
end

should "map multiple hosts to ip addresses on the same line" do
assert_equal "router.com", @hoster.entries["192.168.1.1"].first
assert_equal "router", @hoster.entries["192.168.1.1"].last
end

should "map multiple hosts to same ip address on different lines" do
assert_equal "localhost", @hoster.entries["127.0.0.1"].first
assert_equal "test.com", @hoster.entries["127.0.0.1"].last
end

end

context "Manipulating hosts file" do
setup do
File.open("hosts","w") do |file|
file.puts TestContent
File.open("test/hosts","w") do |file|
file.puts BaseFile
end
@hoster = Hosts.new("hosts")
@hoster = Hosts.new("test/hosts")
end

should "add a host to the correct line for specified ip address" do
assert_equal 2, @hoster.entries["192.168.1.1"].size
@hoster.add("router.org","192.168.1.1")
assert_equal 3, @hoster.entries["192.168.1.1"].size
end

should "remove correct host from line for specified ip address" do
assert_equal 2, @hoster.entries["192.168.1.1"].size
@hoster.remove("router.com", "192.168.1.1")
assert_equal 1, @hoster.entries["192.168.1.1"].size
assert_equal "router", @hoster.entries["192.168.1.1"].first
end

# should "write correct changes to file" do
# @hoster.add("test.dev")
# @hoster.add("router.org","192.168.1.1")
# @hoster.remove("router.com", "192.168.1.1")
# #@hoster.finalize_changes!
# puts @hoster.raw_data
# new_content = <<CONTENT
# 127.0.0.1 localhost test.dev
# 127.0.1.1 localhost
# 192.168.1.1 router router.org
# 192.168.1.2 localhost
# 127.0.0.1 test.com
# CONTENT
# assert_equal new_content, @hoster.raw_data
# end

should "write correct changes to file" do
@hoster.add("test.dev")
@hoster.add("router.org","192.168.1.1")
@hoster.remove("router.com", "192.168.1.1")
@hoster.write_changes!
assert_equal ModifiedFile, @hoster.dump
end
end
end

0 comments on commit c5c98bf

Please sign in to comment.