svutil 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/svutil.rb CHANGED
@@ -6,5 +6,5 @@ require 'svutil/log'
6
6
  require 'svutil/process_manager'
7
7
 
8
8
  module SVUtil
9
- VERSION = '0.9.4'
9
+ VERSION = '0.9.5'
10
10
  end
data/lib/svutil/config.rb CHANGED
@@ -4,9 +4,11 @@ require 'ostruct'
4
4
  require 'pp'
5
5
 
6
6
  module SVUtil
7
- class Defaults
8
- attr_reader :attrs
7
+ def self.config
8
+ Config.config_class
9
+ end
9
10
 
11
+ class Defaults
10
12
  def initialize
11
13
  @attrs = {}
12
14
  end
@@ -24,39 +26,43 @@ module SVUtil
24
26
  end
25
27
  end
26
28
 
29
+ # TODO: We could make Config a module so that it cannot be instantiated (see http://dalibornasevic.com/posts/9-ruby-singleton-pattern-again)
27
30
  class Config
28
- attr_writer :config_file
29
- attr_reader :attrs
31
+
32
+ class << self
33
+ attr_writer :config_file
34
+ attr_reader :attrs
35
+ attr_reader :defaults
36
+ # Used mainly for testing
37
+ attr_accessor :option_source
30
38
 
31
- def initialize
32
- @cli_options = {}
33
- @attrs = if self.class.defaults
34
- self.class.defaults.attrs.clone
35
- else
36
- {}
39
+ attr_accessor :cli_options
40
+ attr_accessor :cli_option_handlers
41
+
42
+ def clear_all
43
+ @attrs = {}
37
44
  end
38
- end
39
45
 
40
- def set(options = {})
41
- if block_given?
42
- yield self
46
+ def set(options = {})
47
+ @attrs ||= {}
48
+ if block_given?
49
+ yield self
50
+ end
51
+ self.validate
43
52
  end
44
- self.validate
45
- end
46
53
 
47
- def config_file
48
- @config_file ||= "settings"
49
- end
54
+ def defaults(&block)
55
+ @defaults ||= Defaults.new
56
+ yield @defaults
57
+ end
50
58
 
51
- # TODO: Put in module and extend
52
- class << self
53
- attr_reader :cli_option_handlers
54
- attr_reader :validate_block
59
+ def config_file
60
+ @config_file ||= "settings"
61
+ end
55
62
 
56
- def defaults
57
- @defaults ||= Defaults.new
58
- yield @defaults if block_given?
59
- return @defaults
63
+ def set_cli_option(option, value)
64
+ @cli_options ||= {}
65
+ @cli_options[option.to_s] = value
60
66
  end
61
67
 
62
68
  def handle_options(&block)
@@ -67,101 +73,102 @@ module SVUtil
67
73
  def validator(&block)
68
74
  @validate_block = block
69
75
  end
70
- end
71
76
 
72
- def set_cli_option(option, value)
73
- @cli_options ||= {}
74
- @cli_options[option.to_s] = value
75
- end
76
-
77
- def validate
78
- # TODO: Check file perms
79
- if ((pid_file.nil? or pid_file.empty? or File.directory?(pid_file)) && self.daemon)
80
- err("PID file must be a writable file")
77
+ def validate
78
+ # TODO: Check file perms
79
+ if ((pid_file.nil? or pid_file.empty? or File.directory?(pid_file)) && self.daemon)
80
+ err("PID file must be a writable file")
81
+ end
82
+ # TODO: Validate the writability of the log file
83
+ @validate_block.call(self) unless @validate_block.nil?
84
+ true
81
85
  end
82
- # TODO: Validate the writability of the log file
83
- self.instance_exec(self, &self.class.validate_block) unless self.class.validate_block.nil?
84
- true
85
- end
86
-
87
- def init(test_options = nil)
88
- set do |c|
89
- self.config_provided_on_cli = false
90
- OptionParser.new do |opts|
91
- opts.on("-f", "--config [filename]", "Config file to use (default 'settings')") do |filename|
92
- self.config_file = filename.strip
93
- self.config_provided_on_cli = true
94
- end
95
- opts.on("-d", "--daemon", "Run in the background as a daemon") do
96
- set_cli_option(:daemon, true)
97
- end
98
- opts.on("-l", "--debug-log [log-file]", "Debug Log File") do |log|
99
- set_cli_option(:log_file, log)
100
- end
101
- opts.on("-T", "--trace", "Display backtrace on errors") do
102
- set_cli_option(:trace, true)
103
- end
104
- opts.on("-P", "--pid [pid-file]", "PID File") do |pid|
105
- set_cli_option(:pid_file, pid)
106
- end
107
- # Handle CLI passed options
108
- (self.class.cli_option_handlers || []).each do |handler|
109
- self.instance_exec(opts, &handler)
110
- end
111
- end.parse!(test_options || ARGV)
112
86
 
