devdnsd 1.7.0 → 2.0.0

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.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -8,28 +8,28 @@ module DevDNSd
8
8
  # This class holds the configuration of the applicaton.
9
9
  class Configuration < Bovem::Configuration
10
10
  # If to run the server in foreground. Default: `false`.
11
- property :foreground, :default => false
11
+ property :foreground, default: false
12
12
 
13
13
  # The address to listen to. Default: `0.0.0.0`.
14
- property :address, :default => "0.0.0.0"
14
+ property :address, default: "0.0.0.0"
15
15
 
16
16
  # The port to listen to. Default: `7771`.
17
- property :port, :default => 7771
17
+ property :port, default: 7771
18
18
 
19
19
  # The TLD to manage. Default: `dev`.
20
- property :tld, :default => "dev"
20
+ property :tld, default: "dev"
21
21
 
22
22
  # The PID file to use. Default: `/var/run/devdnsd.pid`.
23
- property :pid_file, :default => "/var/log/devdnsd.pid"
23
+ property :pid_file, default: "/var/log/devdnsd.pid"
24
24
 
25
25
  # The file to log to. Default: `/var/log/devdnsd.log`.
26
- property :log_file, :default => "/var/log/devdnsd.log"
26
+ property :log_file, default: "/var/log/devdnsd.log"
27
27
 
28
28
  # The minimum severity to log. Default: `Logger::INFO`.
29
- property :log_level, :default => Logger::INFO
29
+ property :log_level, default: Logger::INFO
30
30
 
31
31
  # The rules of the server. By default, every hostname is resolved with `127.0.0.1`.
32
- property :rules, :default => []
32
+ property :rules, default: []
33
33
 
34
34
  # Creates a new configuration.
35
35
  # A configuration file is a plain Ruby file with a top-level {Configuration config} object.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
data/lib/devdnsd/rule.rb CHANGED
@@ -1,33 +1,31 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
7
7
  module DevDNSd
8
8
  # This class encapsulate a rule for matching an hostname.
9
+ #
10
+ # @attribute match
11
+ # @return [String|Regexp] The pattern to match. Default: `/.+/`.
12
+ # @attribute type
13
+ # @return [Symbol] The type of request to match. Default: `:A`. @see .create
14
+ # @attribute reply
15
+ # @return [String] The IP or hostname to reply back to the client. Default: `127.0.0.1`. @see .create
16
+ # @attribute options
17
+ # @return [Hash] A list of options for the request. Default is an empty hash.
18
+ # @attribute block
19
+ # @return [Proc] An optional block to compute the reply instead of using the `reply` parameter. @see .create
9
20
  class Rule
10
- # The pattern to match. Default: `/.+/`.
11
21
  attr_accessor :match
12
-
13
- # The type of request to match. Default: `:A`.
14
- #
15
- # @see .create
16
22
  attr_accessor :type
17
-
18
- # The IP or hostname to reply back to the client. Default: `127.0.0.1`.
19
- #
20
- # @see .create
21
23
  attr_accessor :reply
22
-
23
- # A list of options for the request. Default is an empty hash.
24
24
  attr_accessor :options
25
-
26
- # An optional block to compute the reply instead of using the `reply` parameter.
27
- #
28
- # @see .create
29
25
  attr_accessor :block
30
26
 
27
+ include Lazier::I18n
28
+
31
29
  # Creates a new rule.
32
30
  #
33
31
  # @param match [String|Regexp] The pattern to match.
@@ -37,23 +35,17 @@ module DevDNSd
37
35
  # @param block [Proc] An optional block to compute the reply instead of using the `reply` parameter.
38
36
  # @see .create
39
37
  def initialize(match = /.+/, reply = "127.0.0.1", type = :A, options = {}, &block)
