vagrant-dnsdock-hostupdater 0.0.24 → 0.0.25
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/hosts/aef/hosts.rb +51 -0
- data/lib/hosts/aef/hosts/comment.rb +73 -0
- data/lib/hosts/aef/hosts/element.rb +108 -0
- data/lib/hosts/aef/hosts/empty_element.rb +50 -0
- data/lib/hosts/aef/hosts/entry.rb +123 -0
- data/lib/hosts/aef/hosts/file.rb +252 -0
- data/lib/hosts/aef/hosts/helpers.rb +121 -0
- data/lib/hosts/aef/hosts/section.rb +141 -0
- data/lib/hosts/aef/hosts/version.rb +29 -0
- data/lib/hosts/aef/linebreak/linebreak.rb +148 -0
- data/lib/hosts/hosts.rb +25 -0
- data/lib/hosts/hosts/bare.rb +23 -0
- data/lib/vagrant-dnsdock-hostupdater/command.rb +12 -0
- data/lib/vagrant-dnsdock-hostupdater/plugin.rb +90 -0
- data/lib/version.rb +1 -1
- data/vagrant-dnsdock-hostupdater.gemspec +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ada68a3e31b09151f2826aaad5a5faa817738fa1
|
4
|
+
data.tar.gz: 9a58213c4d6542524501de34ae33607790f91ffc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae27144af3b31d9dd6d3b137344e221c344e221c91daeeeaf0b4e2198ff690c496b75ff5027b661ec19cafda97ae85fa0bdf390b23c280c050395166c7ce4495
|
7
|
+
data.tar.gz: 656747b8e6040cde091d960994b155e6d7f2cfd9f8bb3e6cf2acba411a69397f11cee864ebe6a8c1ca977635a5b62b275c0943bb7ff32b328f2a293e8614db2a
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'set'
|
21
|
+
require 'pathname'
|
22
|
+
require_relative 'linebreak/linebreak'
|
23
|
+
|
24
|
+
# Namespace for projects of Alexander E. Fischer <aef@raxys.net>.
|
25
|
+
#
|
26
|
+
# If you want to be able to simply type Example instead of Aef::Example to
|
27
|
+
# address classes in this namespace simply write the following before using the
|
28
|
+
# classes.
|
29
|
+
#
|
30
|
+
# @example Including the namespace
|
31
|
+
# include Aef
|
32
|
+
# @author Alexander E. Fischer
|
33
|
+
module Aef
|
34
|
+
|
35
|
+
# Namespace for the hosts library
|
36
|
+
module Hosts
|
37
|
+
|
38
|
+
# An exception for errors happening while parsing a hosts file
|
39
|
+
class ParserError < RuntimeError; end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
require_relative 'hosts/version'
|
44
|
+
require_relative 'hosts/helpers'
|
45
|
+
require_relative 'hosts/file'
|
46
|
+
require_relative 'hosts/element'
|
47
|
+
require_relative 'hosts/section'
|
48
|
+
require_relative 'hosts/entry'
|
49
|
+
require_relative 'hosts/comment'
|
50
|
+
require_relative 'hosts/empty_element'
|
51
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# Represents a comment-only line as element of a hosts file
|
26
|
+
class Comment < Element
|
27
|
+
|
28
|
+
# The comment
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :comment
|
32
|
+
|
33
|
+
# Initializes a comment
|
34
|
+
#
|
35
|
+
# @param comment [String] the comment
|
36
|
+
# @param options [Hash]
|
37
|
+
# @option options [String] :cache sets a cached String representation
|
38
|
+
def initialize(comment, options = {})
|
39
|
+
validate_options(options, :cache)
|
40
|
+
|
41
|
+
raise ArgumentError, 'Comment cannot be empty' unless comment
|
42
|
+
|
43
|
+
@comment = comment.to_s
|
44
|
+
@cache = options[:cache].to_s unless options[:cache].nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Sets the comment
|
48
|
+
def comment=(comment)
|
49
|
+
set_if_changed(:comment, comment.to_s) do
|
50
|
+
invalidate_cache!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# A String representation for debugging purposes
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
def inspect
|
58
|
+
generate_inspect(self, :comment, :cache)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
# Defines the algorithm to generate a String representation from scratch.
|
64
|
+
#
|
65
|
+
# @return [String] a generated String representation
|
66
|
+
def generate_string(options = {})
|
67
|
+
"##{comment}\n"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# The base class for elements which are aggregated by the Aef::Hosts::File
|
26
|
+
# class.
|
27
|
+
#
|
28
|
+
# @abstract This class is not supposed to be instantiated.
|
29
|
+
class Element
|
30
|
+
|
31
|
+
include Helpers
|
32
|
+
|
33
|
+
# Cached String representation
|
34
|
+
#
|
35
|
+
# @return [String, Hash, nil]
|
36
|
+
attr_reader :cache
|
37
|
+
|
38
|
+
# Deletes the cached String representation
|
39
|
+
#
|
40
|
+
# @return [Aef::Hosts::Element] a self reference
|
41
|
+
def invalidate_cache!
|
42
|
+
@cache = nil
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# Tells if a String representation is cached or not
|
48
|
+
#
|
49
|
+
# @return [true, false] true if cache is not empty
|
50
|
+
def cache_filled?
|
51
|
+
@cache ? true : false
|
52
|
+
end
|
53
|
+
|
54
|
+
# A String representation for debugging purposes
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
def inspect
|
58
|
+
generate_inspect(self, :cache)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Provides a String representation of the element
|
62
|
+
#
|
63
|
+
# @param [Hash] options
|
64
|
+
# @option options [true, false] :force_generation if set to true, the
|
65
|
+
# cache won't be used, even if it not empty
|
66
|
+
# @option options [:unix, :windows, :mac] :linebreak_encoding the
|
67
|
+
# linebreak encoding of the result. If nothing is specified the result
|
68
|
+
# will be encoded as if :unix was specified.
|
69
|
+
# @see Aef::Linebreak#encode
|
70
|
+
def to_s(options = {})
|
71
|
+
validate_options(options, :force_generation, :linebreak_encoding)
|
72
|
+
|
73
|
+
string = ''
|
74
|
+
|
75
|
+
if !cache_filled? || options[:force_generation]
|
76
|
+
string << generate_string(options)
|
77
|
+
else
|
78
|
+
string << cache_string(options)
|
79
|
+
end
|
80
|
+
|
81
|
+
if options[:linebreak_encoding]
|
82
|
+
string = Aef::Linebreak.encode(string, options[:linebreak_encoding])
|
83
|
+
end
|
84
|
+
|
85
|
+
string
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# Defines the algorithm to generate a String representation from scratch.
|
91
|
+
#
|
92
|
+
# @abstract This method needs to be implemented in descendant classes.
|
93
|
+
# @return [String] a generated String representation
|
94
|
+
def generate_string(options = {})
|
95
|
+
raise NotImplementedError
|
96
|
+
end
|
97
|
+
|
98
|
+
# Defines the algorithm to construct the String representation from cache
|
99
|
+
#
|
100
|
+
# @return [String] the cached String representation
|
101
|
+
def cache_string(options = {})
|
102
|
+
@cache.dup
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# Represents an empty line as element of a hosts file
|
26
|
+
class EmptyElement < Element
|
27
|
+
|
28
|
+
# Initializes an empty Element
|
29
|
+
#
|
30
|
+
# @param [Hash] options
|
31
|
+
# @option options [String] :cache sets a cached String representation
|
32
|
+
def initialize(options = {})
|
33
|
+
validate_options(options, :cache)
|
34
|
+
|
35
|
+
@cache = options[:cache].to_s unless options[:cache].nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# Defines the algorithm to generate a String representation from scratch.
|
41
|
+
#
|
42
|
+
# @return [String] a generated String representation
|
43
|
+
def generate_string(options = {})
|
44
|
+
"\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# Represents an entry line as element of a hosts file
|
26
|
+
class Entry < Element
|
27
|
+
|
28
|
+
# The network address
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :address
|
32
|
+
|
33
|
+
# The primary hostname for the address
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
attr_reader :name
|
37
|
+
|
38
|
+
# Optional comment
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
attr_reader :comment
|
42
|
+
|
43
|
+
# Optional alias hostnames
|
44
|
+
#
|
45
|
+
# @return [Array<String>]
|
46
|
+
attr_reader :aliases
|
47
|
+
|
48
|
+
# Initializes an entry.
|
49
|
+
#
|
50
|
+
# @param [String] address the network address
|
51
|
+
# @param [String] name the primary hostname for the address
|
52
|
+
# @param [Hash] options
|
53
|
+
# @option options [Array<String>] :aliases a list of aliases for the
|
54
|
+
# address
|
55
|
+
# @option options [String] :comment a comment for the entry
|
56
|
+
# @option options [String] :cache a cached String representation
|
57
|
+
def initialize(address, name, options = {})
|
58
|
+
validate_options(options, :aliases, :comment, :cache)
|
59
|
+
|
60
|
+
raise ArgumentError, 'Address cannot be empty' unless address
|
61
|
+
raise ArgumentError, 'Name cannot be empty' unless name
|
62
|
+
|
63
|
+
@address = address.to_s
|
64
|
+
@name = name.to_s
|
65
|
+
@aliases = options[:aliases] || []
|
66
|
+
@comment = options[:comment].to_s unless options[:comment].nil?
|
67
|
+
@cache = options[:cache].to_s unless options[:cache].nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets the network address
|
71
|
+
def address=(address)
|
72
|
+
set_if_changed(:address, address.to_s) do
|
73
|
+
invalidate_cache!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Sets the primary hostname for the address
|
78
|
+
def name=(name)
|
79
|
+
set_if_changed(:name, name.to_s) do
|
80
|
+
invalidate_cache!
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Sets the optional comment
|
85
|
+
def comment=(comment)
|
86
|
+
set_if_changed(:comment, comment.to_s) do
|
87
|
+
invalidate_cache!
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Sets the optional alias hostnames
|
92
|
+
def aliases=(aliases)
|
93
|
+
set_if_changed(:aliases, [*aliases]) do
|
94
|
+
invalidate_cache!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# A String representation for debugging purposes
|
99
|
+
#
|
100
|
+
# @return [String]
|
101
|
+
def inspect
|
102
|
+
generate_inspect(self, :address, :name, :aliases, :comment, :cache)
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
# Defines the algorithm to generate a String representation from scratch.
|
108
|
+
#
|
109
|
+
# @abstract This method needs to be implemented in descendant classes.
|
110
|
+
# @return [String] a generated String representation
|
111
|
+
def generate_string(options = nil)
|
112
|
+
if comment
|
113
|
+
suffix = " ##{comment}\n"
|
114
|
+
else
|
115
|
+
suffix = "\n"
|
116
|
+
end
|
117
|
+
|
118
|
+
[address, name, *aliases].join(' ') << suffix
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# This class represents a hosts file and aggregates its elements.
|
26
|
+
#
|
27
|
+
# It is able to parse host files from file-system or String and can
|
28
|
+
# generate a String representation of itself to String or file-system.
|
29
|
+
class File
|
30
|
+
|
31
|
+
include Helpers
|
32
|
+
|
33
|
+
# Regular expression to extract a comment line.
|
34
|
+
#
|
35
|
+
# @private
|
36
|
+
COMMENT_LINE_PATTERN = /^\s*#(.*)$/
|
37
|
+
|
38
|
+
# Regular expression to extract section headers and footers.
|
39
|
+
#
|
40
|
+
# @private
|
41
|
+
SECTION_MARKER_PATTERN = /^ -----(BEGIN|END) SECTION (.*)-----(?:[\r])?$/
|
42
|
+
|
43
|
+
# Regular expression to extract entry lines.
|
44
|
+
#
|
45
|
+
# @private
|
46
|
+
ENTRY_LINE_PATTERN = /^([^#]*)(?:#(.*))?$/
|
47
|
+
|
48
|
+
# The hosts file's elements.
|
49
|
+
#
|
50
|
+
# @return [Array<Aef::Hosts::Element>]
|
51
|
+
attr_accessor :elements
|
52
|
+
|
53
|
+
# The filesystem path of the hosts file.
|
54
|
+
#
|
55
|
+
# @return [Pathname, nil]
|
56
|
+
attr_reader :path
|
57
|
+
|
58
|
+
class << self
|
59
|
+
# Parses a hosts file given as path.
|
60
|
+
#
|
61
|
+
# @param [Pathname] path the hosts file path
|
62
|
+
# @return [Aef::Hosts::File] a file
|
63
|
+
def read(path)
|
64
|
+
new(path).read
|
65
|
+
end
|
66
|
+
|
67
|
+
# Parses a hosts file given as String.
|
68
|
+
#
|
69
|
+
# @param [String] data a String representation of the hosts file
|
70
|
+
# @return [Aef::Hosts::File] a file
|
71
|
+
def parse(data)
|
72
|
+
new.parse(data)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Initializes a file.
|
77
|
+
#
|
78
|
+
# @param [Pathname] path path to the hosts file
|
79
|
+
def initialize(path = nil)
|
80
|
+
reset
|
81
|
+
self.path = path
|
82
|
+
end
|
83
|
+
|
84
|
+
# Removes all elements.
|
85
|
+
#
|
86
|
+
# @return [Aef::Hosts::File] a self reference
|
87
|
+
def reset
|
88
|
+
@elements = []
|
89
|
+
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
# Deletes the cached String representations of all elements.
|
94
|
+
#
|
95
|
+
# @return [Aef::Hosts::File] a self reference
|
96
|
+
def invalidate_cache!
|
97
|
+
elements.each do |element|
|
98
|
+
element.invalidate_cache!
|
99
|
+
end
|
100
|
+
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sets the filesystem path of the hosts file.
|
105
|
+
def path=(path)
|
106
|
+
@path = to_pathname(path)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Parses a hosts file given as path.
|
110
|
+
#
|
111
|
+
# @param [Pathname] path override the path attribute for this operation
|
112
|
+
# @return [Aef::Hosts::File] a self reference
|
113
|
+
def read(path = nil)
|
114
|
+
path = path.nil? ? @path : to_pathname(path)
|
115
|
+
|
116
|
+
raise ArgumentError, 'No path given' unless path
|
117
|
+
|
118
|
+
parse(path.read)
|
119
|
+
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
# Parses a hosts file given as String.
|
124
|
+
#
|
125
|
+
# @param [String] data a String representation of the hosts file
|
126
|
+
# @return [Aef::Hosts::File] a self reference
|
127
|
+
def parse(data)
|
128
|
+
current_section = self
|
129
|
+
|
130
|
+
data.to_s.lines.each_with_index do |line, line_number|
|
131
|
+
line = Linebreak.encode(line, :unix)
|
132
|
+
|
133
|
+
if COMMENT_LINE_PATTERN =~ line
|
134
|
+
comment = $1
|
135
|
+
|
136
|
+
if SECTION_MARKER_PATTERN =~ comment
|
137
|
+
type = $1
|
138
|
+
name = $2
|
139
|
+
|
140
|
+
case type
|
141
|
+
when 'BEGIN'
|
142
|
+
unless current_section.is_a?(Section)
|
143
|
+
current_section = Section.new(
|
144
|
+
name,
|
145
|
+
:cache => {:header => line, :footer => nil}
|
146
|
+
)
|
147
|
+
else
|
148
|
+
raise ParserError, "Invalid cascading of sections. Cannot start new section '#{name}' without first closing section '#{current_section.name}' on line #{line_number + 1}."
|
149
|
+
end
|
150
|
+
when 'END'
|
151
|
+
if name == current_section.name
|
152
|
+
current_section.cache[:footer] = line
|
153
|
+
elements << current_section
|
154
|
+
current_section = self
|
155
|
+
else
|
156
|
+
raise ParserError, "Invalid closing of section. Found attempt to close section '#{name}' in body of section '#{current_section.name}' on line #{line_number + 1}."
|
157
|
+
end
|
158
|
+
end
|
159
|
+
else
|
160
|
+
current_section.elements << Comment.new(
|
161
|
+
comment,
|
162
|
+
:cache => line
|
163
|
+
)
|
164
|
+
end
|
165
|
+
else
|
166
|
+
ENTRY_LINE_PATTERN =~ line
|
167
|
+
|
168
|
+
entry = $1
|
169
|
+
comment = $2
|
170
|
+
|
171
|
+
if entry and not entry =~ /^\s+$/
|
172
|
+
|
173
|
+
split = entry.split(/\s+/)
|
174
|
+
split.shift if split.first == ''
|
175
|
+
|
176
|
+
address, name, *aliases = *split
|
177
|
+
|
178
|
+
current_section.elements << Entry.new(
|
179
|
+
address, name,
|
180
|
+
:aliases => aliases,
|
181
|
+
:comment => comment,
|
182
|
+
:cache => line
|
183
|
+
)
|
184
|
+
else
|
185
|
+
current_section.elements << EmptyElement.new(
|
186
|
+
:cache => line
|
187
|
+
)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
self
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generates a hosts file and writes it to a path.
|
196
|
+
#
|
197
|
+
# @param [Hash] options
|
198
|
+
# @option options [Pathname] :path overrides the path attribute for this
|
199
|
+
# operation
|
200
|
+
# @option options [true, false] :force_generation if set to true, the
|
201
|
+
# cache won't be used, even if it not empty
|
202
|
+
# @option options [:unix, :windows, :mac] :linebreak_encoding the
|
203
|
+
# linebreak encoding of the result. If nothing is specified the result
|
204
|
+
# will be encoded as if :unix was specified.
|
205
|
+
# @see Aef::Linebreak#encode
|
206
|
+
def write(options = {})
|
207
|
+
validate_options(options, :force_generation, :linebreak_encoding, :path)
|
208
|
+
|
209
|
+
path = options[:path].nil? ? @path : to_pathname(options[:path])
|
210
|
+
|
211
|
+
raise ArgumentError, 'No path given' unless path
|
212
|
+
|
213
|
+
options.delete(:path)
|
214
|
+
|
215
|
+
path.open('w') do |file|
|
216
|
+
file.write(to_s(options))
|
217
|
+
end
|
218
|
+
|
219
|
+
true
|
220
|
+
end
|
221
|
+
|
222
|
+
# A String representation for debugging purposes.
|
223
|
+
#
|
224
|
+
# @return [String]
|
225
|
+
def inspect
|
226
|
+
generate_inspect(self, :path, :elements)
|
227
|
+
end
|
228
|
+
|
229
|
+
# A String representation of the hosts file.
|
230
|
+
#
|
231
|
+
# @param [Hash] options
|
232
|
+
# @option options [true, false] :force_generation if set to true, the
|
233
|
+
# cache won't be used, even if it not empty
|
234
|
+
# @option options [:unix, :windows, :mac] :linebreak_encoding the
|
235
|
+
# linebreak encoding of the result. If nothing is specified the result
|
236
|
+
# will be encoded as if :unix was specified.
|
237
|
+
# @see Aef::Linebreak#encode
|
238
|
+
def to_s(options = {})
|
239
|
+
validate_options(options, :force_generation, :linebreak_encoding)
|
240
|
+
|
241
|
+
string = ''
|
242
|
+
|
243
|
+
@elements.each do |element|
|
244
|
+
string << element.to_s(options)
|
245
|
+
end
|
246
|
+
|
247
|
+
string
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# Helper methods used internally in the hosts library
|
26
|
+
#
|
27
|
+
# @private
|
28
|
+
module Helpers
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# Ensures that an options Hash has includes only valid keys
|
33
|
+
#
|
34
|
+
# @param [Hash] options the options Hash to verify
|
35
|
+
# @param [Array<Symbol>] valid_keys a list of valid keys for the Hash
|
36
|
+
# @raise [ArgumentError] if Hash includes invalid keys
|
37
|
+
def validate_options(options, *valid_keys)
|
38
|
+
remainder = options.keys - valid_keys
|
39
|
+
|
40
|
+
unless remainder.empty?
|
41
|
+
raise ArgumentError, "Invalid option keys: #{remainder.map(&:inspect).join(',')}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Casts a given object to Pathname or passes through a given nil
|
46
|
+
#
|
47
|
+
# @param [String, Pathname, nil] path a filesystem path
|
48
|
+
# @return [Pathname, nil]
|
49
|
+
def to_pathname(path)
|
50
|
+
path.nil? ? nil : Pathname.new(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Generates a String representation for debugging purposes.
|
54
|
+
#
|
55
|
+
# @param [Object] model a model for which the String is generated
|
56
|
+
# @param [Array<Symbol, String>] attributes Attributes to be displayed.
|
57
|
+
# If given as Symbol, the attribute's value will be presented by name
|
58
|
+
# and the inspect output of its value. If given as String, the String
|
59
|
+
# will represent it instead.
|
60
|
+
# @return [String] a string representation for debugging purposes
|
61
|
+
def generate_inspect(model, *attributes)
|
62
|
+
string = "#<#{model.class}"
|
63
|
+
|
64
|
+
components = []
|
65
|
+
|
66
|
+
attributes.each do |attribute|
|
67
|
+
if attribute == :cache
|
68
|
+
components << 'cached!' if model.send(:cache_filled?)
|
69
|
+
elsif attribute == :elements
|
70
|
+
components << generate_elements_partial(model.elements)
|
71
|
+
elsif attribute.is_a?(Symbol)
|
72
|
+
components << "#{attribute}=#{model.send(attribute).inspect}"
|
73
|
+
else
|
74
|
+
components << attribute
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
components.unshift(':') unless components.empty?
|
79
|
+
|
80
|
+
string << components.join(' ')
|
81
|
+
string << '>'
|
82
|
+
end
|
83
|
+
|
84
|
+
# Generate a partial String for an element listing in inspect output.
|
85
|
+
#
|
86
|
+
# @return [String] element partial
|
87
|
+
def generate_elements_partial(elements)
|
88
|
+
elements_string = 'elements=['
|
89
|
+
|
90
|
+
unless elements.empty?
|
91
|
+
elements_string << "\n"
|
92
|
+
elements_string << elements.map{|element|
|
93
|
+
element.inspect.lines.map{|line| " #{line}"}.join
|
94
|
+
}.join(",\n")
|
95
|
+
elements_string << "\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
elements_string << "]"
|
99
|
+
end
|
100
|
+
|
101
|
+
# Sets a given attribute and executes the block if the current value
|
102
|
+
# differs from the given.
|
103
|
+
#
|
104
|
+
# @param [Symbol] attribute the attribute's name
|
105
|
+
# @param [Object] new_value the value to be assigned to the attribute if
|
106
|
+
# it differs from its current value
|
107
|
+
# @yield Executed if current value differs from the given
|
108
|
+
def set_if_changed(attribute, new_value)
|
109
|
+
variable_name = :"@#{attribute}"
|
110
|
+
old_value = instance_variable_get(variable_name)
|
111
|
+
|
112
|
+
if new_value != old_value
|
113
|
+
instance_variable_set(variable_name, new_value)
|
114
|
+
|
115
|
+
yield if block_given?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require_relative '../hosts'
|
21
|
+
|
22
|
+
module Aef
|
23
|
+
module Hosts
|
24
|
+
|
25
|
+
# This represents a section as element of a hosts file. It consists of a
|
26
|
+
# header, futher included elements and a footer
|
27
|
+
class Section < Element
|
28
|
+
|
29
|
+
# Title of the section
|
30
|
+
#
|
31
|
+
# @return [String]
|
32
|
+
attr_reader :name
|
33
|
+
|
34
|
+
# Elements inside the section
|
35
|
+
#
|
36
|
+
# @note If the Array is modified in place, you need to manually
|
37
|
+
# invalidate the cache with option :only_section => true.
|
38
|
+
# @see #invalidate_cache!
|
39
|
+
# @return [Array<Aef::Host::Element>]
|
40
|
+
attr_reader :elements
|
41
|
+
|
42
|
+
# Initializes a section
|
43
|
+
#
|
44
|
+
# @param [String] name title of the section
|
45
|
+
# @param [Hash] options
|
46
|
+
# @option options [String] :cache sets a cached String representation
|
47
|
+
# @option options [Array<Aef::Hosts::Element>] :elements a list of
|
48
|
+
# elements in the section
|
49
|
+
def initialize(name, options = {})
|
50
|
+
validate_options(options, :cache, :elements)
|
51
|
+
|
52
|
+
raise ArgumentError, 'Name cannot be empty' unless name
|
53
|
+
|
54
|
+
@name = name.to_s
|
55
|
+
@elements = options[:elements] || []
|
56
|
+
@cache = options[:cache] || {:header => nil, :footer => nil}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Deletes the cached String representation
|
60
|
+
#
|
61
|
+
# @param [Hash] options
|
62
|
+
# @option [true, false] :only_section if set to true, the invalidation
|
63
|
+
# will not cascade onto the elements. Default is false.
|
64
|
+
# @return [Aef::Hosts::Section] a self reference
|
65
|
+
def invalidate_cache!(options = {})
|
66
|
+
@cache = {:header => nil, :footer => nil}
|
67
|
+
|
68
|
+
unless options[:only_section]
|
69
|
+
elements.each do |element|
|
70
|
+
element.invalidate_cache!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Tells if a String representation is cached or not
|
76
|
+
#
|
77
|
+
# @return [true, false] true if cache is not empty
|
78
|
+
def cache_filled?
|
79
|
+
!!@cache[:header] && !!@cache[:footer]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the title of the section
|
83
|
+
def name=(name)
|
84
|
+
set_if_changed(:name, name.to_s) do
|
85
|
+
invalidate_cache!(:only_section => true)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sets the elements inside the section
|
90
|
+
def elements=(elements)
|
91
|
+
set_if_changed(:elements, [*elements]) do
|
92
|
+
invalidate_cache!(:only_section => true)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# A String representation for debugging purposes
|
97
|
+
#
|
98
|
+
# @return [String]
|
99
|
+
def inspect
|
100
|
+
generate_inspect(self, :name, :cache, :elements)
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
# Defines the algorithm to generate a String representation from scratch.
|
106
|
+
#
|
107
|
+
# @return [String] a generated String representation
|
108
|
+
def generate_string(options = {})
|
109
|
+
string = ''
|
110
|
+
|
111
|
+
string << "# -----BEGIN SECTION #{name}-----\n"
|
112
|
+
|
113
|
+
@elements.each do |element|
|
114
|
+
string << element.to_s(options)
|
115
|
+
end
|
116
|
+
|
117
|
+
string << "# -----END SECTION #{name}-----\n"
|
118
|
+
|
119
|
+
string
|
120
|
+
end
|
121
|
+
|
122
|
+
# Defines the algorithm to construct the String representation from cache
|
123
|
+
#
|
124
|
+
# @return [String] the cached String representation
|
125
|
+
def cache_string(options = {})
|
126
|
+
string = ''
|
127
|
+
|
128
|
+
string << @cache[:header]
|
129
|
+
|
130
|
+
@elements.each do |element|
|
131
|
+
string << element.to_s(options)
|
132
|
+
end
|
133
|
+
|
134
|
+
string << @cache[:footer]
|
135
|
+
|
136
|
+
string
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
module Aef
|
21
|
+
module Hosts
|
22
|
+
|
23
|
+
# The currently loaded library version
|
24
|
+
#
|
25
|
+
# Using Semantic Versioning (2.0.0-rc.1) rules
|
26
|
+
# @see http://semver.org/
|
27
|
+
VERSION = '0.1.1'.freeze
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@godobject.net>, 2009-2013
|
4
|
+
|
5
|
+
This file is part of Linebreak.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'set'
|
21
|
+
|
22
|
+
# Namespace for projects of Alexander E. Fischer <aef@raxys.net>.
|
23
|
+
#
|
24
|
+
# If you want to be able to simply type Example instead of Aef::Example to
|
25
|
+
# address classes in this namespace simply write the following before using the
|
26
|
+
# classes.
|
27
|
+
#
|
28
|
+
# @example Including the namespace
|
29
|
+
# include Aef
|
30
|
+
# @author Alexander E. Fischer
|
31
|
+
module Aef
|
32
|
+
|
33
|
+
# Namespace for the linebreak library
|
34
|
+
module Linebreak
|
35
|
+
|
36
|
+
# Mapping table from symbol to actual linebreak sequence
|
37
|
+
#
|
38
|
+
# @private
|
39
|
+
BREAK_BY_SYSTEM = {
|
40
|
+
:unix => "\n",
|
41
|
+
:windows => "\r\n",
|
42
|
+
:mac => "\r"
|
43
|
+
}
|
44
|
+
|
45
|
+
# Mapping table from actual linebreak sequence to symbol
|
46
|
+
#
|
47
|
+
# @private
|
48
|
+
SYSTEM_BY_BREAK = BREAK_BY_SYSTEM.invert
|
49
|
+
|
50
|
+
# Regular expression for linebreak detection and extraction
|
51
|
+
#
|
52
|
+
# @private
|
53
|
+
BREAK_REGEXP = /(\r\n|[\r\n])/
|
54
|
+
|
55
|
+
# Detects encoding systems of a string.
|
56
|
+
#
|
57
|
+
# @param [String] input a String to be analysed
|
58
|
+
# @return [Set<Symbol>] the encoding systems present in the given String
|
59
|
+
def self.encodings(input)
|
60
|
+
if input.respond_to?(:to_s) then input = input.to_s
|
61
|
+
else raise ArgumentError, 'Input needs to be a string or must support to_s' end
|
62
|
+
|
63
|
+
occurences = Set.new
|
64
|
+
|
65
|
+
input.scan(BREAK_REGEXP).each do |linebreak|
|
66
|
+
occurences << SYSTEM_BY_BREAK[linebreak.first]
|
67
|
+
end
|
68
|
+
|
69
|
+
occurences
|
70
|
+
end
|
71
|
+
|
72
|
+
# Checks whether a string includes linebreaks of all the given encoding
|
73
|
+
# systems.
|
74
|
+
#
|
75
|
+
# @param [String] input a String to be analysed
|
76
|
+
# @param [Array<Symbol>] encodings one or more encoding systems
|
77
|
+
# @return [true, false] true if all of the given linebreak systems are
|
78
|
+
# present in the given String
|
79
|
+
def self.encoding?(input, *encodings)
|
80
|
+
systems = BREAK_BY_SYSTEM.keys
|
81
|
+
|
82
|
+
encodings.flatten!
|
83
|
+
encodings.each do |encoding|
|
84
|
+
unless systems.include?(encoding)
|
85
|
+
raise ArgumentError,
|
86
|
+
%{Invalid encoding system. Available systems: #{systems.join(', ')}. Arguments are expected as symbols or an array of symbols.}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Aef::Linebreak.encodings(input) == Set.new(encodings)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create a copy of a string with all the string's linebreaks replaced by
|
94
|
+
# linebreaks of a specific system or a given replacement.
|
95
|
+
#
|
96
|
+
# @overload encode(input, system)
|
97
|
+
# @param [String] input a String as conversion template
|
98
|
+
# @param [:unix, :windows, :mac] system a target linebreak system
|
99
|
+
#
|
100
|
+
# @overload encode(input, replacement)
|
101
|
+
# @param [String] input a String as conversion template
|
102
|
+
# @param [String] replacement a String to be the replacement for all
|
103
|
+
# linebreaks in the template
|
104
|
+
def self.encode(input, system_or_replacement = :unix)
|
105
|
+
if input.respond_to?(:to_s) then input = input.to_s
|
106
|
+
else raise ArgumentError, 'Input needs to be a string or must support to_s' end
|
107
|
+
|
108
|
+
input.gsub(BREAK_REGEXP,
|
109
|
+
BREAK_BY_SYSTEM[system_or_replacement] || system_or_replacement)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Detects encoding systems of a string.
|
113
|
+
#
|
114
|
+
# This method is supposed to be used as a method of String.
|
115
|
+
#
|
116
|
+
# @return [Set<Symbol>] the encoding systems present in the String
|
117
|
+
def linebreak_encodings
|
118
|
+
Aef::Linebreak.encodings(self)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Checks whether a string includes linebreaks of all the given encoding
|
122
|
+
# systems.
|
123
|
+
#
|
124
|
+
# This method is supposed to be used as a method of String.
|
125
|
+
#
|
126
|
+
# @param [Array<Symbol>] encodings one or more encoding systems
|
127
|
+
# @return [true, false] true if all of the given linebreak systems are
|
128
|
+
# present in the given String
|
129
|
+
def linebreak_encoding?(*encodings)
|
130
|
+
Aef::Linebreak.encoding?(self, encodings)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Create a copy of a string with all the string's linebreaks replaced by
|
134
|
+
# linebreaks of a specific system or a given replacement.
|
135
|
+
#
|
136
|
+
# This method is supposed to be used as a method of String.
|
137
|
+
#
|
138
|
+
# @overload encode(system)
|
139
|
+
# @param [:unix, :windows, :mac] system a target linebreak system
|
140
|
+
#
|
141
|
+
# @overload encode(replacement)
|
142
|
+
# @param [String] replacement a String to be the replacement for all
|
143
|
+
# linebreaks in the template
|
144
|
+
def linebreak_encode(system_or_replacement = :unix)
|
145
|
+
Aef::Linebreak.encode(self, system_or_replacement)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
data/lib/hosts/hosts.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
# Helper file to allow loading by gem name. Creates an alias for Aef::Hosts
|
21
|
+
# named simply Hosts if this name isn't used otherwise.
|
22
|
+
|
23
|
+
require_relative 'aef/hosts'
|
24
|
+
|
25
|
+
::Hosts = Aef::Hosts unless defined?(::Hosts)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
# Require this file if you don't want an alias for Aef::Hosts named simply
|
21
|
+
# Hosts.
|
22
|
+
|
23
|
+
require_relative '../hosts'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module DnsdockHostUpdater
|
3
|
+
|
4
|
+
module OS
|
5
|
+
def OS.windows?
|
6
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def OS.mac?
|
10
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def OS.unix?
|
14
|
+
!OS.windows?
|
15
|
+
end
|
16
|
+
|
17
|
+
def OS.linux?
|
18
|
+
OS.unix? and not OS.mac?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Plugin < Vagrant.plugin('2')
|
23
|
+
name "dnsdock-host-updater"
|
24
|
+
|
25
|
+
description <<-DESC
|
26
|
+
Updates hosts for docker containers on guest VM.
|
27
|
+
DESC
|
28
|
+
|
29
|
+
@started = false
|
30
|
+
|
31
|
+
# Add command for `$ vagrant dnsdock-host-updater`
|
32
|
+
# command 'dnsdock-host-updater' do
|
33
|
+
# require_relative 'command'
|
34
|
+
# Command
|
35
|
+
# end
|
36
|
+
|
37
|
+
def self.pid_path
|
38
|
+
File.expand_path('~/.docker-host-manager.pid')
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.log(msg)
|
42
|
+
puts "[vagrant-dnsdock-hostupdater] #{msg}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.pid
|
46
|
+
File.exist?(pid_path) ? File.read(pid_path) : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.close_manager
|
50
|
+
if pid
|
51
|
+
log "Already running with PID: #{pid}"
|
52
|
+
begin
|
53
|
+
log "Attempting to stop server with PID: #{pid}"
|
54
|
+
Process.kill('KILL', pid.to_i)
|
55
|
+
rescue
|
56
|
+
log "Unable to kill process with ID: #{pid}. This may be because the process has already been terminated."
|
57
|
+
end
|
58
|
+
|
59
|
+
log "Cleaning up PID file: #{pid_path}"
|
60
|
+
File.delete(pid_path)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.init_plugin
|
65
|
+
server_path = File.expand_path('../../server.rb', __FILE__)
|
66
|
+
|
67
|
+
if @started
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
close_manager
|
72
|
+
|
73
|
+
pid = Process.spawn("ruby #{server_path}")
|
74
|
+
log "Started server with PID: #{pid}"
|
75
|
+
|
76
|
+
if pid
|
77
|
+
pid_file = File.open(pid_path, 'w')
|
78
|
+
pid_file << pid
|
79
|
+
pid_file.close
|
80
|
+
log "Wrote server PID (#{pid}) to #{pid_path}"
|
81
|
+
Process.detach(pid)
|
82
|
+
@started = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
action_hook(:up, :machine_action_up) { init_plugin }
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/version.rb
CHANGED
@@ -11,7 +11,7 @@ DNSDock should be configured on the guest machine to enable containers to resolv
|
|
11
11
|
DESCRIPTION
|
12
12
|
s.authors = ['Brian Coit']
|
13
13
|
s.email = 'brian.coit@cellosignal.com'
|
14
|
-
s.files = Dir['{lib}
|
14
|
+
s.files = Dir['{lib}/**/*'] + ['Rakefile', 'Gemfile', 'Gemfile.lock', 'vagrant-dnsdock-hostupdater.gemspec']
|
15
15
|
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
16
|
s.require_paths = ['lib']
|
17
17
|
s.homepage = 'https://bitbucket.org/briancoit'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-dnsdock-hostupdater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Coit
|
@@ -67,9 +67,23 @@ files:
|
|
67
67
|
- lib/client.rb
|
68
68
|
- lib/event-watcher.rb
|
69
69
|
- lib/host-manager.rb
|
70
|
+
- lib/hosts/aef/hosts.rb
|
71
|
+
- lib/hosts/aef/hosts/comment.rb
|
72
|
+
- lib/hosts/aef/hosts/element.rb
|
73
|
+
- lib/hosts/aef/hosts/empty_element.rb
|
74
|
+
- lib/hosts/aef/hosts/entry.rb
|
75
|
+
- lib/hosts/aef/hosts/file.rb
|
76
|
+
- lib/hosts/aef/hosts/helpers.rb
|
77
|
+
- lib/hosts/aef/hosts/section.rb
|
78
|
+
- lib/hosts/aef/hosts/version.rb
|
79
|
+
- lib/hosts/aef/linebreak/linebreak.rb
|
80
|
+
- lib/hosts/hosts.rb
|
81
|
+
- lib/hosts/hosts/bare.rb
|
70
82
|
- lib/launch-control
|
71
83
|
- lib/server.rb
|
72
84
|
- lib/vagrant-dnsdock-hostupdater.rb
|
85
|
+
- lib/vagrant-dnsdock-hostupdater/command.rb
|
86
|
+
- lib/vagrant-dnsdock-hostupdater/plugin.rb
|
73
87
|
- lib/version.rb
|
74
88
|
- vagrant-dnsdock-hostupdater.gemspec
|
75
89
|
homepage: https://bitbucket.org/briancoit
|