ghost 1.0.0.pre → 1.0.0.pre.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -65,6 +65,11 @@ Command
65
65
  Listing 1 host(s):
66
66
  staging-server.local -> 64.233.167.99
67
67
 
68
+ With RVM you need to add `rvmsudo` before the command:
69
+
70
+ $ rvmsudo ghost add mydevsite.local
71
+ [Adding] mydevsite.local -> 127.0.0.1
72
+
68
73
  Library
69
74
  -------
70
75
 
@@ -77,23 +82,37 @@ Installation
77
82
 
78
83
  sudo gem install ghost
79
84
 
85
+ If you are using RVM:
86
+
87
+ gem install ghost
88
+
80
89
  Contributors
81
90
  ============
82
91
 
83
- If this list is ever out of date, you can get full contributor list with `git log --format='%aN (%ae)' | sort -u`
92
+ If this list is ever out of date, you can get full contributor list
93
+ with `git log --format='%aN (%ae)' | sort -u` or from [here](https://github.com/bjeanes/ghost/graphs/contributors).
84
94
 
85
95
  * [Alkesh Vaghmaria](https://github.com/alkesh)
86
96
  * [Andrei Serdeliuc](https://github.com/extraordinaire)
87
97
  * [Ben Hoskings](https://github.com/benhoskings)
88
- * [Bodaniel Jeanes](https://github.com/bjeanes)
89
- * [Courtois Simon](https://github.com/simonc)
98
+ * [Bo Jeanes](https://github.com/bjeanes)
99
+ * [David Warkentin](https://github.com/ev0rtex)
100
+ * [Duncan Beevers](https://github.com/duncanbeevers)
90
101
  * [Felipe Coury](https://github.com/fcoury)
102
+ * [Finn Smith](https://github.com/finn)
103
+ * [Geoff Wagstaff](https://github.com/TheDeveloper)
104
+ * [Johannes Thoenes](https://github.com/jthoenes)
91
105
  * [Justin Mazzi](https://github.com/jmazzi)
92
106
  * [Lars Fronius](https://github.com/LarsFronius)
93
107
  * [Lee Jensen](https://github.com/outerim)
108
+ * [Luiz Galaviz](https://github.com/MGalv)
109
+ * [Luiz Rocha](https://github.com/lsdr)
94
110
  * [Mitchell Riley](https://github.com/mitchellvriley)
111
+ * [Noah Kantrowitz](https://github.com/coderanger)
95
112
  * [Ryan Bigg](https://github.com/radar)
96
113
  * [Sam Beam](https://github.com/sbeam)
114
+ * [Simon Courtois](https://github.com/simonc)
115
+ * [Turadg Aleahmad](https://github.com/turadg)
97
116
 
98
117
  Legal Stuff
99
118
  ===========
@@ -0,0 +1,25 @@
1
+ Ghost::Cli.task :set do
2
+ desc "Add a host or modify the IP of an existing host"
3
+ def perform(host, ip = nil)
4
+ host = Ghost::Host.new(*[host, ip].compact)
5
+ Ghost.store.set(host)
6
+ puts "[Setting] #{host.name} -> #{host.ip}"
7
+ rescue Ghost::Host::NotResolvable
8
+ abort "Unable to resolve IP address for target host #{ip.inspect}."
9
+ end
10
+
11
+ help do
12
+ <<-EOF.unindent
13
+ Usage: ghost set <local host name> [<remote host name>|<IP address>]
14
+
15
+ #{desc}.
16
+
17
+ If a second parameter is not provided, it defaults to 127.0.0.1
18
+
19
+ Examples:
20
+ ghost set my-localhost # points to 127.0.0.1
21
+ ghost set google.dev google.com # points to the IP of google.com
22
+ ghost set router 192.168.1.1 # points to 192.168.1.1
23
+ EOF
24
+ end
25
+ end
@@ -2,21 +2,19 @@ require 'set'
2
2
 
3
3
  require 'ghost/host'
4
4
  require 'ghost/tokenized_file'
5
+ require 'resolv'
5
6
 
6
7
  module Ghost
7
8
  module Store
8
9
  # TODO: A lot of this duplicates Resolv::Hosts in Ruby stdlib.
9
10
  # Can that be modifiied to use tokens in place of this?
10
11
  class HostsFileStore
11
- attr_accessor :path, :file
12
+ attr_accessor :path, :file, :strict
12
13
 
13
- # TODO: Support windows locations:
14
- # Windows 95/98/Me c:\windows\hosts
15
- # Windows NT/2000/XP Pro c:\winnt\system32\drivers\etc\hosts
16
- # Windows XP Home c:\windows\system32\drivers\etc\hosts
17
- def initialize(path = "/etc/hosts")
14
+ def initialize(path = Resolv::Hosts::DefaultFileName)
18
15
  self.path = path
19
16
  self.file = Ghost::TokenizedFile.new(path, "# ghost start", "# ghost end")
17
+ self.strict = true
20
18
  end
21
19
 
22
20
  def add(host)
@@ -28,6 +26,16 @@ module Ghost
28
26
  true
29
27
  end
30
28
 
29
+ def set(host)
30
+ sync do |buffer|
31
+ delete_host host, buffer
32
+ buffer[host.ip] << host.name
33
+ buffer_changed!
34
+ end
35
+
36
+ true
37
+ end
38
+
31
39
  def all
32
40
  sync do |buffer|
33
41
  buffer.map do |ip, hosts|
@@ -41,17 +49,34 @@ module Ghost
41
49
  end
42
50
 
43
51
  def delete(host)
44
- result = SortedSet.new
45
52
  sync do |buffer|
46
- buffer.each do |ip, names|
47
- names.dup.each do |name|
48
- next unless host.match(name)
49
- next if host.respond_to?(:ip) && host.ip != ip
53
+ delete_host host, buffer, :strict
54
+ end
55
+ end
56
+
57
+ def purge(host)
58
+ sync do |buffer|
59
+ delete_host host, buffer
60
+ end
61
+ end
50
62
 
51
- result << Ghost::Host.new(name, ip)
52
- names.delete(name)
53
- buffer_changed!
63
+ def delete_host(host, buffer, strict = false)
64
+ result = SortedSet.new
65
+ buffer.each do |ip, names|
66
+ names.each do |name|
67
+ if host.kind_of? Host
68
+ next unless host.name == name
69
+ elsif host.kind_of? String
70
+ next unless host == name
71
+ else
72
+ next unless host.match(name)
54
73
  end
74
+
75
+ next if host.respond_to?(:ip) && host.ip != ip && strict
76
+
77
+ result << Ghost::Host.new(name, ip)
78
+ names.delete(name)
79
+ buffer_changed!
55
80
  end
56
81
  end
57
82
  result.to_a
@@ -1,3 +1,3 @@
1
1
  module Ghost
2
- VERSION = "1.0.0.pre"
2
+ VERSION = "1.0.0.pre.2"
3
3
  end
@@ -14,6 +14,7 @@ describe Ghost::Cli, :type => :cli do
14
14
  export Export all hosts in /etc/hosts format
15
15
  import Import hosts in /etc/hosts format
16
16
  list Show all (or a filtered) list of hosts
17
+ set Add a host or modify the IP of an existing host
17
18
 
18
19
  See 'ghost help <task>' for more information on a specific task.
19
20
  EOF
@@ -34,7 +34,10 @@ describe Ghost::Store::HostsFileStore do
34
34
  before { write(contents) }
35
35
 
36
36
  it 'manages the default file of /etc/hosts when no file path is provided' do
37
- described_class.new.path.should == "/etc/hosts"
37
+ previous_hosts_location = Resolv::Hosts::DefaultFileName
38
+ Resolv::Hosts::DefaultFileName = "hosts_location"
39
+ described_class.new.path.should == "hosts_location"
40
+ Resolv::Hosts::DefaultFileName = previous_hosts_location
38
41
  end
39
42
 
40
43
  it 'manages the file at the provided path when given' do
@@ -276,6 +279,95 @@ describe Ghost::Store::HostsFileStore do
276
279
  end
277
280
  end
278
281
 
282
+ describe "#set" do
283
+ let(:host) { Ghost::Host.new("github.com", "127.0.0.1") }
284
+
285
+ context 'with existing ghost-managed hosts in the file' do
286
+ let(:contents) do
287
+ <<-EOF.gsub(/^\s+/,'')
288
+ 127.0.0.1 localhost localhost.localdomain
289
+ # ghost start
290
+ 192.168.1.1 github.com
291
+ 192.168.1.2 github.com
292
+ # ghost end
293
+ EOF
294
+ end
295
+
296
+ context 'when setting the host to an IP' do
297
+ it 'replaces all instances of that hostname with a single entry for that IP' do
298
+ store.set(host)
299
+ read.should == <<-EOF.gsub(/^\s+/,'')
300
+ 127.0.0.1 localhost localhost.localdomain
301
+ # ghost start
302
+ 127.0.0.1 github.com
303
+ # ghost end
304
+ EOF
305
+ end
306
+
307
+ it 'returns true' do
308
+ store.set(host).should be_true
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ describe "#purge" do
315
+ context 'with existing ghost-managed hosts in the file' do
316
+ let(:contents) do
317
+ <<-EOF.gsub(/^\s+/,'')
318
+ 127.0.0.1 localhost localhost.localdomain
319
+ # ghost start
320
+ 127.0.0.1 google.com
321
+ 127.0.0.2 gooogle.com
322
+ 192.168.1.1 github.com
323
+ # ghost end
324
+ EOF
325
+ end
326
+
327
+ context 'when purging one of the ghost entries' do
328
+ context 'using a Ghost::Host to identify host' do
329
+ context 'and the IP does not match an entry' do
330
+ let(:host) { Ghost::Host.new("google.com", "127.0.0.2") }
331
+
332
+ it 'returns array of removed hosts' do
333
+ store.purge(host).should == [Ghost::Host.new('google.com', '127.0.0.1')]
334
+ end
335
+
336
+ it 'removes the host from the file' do
337
+ store.purge(host)
338
+ read.should == <<-EOF.gsub(/^\s+/,'')
339
+ 127.0.0.1 localhost localhost.localdomain
340
+ # ghost start
341
+ 127.0.0.2 gooogle.com
342
+ 192.168.1.1 github.com
343
+ # ghost end
344
+ EOF
345
+ end
346
+ end
347
+
348
+ context 'and the IP matches an entry' do
349
+ let(:host) { Ghost::Host.new("google.com", "127.0.0.1") }
350
+
351
+ it 'returns array of removed hosts' do
352
+ store.purge(host).should == [Ghost::Host.new('google.com', '127.0.0.1')]
353
+ end
354
+
355
+ it 'removes the host from the file' do
356
+ store.purge(host)
357
+ read.should == <<-EOF.gsub(/^\s+/,'')
358
+ 127.0.0.1 localhost localhost.localdomain
359
+ # ghost start
360
+ 127.0.0.2 gooogle.com
361
+ 192.168.1.1 github.com
362
+ # ghost end
363
+ EOF
364
+ end
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
370
+
279
371
  describe "#empty" do
280
372
  context 'with no ghost-managed hosts in the file' do
281
373
  it 'returns false' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghost
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre
4
+ version: 1.0.0.pre.2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,41 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-05 00:00:00.000000000Z
12
+ date: 2012-11-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: unindent
16
- requirement: &70100277448360 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - =
19
+ - - '='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '1.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70100277448360
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &70100277447880 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
- - - =
35
+ - - '='
31
36
  - !ruby/object:Gem::Version
32
37
  version: 2.9.0
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70100277447880
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.9.0
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: rake
38
- requirement: &70100277447400 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
- - - =
51
+ - - '='
42
52
  - !ruby/object:Gem::Version
43
53
  version: 0.9.2.2
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70100277447400
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2.2
47
62
  description: Allows you to create, list, and modify local hostnames on POSIX systems
48
63
  (e.g. Mac OS X and Linux) and Windows
49
64
  email: me@bjeanes.com
@@ -62,6 +77,7 @@ files:
62
77
  - lib/ghost/cli/task/help.rb
63
78
  - lib/ghost/cli/task/import.rb
64
79
  - lib/ghost/cli/task/list.rb
80
+ - lib/ghost/cli/task/set.rb
65
81
  - lib/ghost/cli/task.rb
66
82
  - lib/ghost/cli.rb
67
83
  - lib/ghost/host.rb
@@ -107,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
123
  version: 1.3.1
108
124
  requirements: []
109
125
  rubyforge_project: ghost
110
- rubygems_version: 1.8.10
126
+ rubygems_version: 1.8.23
111
127
  signing_key:
112
128
  specification_version: 3
113
129
  summary: Allows you to create, list, and modify local hostnames