87
+ def init
88
+ set do |c|
89
+ self.config_provided_on_cli = false
90
+ OptionParser.new do |opts|
91
+ opts.on("-f", "--config [filename]", "Config file to use (default 'settings')") do |filename|
92
+ self.config_file = filename.strip
93
+ self.config_provided_on_cli = true
94
+ end
95
+ opts.on("-d", "--daemon", "Run in the background as a daemon") do
96
+ set_cli_option(:daemon, true)
97
+ end
98
+ opts.on("-l", "--debug-log [log-file]", "Debug Log File") do |log|
99
+ set_cli_option(:log_file, log)
100
+ end
101
+ opts.on("-T", "--trace", "Display backtrace on errors") do
102
+ set_cli_option(:trace, true)
103
+ end
104
+ opts.on("-P", "--pid [pid-file]", "PID File") do |pid|
105
+ set_cli_option(:pid_file, pid)
106
+ end
107
+ # Handle CLI passed options
108
+ (cli_option_handlers || []).each do |handler|
109
+ handler.call(opts)
110
+ end
111
+ end.parse!(self.option_source || ARGV)
113
112
 
114
- # Process the config file
115
- if (self.config_file && File.exists?(self.config_file)) || self.config_provided_on_cli
116
- load_config_file
117
- end
113
+ # Process the config file
114
+ if (self.config_file && File.exists?(self.config_file)) || self.config_provided_on_cli
115
+ load_config_file
116
+ end
118
117
 
119
- # Finally apply any CLI options
120
- (@cli_options || {}).each do |(k,v)|
121
- @attrs[k.to_s] = v
118
+ # Finally apply any CLI options
119
+ (cli_options || {}).each do |(k,v)|
120
+ c.send("#{k}=", v)
121
+ end
122
122
  end
123
123
  end
124
- end
125
124
 
126
- private
127
- def method_missing(method_id, *args)
128
- if method_id.to_s =~ /=$/
129
- @attrs[method_id.to_s[0...-1]] = args.first
130
- else
131
- value = @attrs[method_id.to_s]
125
+ private
126
+ def method_missing(method_id, *args)
127
+ @defaults ||= Defaults.new
128
+ @attrs ||= {}
129
+ if method_id.to_s =~ /=$/
130
+ @attrs[method_id.to_s[0...-1]] = args.first
131
+ else
132
+ value = @attrs[method_id.to_s]
133
+ if !value && @defaults
134
+ @defaults.default_for(method_id.to_s)
135
+ else
136
+ value
137
+ end
138
+ end
132
139
  end
133
- end
134
140
 
135
- def load_config_file
136
- contents = ""
137
- File.open(config_file, "r") { |file| contents << file.read }
138
- contents.split("\n").each_with_index do |line, index|
139
- pair = line.split("=")
140
- if pair.size != 2
141
- err("Invalid config file '#{config_file}'. Syntax error at line #{index + 1}")
141
+ def load_config_file
142
+ contents = ""
143
+ File.open(config_file, "r") { |file| contents << file.read }
144
+ contents.split("\n").each_with_index do |line, index|
145
+ pair = line.split("=")
146
+ if pair.size != 2
147
+ err("Invalid config file '#{config_file}'. Syntax error at line #{index + 1}")
148
+ end
149
+ self.send("#{pair[0].strip}=", pair[1].strip)
142
150
  end
143
- self.send("#{pair[0].strip}=", pair[1].strip)
144
151
  end
145
- end
146
152
 
