ghost 1.0.0.pre → 1.0.0.pre.2
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.
- data/README.md +22 -3
- data/lib/ghost/cli/task/set.rb +25 -0
- data/lib/ghost/store/hosts_file_store.rb +39 -14
- data/lib/ghost/version.rb +1 -1
- data/spec/ghost/cli/task/help_spec.rb +1 -0
- data/spec/ghost/store/hosts_file_store_spec.rb +93 -1
- metadata +28 -12
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
|
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
|
-
* [
|
89
|
-
* [
|
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
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
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
|
data/lib/ghost/version.rb
CHANGED
@@ -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
|
-
|
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-
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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.
|
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
|