svutil 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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