40
- reply ||= "127.0.0.1"
41
- type ||= :A
42
- @match = match
43
- @type = type
44
- @reply = block.blank? ? reply : nil
45
- @options = options
46
- @block = block
47
-
48
- raise(DevDNSd::Errors::InvalidRule.new("You must specify at least a rule and a host (also via a block). Optionally you can add a record type (default: A) and the options.")) if @reply.blank? && @block.nil?
49
- raise(DevDNSd::Errors::InvalidRule.new("You can only use hashs for options.")) if !@options.is_a?(::Hash)
38
+ self.i18n_setup(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/"))
39
+ self.i18n = options[:locale]
40
+ setup(match, reply, type, options, block)
41
+ validate_rule
50
42
  end
51
43
 
52
44
  # Returns the resource class(es) for the current rule.
53
45
  #
54
46
  # @return [Array|Class] The class(es) for the current rule.
55
47
  def resource_class
56
- classes = self.type.ensure_array.collect {|cls| self.class.symbol_to_resource_class(cls) }.compact.uniq
48
+ classes = @type.ensure_array.collect {|cls| self.class.symbol_to_resource_class(cls, options[:locale]) }.compact.uniq
57
49
  classes.length == 1 ? classes.first : classes
58
50
  end
59
51
 
@@ -61,14 +53,14 @@ module DevDNSd
61
53
  #
62
54
  # @return [Boolean] `true` if the rule is a Regexp, `false` otherwise.
63
55
  def is_regexp?
64
- self.match.is_a?(::Regexp)
56
+ @match.is_a?(::Regexp)
65
57
  end
66
58
 
67
59
  # Checks if the rule is a regexp.
68
60
  #
69
61
  # @return [Boolean] `true` if the rule has a block, `false` otherwise.
70
62
  def has_block?
71
- self.block.present?
63
+ @block.present?
72
64
  end
73
65
 
74
66
  # Matches a hostname to the rule.
@@ -76,7 +68,7 @@ module DevDNSd
76
68
  # @param hostname [String] The hostname to match.
77
69
  # @return [MatchData|Boolean|Nil] Return `true` or MatchData (if the pattern is a regexp) if the rule matches, `false` or `nil` otherwise.
78
70
  def match_host(hostname)
79
- self.is_regexp? ? self.match.match(hostname) : (self.match == hostname)
71
+ self.is_regexp? ? @match.match(hostname) : (@match == hostname)
80
72
  end
81
73
 
82
74
  # Creates a new rule.
@@ -86,23 +78,10 @@ module DevDNSd
86
78
  # @param type [Symbol] The type of request to match. This is ignored if a block is provided.
87
79
  # @param options [Hash] A list of options for the request.
88
80
  # @param block [Proc] An optional block to compute the reply instead of using the `reply_or_type` parameter. In this case `reply_or_type` is used for the type of the request and `type` is ignored.
81
+ # @return [Rule] The new rule.
89
82
  def self.create(match, reply_or_type = nil, type = nil, options = {}, &block)
90
- raise(DevDNSd::Errors::InvalidRule.new("You must specify at least a rule and a host (also via a block). Optionally you can add a record type (default: A) and the options.")) if reply_or_type.blank? && block.nil?
91
- raise(DevDNSd::Errors::InvalidRule.new("You can only use hashs for options.")) if !options.is_a?(::Hash)
92
-
93
- rv = self.new(match)
94
- rv.options = options
95
-
96
- if block.present? then # reply_or_type acts like a type, type is ignored
97
- rv.type = reply_or_type || :A
98
- rv.reply = nil
99
- rv.block = block
100
- else # reply_or_type acts like a reply
101
- rv.reply = reply_or_type || "127.0.0.1"
102
- rv.type = type || :A
103
- end
104
-
105
- rv
83
+ validate_options(reply_or_type, options, block, Lazier::Localizer.new(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/"), options.is_a?(Hash) ? options[:locale] : nil))
84
+ setup(self.new(match), reply_or_type, type, options, block)
106
85
  end
107
86
 
108
87
  # Converts a class to the correspondent symbol.
@@ -116,15 +95,72 @@ module DevDNSd
116
95
  # Converts a symbol to the correspondent DNS resource class.
117
96
  #
118
97
  # @param symbol [Symbol] The symbol to convert.
98
+ # @param locale [Symbol] The locale to use for the messages.
119
99
  # @return [Symbol] The class associated to the symbol.
120
- def self.symbol_to_resource_class(symbol)
100
+ def self.symbol_to_resource_class(symbol, locale = nil)
121
101
  symbol = symbol.to_s.upcase
122
102
 
123
103
  begin
124
104
  "Resolv::DNS::Resource::IN::#{symbol}".constantize
125
105
  rescue ::NameError
126
- raise(DevDNSd::Errors::InvalidRule.new("Invalid resource class #{symbol}."))
106
+ raise(DevDNSd::Errors::InvalidRule.new(Lazier::Localizer.new(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/"), locale).i18n.invalid_class(symbol)))
127
107
  end
128
108
  end
109
+
110
+ private
111
+ # Setups a new rule.
112
+ #
113
+ # @param match [String|Regexp] The pattern to match.
114
+ # @param reply [String] The IP or hostname to reply back to the client.
115
+ # @param type [Symbol] The type of request to match.
116
+ # @param options [Hash] A list of options for the request.
117
+ # @param block [Proc] An optional block to compute the reply instead of using the `reply` parameter.
118
+ def setup(match, reply, type, options, block)
119
+ @match = match
120
+ @type = type || :A
121
+ @reply = block.blank? ? (reply || "127.0.0.1") : nil
122
+ @options = options
123
+ @block = block
124
+ end
125
+
126
+ # Validates a newly created rule.
127
+ def validate_rule
128
+ raise(DevDNSd::Errors::InvalidRule.new(self.i18n.rule_invalid_call)) if @reply.blank? && @block.nil?
129
+ raise(DevDNSd::Errors::InvalidRule.new(self.i18n.rule_invalid_options)) if !@options.is_a?(::Hash)
130
+ end
131
+
132
+ # Setups a new rule.
133
+ #
134
+ # @param rv [Rule] The rule that is been created.
135
+ # @param reply_or_type [String|Symbol] The IP or hostname to reply back to the client (or the type of request to match, if a block is provided).
136
+ # @param type [Symbol] The type of request to match. This is ignored if a block is provided.
137
+ # @param options [Hash] A list of options for the request.
138
+ # @param block [Proc] An optional block to compute the reply instead of using the `reply_or_type` parameter. In this case `reply_or_type` is used for the type of the request and `type` is ignored.
139
+ # @return [Rule] The new rule.
140
+ def self.setup(rv, reply_or_type, type, options = {}, block)
141
+ rv.options = options
142
+ rv.block = block
143
+
144
+ if block.present? then # reply_or_type acts like a type, type is ignored
145
+ rv.type = reply_or_type || :A
146
+ rv.reply = nil
147
+ else # reply_or_type acts like a reply
148
+ rv.reply = reply_or_type || "127.0.0.1"
149
+ rv.type = type || :A
150
+ end
151
+
152
+ rv
153
+ end
154
+
155
+ # Validate options for a new rule creation.
156
+ #
157
+ # @param reply_or_type [String|Symbol] The IP or hostname to reply back to the client (or the type of request to match, if a block is provided).
158
+ # @param options [Hash] A list of options for the request.
159
+ # @param block [Proc] An optional block to compute the reply instead of using the `reply_or_type` parameter. In this case `reply_or_type` is used for the type of the request and `type` is ignored.
160
+ # @param localizer [Localizer] A localizer object.
161
+ def self.validate_options(reply_or_type, options, block, localizer)
162
+ raise(DevDNSd::Errors::InvalidRule.new(localizer.i18n.rule_invalid_call)) if reply_or_type.blank? && block.nil?
163
+ raise(DevDNSd::Errors::InvalidRule.new(localizer.i18n.rule_invalid_options)) if !options.is_a?(::Hash)
164
+ end
129
165
  end
130
166
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -10,10 +10,10 @@ module DevDNSd
10
10
  # @see http://semver.org
11
11
  module Version
12
12
  # The major version.
13
- MAJOR = 1
13
+ MAJOR = 2
14
14
 
15
15
  # The minor version.
16
- MINOR = 7
16
+ MINOR = 0
17
17
 
18
18
  # The patch version.
19
19
  PATCH = 0
data/lib/devdnsd.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -15,4 +15,7 @@ require "devdnsd/application"
15
15
  require "devdnsd/configuration"
16
16
  require "devdnsd/errors"
17
17
  require "devdnsd/rule"
18
- require "devdnsd/version" if !defined?(DevDNSd::Version)
18
+ require "devdnsd/version" if !defined?(DevDNSd::Version)
19
+
20
+ # DevDNSd is only supported on MRI
21
+ DevDNSd::Application.check_ruby_implementation
data/locales/en.yml ADDED
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
+ #
6
+
7
+ ---
8
+ devdnsd:
9
+ rule_invalid_call: "You must specify at least a rule and a host (also via a block). Optionally you can add a record type (default: A) and the options."
10
+ rule_invalid_options: "You can only use hashs for options."
11
+ rule_invalid_resource: "Invalid resource class %1."
12
+ dns_update: "Flushing DNS cache and resolvers ..."
13
+ no_jruby_rubinius: "DevDNSd is not available on JRuby or Rubinius."
14
+ no_fork: "Forking is not available for this platform. Running in foreground ..."
15
+ starting: "Starting DevDNSd ..."
16
+ match: "Found match on %1 with type %2."
17
+ reply: "Reply is %1 with type %2."
18
+ no_reply: "No reply found."
19
+ no_agent: "Install DevDNSd as a local resolver is only available on MacOSX."
20
+ resolver_creating: "Creating the resolver in {mark=bright}%1{/mark} ..."
21
+ resolver_creating_error: "Cannot create the resolver file."
22
+ resolver_deleting: "Deleting the resolver %1 ..."
23
+ resolver_deleting_error: "Cannot delete the resolver file."
24
+ agent_creating: "Creating the launch agent in {mark=bright}%1{/mark} ..."
25
+ agent_creating_error: "Cannot create the launch agent."
26
+ agent_deleting: "Deleting the launch agent %1 ..."
27
+ agent_deleting_error: "Cannot delete the launch agent."
28
+ agent_loading: "Loading the launch agent %1 ..."
29
+ agent_loading_error: "Cannot load the launch agent."
30
+ agent_unloading: "Unloading the launch agent %1 ..."
31
+ agent_unloading_error: "Cannot unload the launch agent."
32
+ logging_failed: "Cannot log to {mark=bright}%1{/mark}. Exiting..."
33
+ application_description: "A small DNS server to enable local domain resolution."
34
+ application_help_configuration: "The configuration file to use. Default is \"~/.devdnsd_config\"."
35
+ application_help_tld: "The TLD to handle. Default is \"dev\"."
36
+ application_help_port: "The port to bind. Default is 7771."
37
+ application_help_pid_file: "The PID file to use. Default is \"/var/run/devdnsd.pid\"."
38
+ application_help_log_file: "The log file to use. Not used if run in foreground. Default is \"/var/log/devdnsd.log\"."
39
+ application_help_log_level: "The log level to use. Valid values are from 0 to 5 where 0 means \"all messages\". Default is 1."
40
+ application_help_foreground: "Do not daemonize."
41
+ application_meta_file: "FILE"
42
+ application_meta_domain: "DOMAIN"
43
+ application_meta_level: "LEVEL"
44
+ application_meta_port: "PORT"
45
+ command_start: "Starts the server."
46
+ command_install: "Installs the server."
47
+ command_uninstall: "Uninstalls the server."
48
+ command_stop: "Stops the server."
data/locales/it.yml ADDED
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
+ #
6
+
7
+ ---
8
+ devdnsd:
9
+ rule_invalid_call: "Devi specificare almeno una regola e un host (anche tramite un blocco). Opzionalmente puoi aggiungere un tipo di record (default: A) e le opzioni."
10
+ rule_invalid_options: "Puoi usare solo hash per le opzioni."
11
+ rule_invalid_resource: "Classe di risorsa %1 non valida."
12
+ no_jruby_rubinius: "DevDNSd non è disponibile per JRuby o Rubinius."
13
+ no_fork: "Il forking non è disponibile per questa piattaforma. Eseguo foreground ..."
14
+ dns_update: "Cancello la cache dei DNS e dei resolver ..."
15
+ starting: "Avvio DevDNSd ..."
16
+ match: "Trovata corrispondenza per %1 con tipo %2."
17
+ reply: "La risposta è %1 con tipo %2."
18
+ no_reply: "Nessuna risposta trovata."
19
+ no_agent: "Installare DevDNSd come resolver locale è disponibile solo su MacOSX."
20
+ resolver_creating: "Creo il resolver in {mark=bright}%1{/mark} ..."
21
+ resolver_creating_error: "Impossible creare il file del resolver."
22
+ resolver_deleting: "Cancello resolver %1 ..."
23
+ resolver_deleting_error: "Impossibile cancellare il file del resolver."
24
+ agent_creating: "Creo il launch agent in {mark=bright}%1{/mark} ..."
25
+ agent_creating_error: "Impossibile creare il launch agent."
26
+ agent_deleting: "Cancello il launch agent %1 ..."
27
+ agent_deleting_error: "Impossibile cancellare launch agent."
28
+ agent_loading: "Avvio il launch agent %1 ..."
29
+ agent_loading_error: "Impossibile avviare il launch agent."
30
+ agent_unloading: "Fermo il launch agent %1 ..."
31
+ agent_unloading_error: "Impossible fermare il launch agent."
32
+ logging_failed: "Impossibile eseguire il logging in {mark=bright}%1{/mark}. Esco..."
33
+ application_description: "Un piccolo server DNS per abilitare la risoluzione di domini locali."
34
+ application_help_configuration: "Il file di configurazione da usare. Il valore predefinito è \"~/.devdnsd_config\"."
35
+ application_help_tld: "Il TLD da gestiere. Il valore predefinito è \"dev\"."
36
+ application_help_port: "The port to bind. La porta predefinita è 7771."
37
+ application_help_pid_file: "Il file PID da usare. Il file predefinito è \"/var/run/devdnsd.pid\"."
38
+ application_help_log_file: "Il file di log da utilizzare. Non usato se eseguito in foreground. Il valore predefinito è \"/var/log/devdnsd.log\"."
39
+ application_help_log_level: "Il livello di log da utilizzare. I valori validi sono da 0 a 5 dove 0 significa \"tutti i messaggi\". Il valore predefinito è 1."
40
+ application_help_foreground: "Non eseguire in background."
41
+ application_meta_file: "FILE"
42
+ application_meta_domain: "DOMINIO"
43
+ application_meta_level: "LIVELLO"
44
+ application_meta_port: "PORTA"
45
+ command_start: "Avvia server."
46
+ command_install: "Installa il server."
47
+ command_uninstall: "Disinstalla il server."
48
+ command_stop: "Ferma il server."
@@ -1,20 +1,17 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
7
7
  require "pathname"
8
+ require "simplecov"
8
9
 
9
- if ENV["DEVDNSD_COVERAGE"] == "TRUE" && RUBY_VERSION >= "1.9" then
10
- require "simplecov"
11
-
10
+ SimpleCov.start do
12
11
  root = Pathname.new(File.dirname(__FILE__)) + ".."
13
12
 
14
- SimpleCov.start do
15
- add_filter do |src_file|
16
- path = Pathname.new(src_file.filename).relative_path_from(root).to_s
17
- path =~ /^lib\/devdnsd\/patches/ || path !~ /^(bin|lib)/
18
- end
13
+ add_filter do |src_file|
14
+ path = Pathname.new(src_file.filename).relative_path_from(root).to_s
15
+ path =~ /^lib\/devdnsd\/patches/ || path !~ /^(bin|lib)/
19
16
  end
20
17
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2012 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -13,20 +13,20 @@ describe DevDNSd::Application do
13
13
  end
14
14
 
15
15
  def create_application(overrides = {})
16
- mamertes_app = Mamertes::App(:run => false) do
17
- option "configuration", [], {:default => overrides["configuration"] || "/dev/null"}
18
- option "tld", [], {:default => overrides["tld"] || "dev"}
19
- option "port", [], {:type => Integer, :default => overrides["port"] || 7771}
20
- option "pid-file", [:P], {:type => String, :default => "/var/run/devdnsd.pid"}
21
- option "log-file", [], {:default => overrides["log-file"] || "/dev/null"}
22
- option "log-level", [:L], {:type => Integer, :default => overrides["log-level"] || 1}
16
+ mamertes_app = Mamertes::App(run: false) do
17
+ option :configuration, [], {default: overrides["configuration"] || "/dev/null"}
18
+ option :tld, [], {default: overrides["tld"] || "dev"}
19
+ option :port, [], {type: Integer, default: overrides["port"] || 7771}
20
+ option :pid_file, [:P, "pid-file"], {type: String, default: "/var/run/devdnsd.pid"}
21
+ option :log_file, [:l, "log-file"], {default: overrides["log_file"] || "/dev/null"}
22
+ option :log_level, [:L, "log-level"], {type: Integer, default: overrides["log_level"] || 1}
23
23
  end
24
24
 
25
- DevDNSd::Application.new(mamertes_app)
25
+ DevDNSd::Application.new(mamertes_app, :en)
26
26
  end
27
27
 
28
28
  let(:log_file) { "/tmp/devdnsd-test-log-#{Time.now.strftime("%Y%m%d-%H%M%S")}" }
29
- let(:application){ create_application({"log-file" => log_file}) }
29
+ let(:application){ create_application({"log_file" => log_file}) }
30
30
  let(:executable) { ::Pathname.new(::File.dirname((__FILE__))) + "../../bin/devdnsd" }
31
31
  let(:sample_config) { ::Pathname.new(::File.dirname((__FILE__))) + "../../config/devdnsd_config.sample" }
32
32
  let(:resolver_path) { "/tmp/devdnsd-test-resolver-#{Time.now.strftime("%Y%m%d-%H%M%S")}" }
@@ -47,7 +47,7 @@ describe DevDNSd::Application do
47
47
  file.write("config.port = ")
48
48
  file.close
49
49
 
50
- expect { create_application({"configuration" => file.path, "log-file" => log_file}) }.to raise_error(::SystemExit)
50
+ expect { create_application({"configuration" => file.path, "log_file" => log_file}) }.to raise_error(::SystemExit)
51
51
  ::File.unlink(path)
52
52
  end
53
53
  end
@@ -66,19 +66,35 @@ describe DevDNSd::Application do
66
66
  end
67
67
  end
68
68
 
69
+ describe ".check_ruby_implementation" do
70
+ it "won't run on Rubinius" do
71
+ stub_const("Rubinius", true)
72
+ Kernel.should_receive(:exit).with(0)
73
+ Kernel.should_receive(:puts)
74
+ DevDNSd::Application.check_ruby_implementation
75
+ end
76
+
77
+ it "won't run on JRuby" do
78
+ stub_const("JRuby", true)
79
+ Kernel.should_receive(:exit).with(0)
80
+ Kernel.should_receive(:puts)
81
+ DevDNSd::Application.check_ruby_implementation
82
+ end
83
+ end
84
+
69
85
  describe ".instance" do
70
86
  before(:each) do
71
87
  DevDNSd::Application.unstub(:instance)
72
88
  end
73
89
 
74
90
  let(:mamertes) {
75
- mamertes_app = Mamertes::App(:run => false) do
76
- option "configuration", [], {:default => "/dev/null"}
77
- option "tld", [], {:default => "dev"}
78
- option "port", [], {:type => Integer, :default => 7771}
79
- option "pid-file", [:P], {:type => String, :default => "/var/run/devdnsd.pid"}
80
- option "log-file", [], {:default => "/dev/null"}
81
- option "log-level", [:L], {:type => Integer, :default => 1}
91
+ mamertes_app = Mamertes::App(run: false) do
92
+ option :configuration, [], {default: "/dev/null"}
93
+ option :tld, [], {default: "dev"}
94
+ option :port, [], {type: Integer, default: 7771}
95
+ option :pid_file, [:P], {type: String, default: "/var/run/devdnsd.pid"}
96
+ option :log_file, [], {default: "/dev/null"}
97
+ option :log_level, [:L], {type: Integer, default: 1}
82
98
  end
83
99
  }
84
100
 
@@ -95,12 +111,12 @@ describe DevDNSd::Application do
95
111
 
96
112
  it "should recreate an instance" do
97
113
  other = DevDNSd::Application.instance(mamertes)
98
- expect(DevDNSd::Application.instance(mamertes, true)).not_to eq(other)
114
+ expect(DevDNSd::Application.instance(mamertes, :en, true)).not_to eq(other)
99
115
  end
100
116
  end
101
117
 
102
118
  describe ".pid_fn" do
103
- let(:application){ create_application({"log-file" => log_file, "configuration" => sample_config}) }
119
+ let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
104
120
 
105
121
  it "returns the default file" do
106
122
  expect(DevDNSd::Application.pid_fn).to eq("/var/run/devdnsd.pid")
@@ -113,7 +129,7 @@ describe DevDNSd::Application do
113
129
  end
114
130
 
115
131
  describe ".pid_directory" do
116
- let(:application){ create_application({"log-file" => log_file, "configuration" => sample_config}) }
132
+ let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
117
133
 
118
134
  it "returns the default path" do
119
135
  expect(DevDNSd::Application.pid_directory).to eq("/var/run")
@@ -126,7 +142,7 @@ describe DevDNSd::Application do
126
142
  end
127
143
 
128
144
  describe ".daemon_name" do
129
- let(:application){ create_application({"log-file" => log_file, "configuration" => sample_config}) }
145
+ let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
130
146
 
131
147
  it "returns the default name" do
132
148
  expect(DevDNSd::Application.daemon_name).to eq("devdnsd")
@@ -139,18 +155,10 @@ describe DevDNSd::Application do
139
155
  end
140
156
 
141
157
  describe "#perform_server" do
142
- let(:application){ create_application({"log-file" => log_file, "configuration" => sample_config}) }
143
-
144
- before(:each) do
145
- class DevDNSd::Application
146
- def on_start
147
- Thread.main[:resolver].wakeup if Thread.main[:resolver].try(:alive?)
148
- end
149
- end
150
- end
158
+ let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
151
159
 
152
160
  def test_resolve(host = "match_1.dev", type = "ANY", nameserver = "127.0.0.1", port = 7771, logger = nil)
153
- host ||= "match.dev"
161
+ application.stub(:on_start) do Thread.main[:resolver].run if Thread.main[:resolver].try(:alive?) end
154
162
 
155
163
  Thread.current[:resolver] = Thread.start {
156
164
  Thread.stop
@@ -159,7 +167,6 @@ describe DevDNSd::Application do
159
167
 
160
168
  Thread.current[:server] = Thread.start {
161
169
  sleep(0.1)
162
-
163
170
  if block_given? then
164
171
  yield
165
172
  else
@@ -178,11 +185,12 @@ describe DevDNSd::Application do
178
185
  application.perform_server
179
186
  end
180
187
 
181
- it "should stop the server" do
182
- application.should_receive(:on_stop)
188
+ it "should setup callbacks" do
189
+ RubyDNS::Server.any_instance.should_receive(:on).with(:start)
190
+ RubyDNS::Server.any_instance.should_receive(:on).with(:stop)
183
191
 
184
192
  Thread.new {
185
- sleep(1)
193
+ sleep(0.1)
186
194
  application.class.quit
187
195
  }
188
196
 
@@ -254,7 +262,7 @@ describe DevDNSd::Application do
254
262
  end
255
263
  end
256
264
 
257
- let(:application){ create_application({"log-file" => log_file, "configuration" => sample_config}) }
265
+ let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
258
266
  let(:transaction){ FakeTransaction.new }
259
267
 
260
268
  it "should match a valid string request" do
@@ -342,17 +350,28 @@ describe DevDNSd::Application do
342
350
 
343
351
  describe "#action_start" do
344
352
  it "should call perform_server in foreground" do
345
- application = create_application({"log-file" => log_file})
353
+ application = create_application({"log_file" => log_file})
346
354
  application.config.foreground = true
347
355
  application.should_receive(:perform_server)
348
356
  application.action_start
349
357
  end
350
358
 
351
359
  it "should start the daemon" do
352
- application = create_application({"log-file" => log_file})
360
+ application = create_application({"log_file" => log_file})
353
361
  ::RExec::Daemon::Controller.should_receive(:start)
354
362
  application.action_start
355
363
  end
364
+
365
+ it "should check for availability of fork" do
366
+ application.config.foreground = false
367
+
368
+ Process.stub(:respond_to?).and_return(false)
369
+ application.should_receive(:perform_server)
370
+ application.logger.should_receive(:warn)
371
+
372
+ application.action_start
373
+ expect(application.config.foreground).to be_true
374
+ end
356
375
  end
357
376
 
358
377
  describe "#action_stop" do
@@ -363,7 +382,7 @@ describe DevDNSd::Application do
363
382
  end
364
383
 
365
384
  describe "#action_install" do
366
- if ::Config::CONFIG['host_os'] =~ /^darwin/ then
385
+ if ::RbConfig::CONFIG['host_os'] =~ /^darwin/ then
367
386
  it "should create the resolver" do
368
387
  application.stub(:resolver_path).and_return(resolver_path)
369
388
  application.stub(:launch_agent_path).and_return(launch_agent_path)
@@ -456,7 +475,7 @@ describe DevDNSd::Application do
456
475
  end
457
476
 
458
477
  describe "#action_uninstall" do
459
- if ::Config::CONFIG['host_os'] =~ /^darwin/ then
478
+ if ::RbConfig::CONFIG['host_os'] =~ /^darwin/ then
460
479
  it "should remove the resolver" do
461
480
  application.stub(:resolver_path).and_return(resolver_path)
462
481
  application.stub(:launch_agent_path).and_return(launch_agent_path)
@@ -510,12 +529,13 @@ describe DevDNSd::Application do
510
529
  ::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
511
530
  end
512
531
 
513
- it "should not unload delete invalid agent" do
532
+ it "should not unload invalid agent" do
514
533
  application.stub(:resolver_path).and_return(resolver_path)
515
534
  application.stub(:launch_agent_path).and_return("/invalid/agent")
516
535
 
517
536
  application.action_install
518
537
  application.stub(:execute_command).and_raise(StandardError)
538
+ application.stub(:dns_update)
519
539
  application.logger.should_receive(:warn).at_least(1)
520
540
  application.action_uninstall
521
541