147
- # TODO: This should be moved out to a Validator class
148
- def err(message)
149
- Log.error(message)
150
- exit 1
151
- end
153
+ # TODO: This should be moved out to a Validator class
154
+ def err(message)
155
+ STDERR.puts(message)
156
+ exit 1
157
+ end
152
158
 
153
- def subclasses_of(*superclasses) #:nodoc:
154
- subclasses = []
155
- superclasses.each do |sup|
156
- ObjectSpace.each_object(Class) do |k|
157
- if superclasses.any? { |superclass| k < superclass } &&
158
- (k.name.nil? || k.name.empty? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
159
- subclasses << k
159
+ def subclasses_of(*superclasses) #:nodoc:
160
+ subclasses = []
161
+ superclasses.each do |sup|
162
+ ObjectSpace.each_object(Class) do |k|
163
+ if superclasses.any? { |superclass| k < superclass } &&
164
+ (k.name.nil? || k.name.empty? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
165
+ subclasses << k
166
+ end
160
167
  end
168
+ subclasses.uniq!
161
169
  end
162
- subclasses.uniq!
170
+ subclasses
163
171
  end
164
- subclasses
165
- end
172
+ end
166
173
  end
167
174
  end
@@ -22,6 +22,7 @@ module SVUtil
22
22
 
23
23
  def start
24
24
  begin
25
+ # TODO: Daemonize will call exit in the main process resulting in an unexpected log entry (even though it forks)
25
26
  daemonize if @config.daemon
26
27
  write_pid_file
27
28
  @server_instance.run
data/test/test_config.rb CHANGED
@@ -3,7 +3,6 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
3
3
  class CustomConfig < SVUtil::Config
4
4
  defaults do |c|
5
5
  c.foo = 'bar'
6
- c.manager = 'daniel'
7
6
  end
8
7
  end
9
8
 
@@ -11,75 +10,77 @@ class TestConfig < Test::Unit::TestCase
11
10
  include SVUtil
12
11
 
13
12
  def setup
14
- @custom_config = CustomConfig.new
15
13
  end
16
14
 
17
15
  def test_set
18
- assert !@custom_config.my_symbol
19
- @custom_config.my_symbol = 'abc'
20
- assert_equal 'abc', @custom_config.my_symbol
21
- @custom_config.my_var = 10
22
- assert_equal 10, @custom_config.my_var
16
+ assert !CustomConfig.my_symbol
17
+ CustomConfig.my_symbol = 'abc'
18
+ assert_equal 'abc', CustomConfig.my_symbol
19
+ CustomConfig.my_var = 10
20
+ assert_equal 10, CustomConfig.my_var
23
21
  end
24
22
 
25
23
  def test_set_with_block
26
- @custom_config.expects(:validate).times(1)
27
- @custom_config.set do |c|
24
+ CustomConfig.expects(:validate).times(1)
25
+ CustomConfig.set do |c|
28
26
  c.another = 'abc'
29
27
  c.some_var = 123
30
28
  c.foobar = true
31
29
  end
32
- assert_equal 'abc', @custom_config.another
33
- assert_equal 123, @custom_config.some_var
34
- assert @custom_config.foobar
30
+ assert_equal 'abc', CustomConfig.another
31
+ assert_equal 123, CustomConfig.some_var
32
+ assert CustomConfig.foobar
35
33
  end
36
34
 
37
35
  def test_standard_cli_options
38
- @custom_config = CustomConfig.new
39
- @custom_config.expects(:validate).times(1)
40
- #@custom_config.option_source = [ "-f", "test/settings", "-d", "-l", "debug", "-T" ]
41
- @custom_config.init([ "-f", "test/settings", "-d", "-l", "debug", "-T" ])
42
- assert_equal "test/settings", @custom_config.config_file
43
- assert_equal "debug", @custom_config.log_file
44
- assert @custom_config.daemon
45
- assert @custom_config.trace
36
+ CustomConfig.expects(:validate).times(1)
37
+ CustomConfig.option_source = [ "-f", "test/settings", "-d", "-l", "debug", "-T" ]
38
+ CustomConfig.init
39
+ assert_equal "test/settings", CustomConfig.config_file
40
+ assert_equal "debug", CustomConfig.log_file
41
+ assert CustomConfig.daemon
42
+ assert CustomConfig.trace
46
43
  end
47
44
 
48
45
  def test_config_file
49
- @custom_config.expects(:validate).times(1)
50
- @custom_config.config_file = "test/settings"
51
- @custom_config.init
52
- assert_equal 'bar', @custom_config.foo
46
+ CustomConfig.expects(:validate).times(1)
47
+ CustomConfig.config_file = "test/settings"
48
+ CustomConfig.init
49
+ assert_equal 'bar', CustomConfig.foo
53
50
  end
54
51
 
55
52
  def test_load_config_file
56
- @custom_config.expects(:load_config_file).times(1)
57
- @custom_config.config_file = "test/settings"
58
- @custom_config.init
59
- assert_equal 'bar', @custom_config.foo
53
+ CustomConfig.expects(:load_config_file).times(1)
54
+ CustomConfig.config_file = "test/settings"
55
+ CustomConfig.init
56
+ assert_equal 'bar', CustomConfig.foo
60
57
  end
61
58
 
62
59
  def test_validations_on_cli_with_no_config_file
63
- @custom_config.expects(:validate).times(1)
64
- @custom_config.config_file = nil
65
- @custom_config.init
60
+ CustomConfig.expects(:validate).times(1)
61
+ CustomConfig.config_file = nil
62
+ CustomConfig.init
66
63
  end
67
64
 
68
65
  # Command Line wins!
69
66
  def test_file_overide
70
- @custom_config.expects(:validate).times(1)
71
- @custom_config.config_file = "test/settings"
72
- @custom_config.init([ "-l", "logfile_set_on_cli" ])
73
- assert_equal "logfile_set_on_cli", @custom_config.log_file
67
+ CustomConfig.expects(:validate).times(1)
68
+ CustomConfig.config_file = "test/settings"
69
+ CustomConfig.option_source = [ "-l", "logfile_set_on_cli" ]
70
+ CustomConfig.init
71
+ assert_equal "logfile_set_on_cli", CustomConfig.log_file
74
72
  end
75
73
 
76
74
  def test_defaults
77
- assert_equal 'daniel', @custom_config.manager
78
- @custom_config.manager = 'james'
79
- assert_equal 'james', @custom_config.manager
75
+ CustomConfig.defaults do |c|
76
+ c.manager = 'daniel'
77
+ end
78
+ assert_equal 'daniel', CustomConfig.manager
79
+ CustomConfig.manager = 'james'
80
+ assert_equal 'james', CustomConfig.manager
80
81
  end
81
82
 
82
83
  def test_custom_defaults
83
- assert_equal 'bar', @custom_config.foo
84
+ assert_equal 'bar', CustomConfig.foo
84
85
  end
85
86
  end
@@ -15,18 +15,19 @@ class TestConfigHandleOptions < Test::Unit::TestCase
15
15
  include SVUtil
16
16
 
17
17
  def setup
18
- @my_config = MyConfig.new
19
18
  end
20
19
 
21
20
  def test_handle_options
22
- @my_config.init([ "-P", "foo", "-x", "12345", "-Q" ])
23
- assert @my_config.pid_file = "foo"
24
- assert @my_config.x = '1234'
25
- assert @my_config.restless
21
+ MyConfig.option_source = [ "-P", "foo", "-x", "12345", "-Q" ]
22
+ MyConfig.init
23
+ assert MyConfig.pid_file = "foo"
24
+ assert MyConfig.x = '1234'
25
+ assert MyConfig.restless
26
26
  end
27
27
 
28
28
  def test_built_in_options
29
- @my_config.init([ "-d", "-P", "foo" ])
30
- assert @my_config.daemon
29
+ MyConfig.option_source = [ "-d", "-P", "foo" ]
30
+ MyConfig.init
31
+ assert MyConfig.daemon
31
32
  end
32
33
  end
@@ -13,25 +13,23 @@ class TestProcesManager < Test::Unit::TestCase
13
13
  @klass = mock
14
14
  @klass.stubs(:new).returns(@instance)
15
15
  @klass.stubs(:instance_of?).with(Class).returns(true)
16
+ ServerConfig.clear_all
16
17
  end
17
18
 
18
19
  def test_initialize
19
- config = ServerConfig.new
20
- ProcessManager.new(@klass, config)
20
+ ProcessManager.new(@klass, ServerConfig)
21
21
  end
22
22
 
23
23
  def test_initialize_and_start_with_server_instance
24
- config = ServerConfig.new
25
- pm = ProcessManager.new(@instance, config)
24
+ pm = ProcessManager.new(@instance, ServerConfig)
26
25
  @instance.expects(:run)
27
26
  assert_exit { pm.start }
28
27
  end
29
28
 
30
29
  # TODO: Could probably test this better by actually forking
31
30
  def test_start_as_daemon
32
- config = ServerConfig.new
33
- config.daemon = true
34
- pm = ProcessManager.new(@klass, config)
31
+ ServerConfig.daemon = true
32
+ pm = ProcessManager.new(@klass, ServerConfig)
35
33
  pm.expects(:daemonize)
36
34
  pm.expects(:write_pid_file)
37
35
  pm.expects(:shutdown)
@@ -40,9 +38,8 @@ class TestProcesManager < Test::Unit::TestCase
40
38
  end
41
39
 
42
40
  def test_start_with_trace
43
- config = ServerConfig.new
44
- config.trace = true
45
- pm = ProcessManager.new(@klass, config)
41
+ ServerConfig.trace = true
42
+ pm = ProcessManager.new(@klass, ServerConfig)
46
43
  pm.expects(:write_pid_file)
47
44
  @instance.expects(:run).raises(Exception)
48
45
  Log.expects(:error).times(2)
@@ -50,8 +47,7 @@ class TestProcesManager < Test::Unit::TestCase
50
47
  end
51
48
 
52
49
  def test_shutdown
53
- config = ServerConfig.new
54
- pm = ProcessManager.new(@klass, config)
50
+ pm = ProcessManager.new(@klass, ServerConfig)
55
51
  pm.expects(:write_pid_file)
56
52
  @instance.expects(:run)
57
53
  assert_exit { pm.start }
@@ -63,9 +59,8 @@ class TestProcesManager < Test::Unit::TestCase
63
59
  end
64
60
 
65
61
  def test_shutdown_with_trace
66
- config = ServerConfig.new
67
- config.trace = true
68
- pm = ProcessManager.new(@klass, config)
62
+ ServerConfig.trace = true
63
+ pm = ProcessManager.new(@klass, ServerConfig)
69
64
  pm.expects(:write_pid_file)
70
65
  @instance.expects(:run)
71
66
  assert_exit { pm.start }
@@ -77,6 +72,5 @@ class TestProcesManager < Test::Unit::TestCase
77
72
  assert_exit { pm.send(:shutdown) }
78
73
  end
79
74
 
80
-
81
75
  # TODO: Test all of the exceptions
82
76
  end
@@ -10,18 +10,17 @@ class TestValidations < Test::Unit::TestCase
10
10
  include SVUtil
11
11
 
12
12
  def setup
13
- @validated_config = ValidatedConfig.new
14
13
  end
15
14
 
16
15
  def test_custom_validation_error
17
- @validated_config.expects(:err).times(1)
18
- @validated_config.output_dir = nil
19
- @validated_config.validate
16
+ ValidatedConfig.expects(:err).times(1)
17
+ ValidatedConfig.output_dir = nil
18
+ ValidatedConfig.validate
20
19
  end
21
20
 
22
21
  def test_custom_validation
23
- @validated_config.expects(:err).never
24
- @validated_config.output_dir = "foo"
25
- assert @validated_config.validate
22
+ ValidatedConfig.expects(:err).never
23
+ ValidatedConfig.output_dir = "foo"
24
+ assert ValidatedConfig.validate
26
25
  end
27
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svutil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-04 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: newgem
16
- requirement: &70131061952480 !ruby/object:Gem::Requirement
16
+ requirement: &70183734200680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.5.3
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70131061952480
24
+ version_requirements: *70183734200680
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: hoe
27
- requirement: &70131061951260 !ruby/object:Gem::Requirement
27
+ requirement: &70183734199780 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.12'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70131061951260
35
+ version_requirements: *70183734199780
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rdoc
38
- requirement: &70131057661900 !ruby/object:Gem::Requirement
38
+ requirement: &70183729865820 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '3.10'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70131057661900
46
+ version_requirements: *70183729865820
47
47
  description: A simple managed process builder for Ruby projects
48
48
  email:
49
49
  - daniel@netfox.com