consoleappsupport 0.5.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.
- data/History.txt +13 -0
- data/Manifest.txt +13 -0
- data/README.txt +69 -0
- data/Rakefile +9 -0
- data/examples/apache_log_to_csv.conf +6 -0
- data/examples/console_app_example.conf +4 -0
- data/examples/console_app_example.rb +47 -0
- data/examples/convert_logs_to_csv.rb +64 -0
- data/examples/example_log4r.xml +21 -0
- data/lib/ConsoleAppHelper.rb +32 -0
- data/lib/ConsoleAppMixin.rb +325 -0
- data/lib/ConsoleAppSupport.rb +12 -0
- data/test/test_consoleappsupport.rb +8 -0
- metadata +84 -0
data/History.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
=== 0.5.0 / 2009-06-08
|
2
|
+
|
3
|
+
* Initial public release
|
4
|
+
|
5
|
+
* Determines configuration options for a program by parsing specially-formatted
|
6
|
+
comments in the main source file, similarly to RDoc.
|
7
|
+
* Loads values for these configuration options by parsing the command line.
|
8
|
+
* Loads further values from a run-time config file. As usual, command-line
|
9
|
+
options override config file options, which override defaults.
|
10
|
+
* Provides a Log4r object with the default configuration, pointed to STDOUT.
|
11
|
+
* Automatically loads a Logr4 config file, if config option "--log4r-file" is
|
12
|
+
defined and enabled.
|
13
|
+
* Displays RDoc usage message if config option "--help" is defined and enabled.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
examples/apache_log_to_csv.conf
|
6
|
+
examples/console_app_example.conf
|
7
|
+
examples/console_app_example.rb
|
8
|
+
examples/convert_logs_to_csv.rb
|
9
|
+
examples/example_log4r.xml
|
10
|
+
lib/ConsoleAppSupport.rb
|
11
|
+
lib/ConsoleAppHelper.rb
|
12
|
+
lib/ConsoleAppMixin.rb
|
13
|
+
test/test_consoleappsupport.rb
|
data/README.txt
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= consoleappsupport
|
2
|
+
http://rubyforge.org/projects/consolesupport/
|
3
|
+
|
4
|
+
== DESCRIPTION:
|
5
|
+
The ConsoleAppSupport module provides some commonly-desired behavior
|
6
|
+
for command-line programs. Its primary audience is Ruby coders
|
7
|
+
who need to frequently and quickly write special-purpose scripts
|
8
|
+
that are nevertheless flexible and self-documenting.
|
9
|
+
|
10
|
+
== FEATURES:
|
11
|
+
This module currently provides the following configuration services for
|
12
|
+
command-line applications:
|
13
|
+
* Determines configuration options for a program by parsing specially-formatted
|
14
|
+
comments in the main source file, similarly to RDoc.
|
15
|
+
* Loads values for these configuration options by parsing the command line.
|
16
|
+
* Loads further values from a run-time config file. As usual, command-line
|
17
|
+
options override config file options, which override defaults.
|
18
|
+
|
19
|
+
The module also provides the following logging services for command-line
|
20
|
+
applications:
|
21
|
+
* Provides a Log4r object with the default configuration, pointed to STDOUT.
|
22
|
+
* Automatically loads a Logr4 config file, if config option "--log4r-file" is
|
23
|
+
defined and enabled.
|
24
|
+
* Displays RDoc usage message if config option "--help" is defined and enabled.
|
25
|
+
|
26
|
+
== SYNOPSIS:
|
27
|
+
1. 'require consoleappsupport' from somewhere in your code.
|
28
|
+
2. Define your program's configuration options in the initial comment block.
|
29
|
+
(see below, and examples/console_app_example.rb for examples)
|
30
|
+
3. 'include ConsoleAppSupport::ConsoleAppMixin' in your main application class.
|
31
|
+
4. Call super in your program's initialize method.
|
32
|
+
5. Use @opts[:option_name] to access the final configuration.
|
33
|
+
6. Use @log.[debug,info,etc.] to send log messages.
|
34
|
+
7. Call read_configuration_files at any time to reload the both the application
|
35
|
+
config file and the Log4r configuration file.
|
36
|
+
|
37
|
+
== REQUIREMENTS:
|
38
|
+
log4j
|
39
|
+
log4r/configurator
|
40
|
+
optparse
|
41
|
+
rdoc/usage
|
42
|
+
ostruct
|
43
|
+
|
44
|
+
== INSTALL:
|
45
|
+
sudo gem consoleappsupport
|
46
|
+
|
47
|
+
== LICENSE:
|
48
|
+
(The MIT License)
|
49
|
+
|
50
|
+
Copyright (c) 2009 FIX
|
51
|
+
|
52
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
53
|
+
a copy of this software and associated documentation files (the
|
54
|
+
'Software'), to deal in the Software without restriction, including
|
55
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
56
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
57
|
+
permit persons to whom the Software is furnished to do so, subject to
|
58
|
+
the following conditions:
|
59
|
+
|
60
|
+
The above copyright notice and this permission notice shall be
|
61
|
+
included in all copies or substantial portions of the Software.
|
62
|
+
|
63
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
64
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
65
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
66
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
67
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
68
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
69
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Config file for convert_logs_to_csv.rb
|
2
|
+
# Use the format: key = value
|
3
|
+
# This pattern and field list are used for Apache "combined" log format
|
4
|
+
# See http://httpd.apache.org/docs/2.0/logs.html#combined
|
5
|
+
log-fields = client ip, identd, user, date, time, time zone, method, request, protocol, response code, bytes returned, referrer, user agent
|
6
|
+
log-pattern = ^(\S+)\s+(\S+)\s+(\S+)\s+\[([\w\/]+):([\d:]+)\s+(\S+)\]\s+"(\S+)\s+(\S+)\s+(\S+)"\s+(\S+)\s+(\S+)\s+"([^"]+)"\s+"([^"]+)"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
# Example application demonstrating the use of the ConsoleAppMixin.
|
5
|
+
# Prints all configuration info, then prints the command-line arguments.
|
6
|
+
#
|
7
|
+
# == Examples
|
8
|
+
# console_app_example.rb -h
|
9
|
+
# console_app_example.rb Show me the arguments
|
10
|
+
# console_app_example.rb -n 5 Show me the arguments
|
11
|
+
# console_app_example.rb -l debug Show me the arguments
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
# console_app_example.rb [options] argument1 arg2 etc...
|
15
|
+
#
|
16
|
+
# == Options (all options can be put into the config file)
|
17
|
+
# -n, --repeat-output [INTEGER] Number of times to echo back the arguments. default = 1
|
18
|
+
# -c, --config-file [FILE] Use config file [FILE]. default = console_app_example.conf
|
19
|
+
# -l, --log-level [LEVEL] Sets Log4r level for console output. default = INFO
|
20
|
+
# -r, --log4r-file [FILE] Optional Log4r config file. default = example_log4r.xml
|
21
|
+
# -h, --help Displays help message
|
22
|
+
#
|
23
|
+
# == Author
|
24
|
+
# Benton Roberts
|
25
|
+
|
26
|
+
require "consoleappsupport"
|
27
|
+
|
28
|
+
class ExampleConsoleApp
|
29
|
+
include ConsoleAppSupport::ConsoleAppMixin
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def run
|
36
|
+
@log.info "Application options: "+ @app_options.inspect
|
37
|
+
@log.info "Application defaults: "+ @default_options.inspect
|
38
|
+
@log.info "Config file options: "+ @configfile_options.inspect
|
39
|
+
@log.info "Command-line options: "+ @commandline_options.inspect
|
40
|
+
@log.info "Final run-time options: "+ @opts.inspect
|
41
|
+
1.upto(@opts[:repeat_output]) { @log.info ARGV.join(' ') }
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
myApp = ExampleConsoleApp.new
|
47
|
+
myApp.run
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
# An example application for the ConsoleAppSupport package.
|
5
|
+
# This program reads log lines from STDIN,
|
6
|
+
# and writes them to STDOUT as comma-separated-value lines.
|
7
|
+
# Log messages are written to STDERR.
|
8
|
+
#
|
9
|
+
# == Examples
|
10
|
+
# cat *.log | convert_logs_to_csv.rb -c apache_log_to_csv.conf > log_data.csv
|
11
|
+
# convert_syslogs_to_csv.rb -h
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
# cat [log files] | convert_logs_to_csv.rb [options] > [output file.csv]
|
15
|
+
#
|
16
|
+
# == Options (all options can be put into the config file)
|
17
|
+
# -p, --log-pattern [REGEX] Regular expression for matching log lines.
|
18
|
+
# -f, --log-fields [LIST] A list of field names to assign to the parenthesized log-pattern matches.
|
19
|
+
# -c, --config-file [FILE] Use config file [FILE], default = apache_log_to_csv.conf
|
20
|
+
# -l, --log-level [LEVEL] Sets log level to DEBUG, INFO, WARN, ERROR or FATAL. default = INFO
|
21
|
+
# -h, --help Displays help message
|
22
|
+
#
|
23
|
+
# == Author
|
24
|
+
# Benton Roberts
|
25
|
+
|
26
|
+
# First, load console app support, and log messages to STDERR
|
27
|
+
#require "#{File.dirname(__FILE__)}/../lib/ConsoleAppHelper.rb"
|
28
|
+
require "consoleappsupport"
|
29
|
+
helper = ConsoleAppSupport::ConsoleAppHelper.new('converter', true)
|
30
|
+
log = helper.log
|
31
|
+
log.outputters = Log4r::Outputter.stderr
|
32
|
+
# First, parse the command-line and read config the file
|
33
|
+
opts = helper.read_configuration_files
|
34
|
+
|
35
|
+
# Turn the "log_fields" run-time option into an array
|
36
|
+
log_fields = opts[:log_fields].split(',').map { |field| field.strip }
|
37
|
+
log.info "Searching for fields: #{log_fields.join ','}"
|
38
|
+
# Turn the "log_pattern" run-time option into an Regular Expression object
|
39
|
+
pattern = Regexp.new(opts[:log_pattern], Regexp::EXTENDED)
|
40
|
+
log.debug "Using pattern: #{pattern}"
|
41
|
+
########## BEGIN OUTPUT
|
42
|
+
puts log_fields.join(',') # Print the CSV header
|
43
|
+
# Now read through each line of standard input
|
44
|
+
lines = 0
|
45
|
+
while(line = STDIN.gets)
|
46
|
+
line.chomp
|
47
|
+
if (matches = pattern.match(line)) then
|
48
|
+
values = matches.to_a # Convert matches to array
|
49
|
+
values = values[1..values.size] # First element contains entire match
|
50
|
+
values = values.map do |value| # Escape values as necessary...
|
51
|
+
if value.include?('"') or value.include?(',') then
|
52
|
+
value.gsub!('"','\\"') # Escape quotation marks
|
53
|
+
value = "\"#{value}\"" # And quote the whole thing
|
54
|
+
end
|
55
|
+
value
|
56
|
+
end
|
57
|
+
puts values.join(',') # Print the values
|
58
|
+
lines += 1
|
59
|
+
else
|
60
|
+
log.warn "Unmatched line: #{line}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# Report on how we did
|
64
|
+
log.info "Done. Wrote #{lines} CSV data records."
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!-- Log Configuration -->
|
2
|
+
<log4r_config>
|
3
|
+
<pre_config>
|
4
|
+
<custom_levels>DEBUG, INFO, WARN, ERROR, FATAL</custom_levels>
|
5
|
+
<global level="ALL"/>
|
6
|
+
</pre_config>
|
7
|
+
|
8
|
+
<!-- Outputters -->
|
9
|
+
<outputter name="console" type="StdoutOutputter" level="DEBUG" >
|
10
|
+
<formatter type="Log4r::PatternFormatter">
|
11
|
+
<pattern>%5l: %M</pattern>
|
12
|
+
</formatter>
|
13
|
+
</outputter>
|
14
|
+
|
15
|
+
<!-- Loggers -->
|
16
|
+
<logger name="ExampleConsoleApp"
|
17
|
+
level="ALL" additive="false" trace="true">
|
18
|
+
<outputter>console</outputter>
|
19
|
+
</logger>
|
20
|
+
|
21
|
+
</log4r_config>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
# Helper class for the ConsoleAppSupport package.
|
5
|
+
#
|
6
|
+
# The ConsoleAppHelper provides the same services as
|
7
|
+
# ConsoleAppSupport::ConsoleAppMixin, but without affecting
|
8
|
+
# the local namespace.
|
9
|
+
#
|
10
|
+
# == Examples
|
11
|
+
# (see examples/convert_logs_to_csv.rb)
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
# * 'require consoleappsupport' from somewhere in your code.
|
15
|
+
# * Define your program's configuration options in the initial comment block.
|
16
|
+
# (see examples/convert_logs_to_csv.rb for examples)
|
17
|
+
# * Create a ConsoleAppSupport::ConsoleAppHelper in your program's initialize method.
|
18
|
+
# * Use helper.opts[:option_name] to access the final configuration.
|
19
|
+
# * Use helper.log.[debug,info,etc.] to send log messages.
|
20
|
+
# * Call helper.read_configuration_files at any time to reload the appliation and
|
21
|
+
# Log4r configuration files.
|
22
|
+
|
23
|
+
require "#{File.dirname(__FILE__)}/../lib/ConsoleAppMixin.rb"
|
24
|
+
|
25
|
+
module ConsoleAppSupport
|
26
|
+
class ConsoleAppHelper
|
27
|
+
include ConsoleAppSupport::ConsoleAppMixin
|
28
|
+
def initialize(*args)
|
29
|
+
super *args
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,325 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
# Main module for the ConsoleAppSupport package.
|
5
|
+
#
|
6
|
+
# The ConsoleAppMixin provides configuration and logging
|
7
|
+
# behavior for command-line applications:
|
8
|
+
# * Determines configuration options for a program by parsing the comments in the main source file.
|
9
|
+
# * Loads values for these configuration options by parsing a configuration file at run-time.
|
10
|
+
# * Overrides the configuration file values with any values passed on the command-line.
|
11
|
+
# * Provides a Log4r object with the default configuration, pointed to STDOUT.
|
12
|
+
# * Automatically loads a Logr4 config file, if config option "--log4r-file" is defined and enabled.
|
13
|
+
# * Displays RDoc usage message if config option "--help" is defined and enabled.
|
14
|
+
#
|
15
|
+
# == Examples
|
16
|
+
# (see examples/console_app_example.rb)
|
17
|
+
#
|
18
|
+
# == Usage
|
19
|
+
# * 'require consoleappsupport' from somewhere in your code.
|
20
|
+
# * Define your program's configuration options in the initial comment block.
|
21
|
+
# (see examples/console_app_example.rb for examples)
|
22
|
+
# * 'include ConsoleAppSupport::ConsoleAppMixin' in your main application class.
|
23
|
+
# * Call super in your program's initialize method.
|
24
|
+
# * Use @opts[:option_name] to access the final configuration.
|
25
|
+
# * Use @log.[debug,info,etc.] to send log messages.
|
26
|
+
# * Call read_configuration_files at any time to reload the appliation and
|
27
|
+
# Log4r configuration files.
|
28
|
+
|
29
|
+
module ConsoleAppSupport
|
30
|
+
|
31
|
+
module ConsoleAppMixin
|
32
|
+
require 'log4r'
|
33
|
+
require 'log4r/configurator'
|
34
|
+
require 'optparse'
|
35
|
+
require 'rdoc/usage'
|
36
|
+
require 'ostruct'
|
37
|
+
|
38
|
+
# An array of symbols representing the names of the
|
39
|
+
# application's possible configuration options.
|
40
|
+
attr_reader :app_options
|
41
|
+
# Hash containing the final configuration values, indexed by app_options
|
42
|
+
attr_reader :opts
|
43
|
+
# Hash of containing the default configuration values, indexed by app_options
|
44
|
+
attr_reader :default_options
|
45
|
+
# Hash containing the config file values, indexed by app_options
|
46
|
+
attr_reader :configfile_options
|
47
|
+
# Hash containing the command-line values, indexed by app_options
|
48
|
+
attr_reader :commandline_options
|
49
|
+
|
50
|
+
# A Log4r logger, initially pointed to STDOUT at level INITIAL_LOG_LEVEL
|
51
|
+
attr_reader :log
|
52
|
+
|
53
|
+
# Regexp used to read application options from the main source file
|
54
|
+
OPTIONS_LINE_EXPRESSION = %r{^\s*#\s*-([\w-]+)\s*,\s*--([\w-]+)\s*(\S.*)$}
|
55
|
+
# Regexp used to determine the Ruby type of each application option
|
56
|
+
OPTION_VALUE_EXPRESSION = %r{^\s*\[(\w+)\]}
|
57
|
+
# Regexp used to determine the default value of each application option
|
58
|
+
DEFAULT_VALUE_EXPRESSION = %r{default[^=]*=\s*(.*\S)\s*$}i
|
59
|
+
|
60
|
+
# Predefined names for application options
|
61
|
+
# that trigger this module's specialized behavior:
|
62
|
+
# * :help - Prints usage and exits
|
63
|
+
# * :config_file - Selects a config file for more options
|
64
|
+
# * :log_level - Sets the STDOUT logging level
|
65
|
+
# * :log4r_file - Loads a Log4r config file
|
66
|
+
SPECIAL_OPTIONS = {
|
67
|
+
:help => "help",
|
68
|
+
:config_file => "config_file",
|
69
|
+
:log_level => "log_level",
|
70
|
+
:log4r_file => "log4r_file",
|
71
|
+
}
|
72
|
+
|
73
|
+
# Logging level during module initilization.
|
74
|
+
# Redefine this to DEBUG before calling super if you
|
75
|
+
# need to trace parsing of the main application source file.
|
76
|
+
INITIAL_LOG_LEVEL = 'INFO'
|
77
|
+
|
78
|
+
# Parses the top-level source file for application configuration options.
|
79
|
+
# Unless skip_config is true, read_configuration_files is then called.
|
80
|
+
def initialize(logger_name = self.class.name, skip_config = false)
|
81
|
+
@app_options = []
|
82
|
+
@opts = @configfile_options = {}
|
83
|
+
initialize_logging logger_name
|
84
|
+
populate_app_options
|
85
|
+
setup_default_options
|
86
|
+
parse_command_line
|
87
|
+
read_configuration_files unless skip_config
|
88
|
+
end
|
89
|
+
|
90
|
+
# Reads the application config file for configuration options, then
|
91
|
+
# loads the Log4r config file (as directed by :log4r_file option).
|
92
|
+
# Returns @opts, the final runtime_options hash.
|
93
|
+
def read_configuration_files
|
94
|
+
config_file = get_config_file_name
|
95
|
+
load_config_file(config_file) if config_file_exists? config_file
|
96
|
+
@log.debug "Config file options loaded: #{@configfile_options.inspect}"
|
97
|
+
@opts = @default_options.merge(@configfile_options.merge(@commandline_options))
|
98
|
+
@log.debug "Final run-time options: #{@opts.inspect}"
|
99
|
+
load_log4r_config_file
|
100
|
+
@opts
|
101
|
+
end
|
102
|
+
|
103
|
+
#########################################################
|
104
|
+
private # methods
|
105
|
+
|
106
|
+
def initialize_logging(logger_name)
|
107
|
+
@log = Log4r::Logger.new logger_name
|
108
|
+
@log.outputters = Log4r::Outputter.stdout
|
109
|
+
@log.level = Log4r::INFO
|
110
|
+
@opts = { SPECIAL_OPTIONS[:log_level] => @log.level }
|
111
|
+
set_log_level INITIAL_LOG_LEVEL
|
112
|
+
end
|
113
|
+
|
114
|
+
# Populates the instance variable @_app_options, based on the
|
115
|
+
# comments in the main application file
|
116
|
+
def populate_app_options
|
117
|
+
@_app_options = {}
|
118
|
+
@log.debug "Reading comments from main application file #{$0}"
|
119
|
+
main_file = File.new($0, "r")
|
120
|
+
while (line = main_file.gets)
|
121
|
+
if (matches = OPTIONS_LINE_EXPRESSION.match line.chomp) then
|
122
|
+
switch, param, description = matches.captures
|
123
|
+
@log.debug "Found application parameter #{param} with switch #{switch}"
|
124
|
+
new_app_option = {:switch => switch, :help => description}
|
125
|
+
if (OPTION_VALUE_EXPRESSION.match description) then
|
126
|
+
@log.debug "This parameter accepts a value of type #{$1}"
|
127
|
+
new_app_option[:type] = $1
|
128
|
+
if (DEFAULT_VALUE_EXPRESSION.match description) then
|
129
|
+
@log.debug "This parameter defaults to '#{$1}'"
|
130
|
+
new_app_option[:default] = convert_string($1, new_app_option[:type])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
@_app_options[param] = new_app_option
|
134
|
+
end
|
135
|
+
end
|
136
|
+
main_file.close
|
137
|
+
@app_options = @_app_options.keys.sort.map { |option| option.gsub('-','_').intern}
|
138
|
+
@log.debug "Application options: #{@app_options.inspect}"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Creates a hash of default option values
|
142
|
+
def setup_default_options
|
143
|
+
@default_options = {}
|
144
|
+
@_app_options.each do |parameter, details|
|
145
|
+
switch = "-#{details[:switch]}"
|
146
|
+
param_string = "--#{parameter}"
|
147
|
+
param_string += " [#{details[:type]}]" if details[:type]
|
148
|
+
if details[:default] then
|
149
|
+
param_key = parameter.gsub('-','_')
|
150
|
+
value = convert_string(details[:default], details[:type])
|
151
|
+
# TODO: convert value to desired type
|
152
|
+
@default_options[param_key.intern] = value
|
153
|
+
set_log_level(value) if param_key == SPECIAL_OPTIONS[:log_level]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
@log.debug "Application defaults: #{@default_options.inspect}"
|
157
|
+
end
|
158
|
+
|
159
|
+
# Populates the instance variable @cmdline_opts based on the
|
160
|
+
# command-line supplied at run-time
|
161
|
+
def parse_command_line
|
162
|
+
@commandline_options = {}
|
163
|
+
opts = OptionParser.new
|
164
|
+
@_app_options.each do |parameter, details|
|
165
|
+
switch = "-#{details[:switch]}"
|
166
|
+
param_string = "--#{parameter}"
|
167
|
+
param_string += " [#{details[:type]}]" if details[:type]
|
168
|
+
opts.on(switch, param_string) do |value|
|
169
|
+
set_cmdline_opt(parameter, value, details[:type])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
begin
|
173
|
+
opts.parse!(ARGV)
|
174
|
+
rescue => e
|
175
|
+
@log.fatal "Error parsing command-line parameters: #{e}"
|
176
|
+
exit 1
|
177
|
+
end
|
178
|
+
@log.debug "Command-line parameters passed: #{@commandline_options.inspect}"
|
179
|
+
end
|
180
|
+
|
181
|
+
# Stores an individual command-line option in @cmdline_opts
|
182
|
+
def set_cmdline_opt(parameter, value, type = nil)
|
183
|
+
value = convert_string(value, type) # Convert to type
|
184
|
+
param_key = parameter.gsub('-','_')
|
185
|
+
@commandline_options[param_key.intern] = value
|
186
|
+
# Handle special options...
|
187
|
+
set_log_level(value) if param_key == SPECIAL_OPTIONS[:log_level]
|
188
|
+
output_help if param_key == SPECIAL_OPTIONS[:help]
|
189
|
+
@log.debug "Found command-line parameter: #{parameter} (#{value})"
|
190
|
+
end
|
191
|
+
|
192
|
+
# Returns the final path to the config file
|
193
|
+
def get_config_file_name
|
194
|
+
cfg_path = nil
|
195
|
+
config_param = SPECIAL_OPTIONS[:config_file]
|
196
|
+
param_key = config_param.gsub('-','_').intern
|
197
|
+
if @commandline_options.has_key? param_key then
|
198
|
+
cfg_path = @commandline_options[param_key]
|
199
|
+
else
|
200
|
+
cfg_path = @default_options[param_key]
|
201
|
+
end
|
202
|
+
cfg_path
|
203
|
+
end
|
204
|
+
|
205
|
+
# Returns true if cfg_path exists in the filesystem, false or nil otherwise
|
206
|
+
def config_file_exists?(cfg_path)
|
207
|
+
file_exists = nil
|
208
|
+
if cfg_path then
|
209
|
+
@log.debug "Checking for config file #{cfg_path}..."
|
210
|
+
if File.exists? cfg_path then
|
211
|
+
file_exists = true
|
212
|
+
else
|
213
|
+
file_exists = false
|
214
|
+
error_msg = "Configuration file #{cfg_path} does not exist."
|
215
|
+
param_key = SPECIAL_OPTIONS[:config_file].gsub('-','_').intern
|
216
|
+
if @commandline_options[param_key] then
|
217
|
+
@log.fatal "#{error_msg} Terminating."
|
218
|
+
exit 2
|
219
|
+
else
|
220
|
+
@log.info "#{error_msg} Skipping..."
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
file_exists
|
225
|
+
end
|
226
|
+
|
227
|
+
# Parses the file at cfg_path, and populates @configfile_options with results
|
228
|
+
def load_config_file(cfg_path)
|
229
|
+
# Open and read in config file
|
230
|
+
@log.info "Loading configuration file #{cfg_path}..."
|
231
|
+
cfg_file = File.new(cfg_path,'r')
|
232
|
+
begin
|
233
|
+
while (line = cfg_file.gets)
|
234
|
+
if line =~ /^\s*([^\s#]+)\s*=\s*(.+)$/
|
235
|
+
key = $1 ; value = $2
|
236
|
+
@log.debug "Read config file parameter '#{key}' with value: #{value}"
|
237
|
+
if not @app_options.include? key.gsub('-','_').intern then
|
238
|
+
@log.fatal "Unrecognized application option '#{key}'"
|
239
|
+
exit 4
|
240
|
+
end
|
241
|
+
value = convert_string(value, @_app_options[key][:type])
|
242
|
+
@configfile_options[key.gsub('-','_').intern] = value
|
243
|
+
# Handle special options
|
244
|
+
set_log_level value if key.gsub('-','_') == SPECIAL_OPTIONS[:log_level]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
rescue => error
|
248
|
+
@log.fatal "Could not read config file #{cfg_file}: #{error}"
|
249
|
+
exit 3
|
250
|
+
ensure
|
251
|
+
cfg_file.close
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Loads the Log4r config file, if it exists.
|
256
|
+
# Otherwise, exits the program if a log4r file was specified by the user
|
257
|
+
def load_log4r_config_file
|
258
|
+
log4r_key = SPECIAL_OPTIONS[:log4r_file].gsub('-','_').intern
|
259
|
+
if cfg_path = @opts[log4r_key]
|
260
|
+
if not File.exists? cfg_path then
|
261
|
+
error_msg = "Log4r configuration file #{cfg_path} does not exist."
|
262
|
+
if cfg_path != @default_options[log4r_key] then
|
263
|
+
@log.fatal "#{error_msg} Terminating."
|
264
|
+
exit 2
|
265
|
+
else
|
266
|
+
@log.info "#{error_msg} Skipping..."
|
267
|
+
end
|
268
|
+
else
|
269
|
+
@log.info "Loading Log4r config file #{cfg_path}..."
|
270
|
+
log_name = @log.name
|
271
|
+
Log4r::Configurator.load_xml_file cfg_path
|
272
|
+
@log = Log4r::Logger[log_name]
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
#########################################################
|
278
|
+
# Utility methods
|
279
|
+
|
280
|
+
def set_log_level(log_level)
|
281
|
+
log_level.upcase!
|
282
|
+
log4r_levels = {
|
283
|
+
"DEBUG" => Log4r::DEBUG,
|
284
|
+
"INFO" => Log4r::INFO,
|
285
|
+
"WARN" => Log4r::WARN,
|
286
|
+
"ERROR" => Log4r::ERROR,
|
287
|
+
"FATAL" => Log4r::FATAL
|
288
|
+
}
|
289
|
+
current_level = @opts[SPECIAL_OPTIONS[:log_level]]
|
290
|
+
desired_level = log4r_levels[log_level]
|
291
|
+
if (! desired_level) then
|
292
|
+
@log.warn "Undefinded log level '#{log_level}' - keeping #{current_level}"
|
293
|
+
else
|
294
|
+
@opts[SPECIAL_OPTIONS[:log_level]] = log_level
|
295
|
+
if @log.level != desired_level then
|
296
|
+
@log.info "Changing application logging level to #{log_level}"
|
297
|
+
@log.level = desired_level
|
298
|
+
@opts[SPECIAL_OPTIONS[:log_level]] = @log.level
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# Converts a string to a numeric of a specified type
|
304
|
+
def convert_string(value, type)
|
305
|
+
if type then
|
306
|
+
case type.downcase
|
307
|
+
when 'integer'
|
308
|
+
value = value.to_i
|
309
|
+
when 'float'
|
310
|
+
value = value.to_f
|
311
|
+
end
|
312
|
+
end
|
313
|
+
value
|
314
|
+
end
|
315
|
+
|
316
|
+
def output_help
|
317
|
+
RDoc::usage() #exits app
|
318
|
+
end
|
319
|
+
|
320
|
+
def output_usage
|
321
|
+
RDoc::usage('usage') # gets usage from top-level file comments
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
# Wrapper file for the ConsoleAppSupport package.
|
5
|
+
# All of this package's functionality is currently in ConsoleAppSupport::ConsoleAppMixin
|
6
|
+
# See that module's documentation for usage.
|
7
|
+
|
8
|
+
module ConsoleAppSupport
|
9
|
+
VERSION = '0.5.0'
|
10
|
+
end
|
11
|
+
|
12
|
+
require "#{File.dirname(__FILE__)}/ConsoleAppHelper.rb"
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: consoleappsupport
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- benton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-08 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
|
+
version:
|
25
|
+
description: |-
|
26
|
+
The ConsoleAppSupport module provides some commonly-desired behavior
|
27
|
+
for command-line programs. Its primary audience is Ruby coders
|
28
|
+
who need to frequently and quickly write special-purpose scripts
|
29
|
+
that are nevertheless flexible and self-documenting.
|
30
|
+
email:
|
31
|
+
- bentonroberts@me.com
|
32
|
+
executables: []
|
33
|
+
|
34
|
+
extensions: []
|
35
|
+
|
36
|
+
extra_rdoc_files:
|
37
|
+
- History.txt
|
38
|
+
- Manifest.txt
|
39
|
+
- README.txt
|
40
|
+
files:
|
41
|
+
- History.txt
|
42
|
+
- Manifest.txt
|
43
|
+
- README.txt
|
44
|
+
- Rakefile
|
45
|
+
- examples/apache_log_to_csv.conf
|
46
|
+
- examples/console_app_example.conf
|
47
|
+
- examples/console_app_example.rb
|
48
|
+
- examples/convert_logs_to_csv.rb
|
49
|
+
- examples/example_log4r.xml
|
50
|
+
- lib/ConsoleAppSupport.rb
|
51
|
+
- lib/ConsoleAppHelper.rb
|
52
|
+
- lib/ConsoleAppMixin.rb
|
53
|
+
- test/test_consoleappsupport.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://rubyforge.org/projects/consolesupport/
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options:
|
60
|
+
- --main
|
61
|
+
- README.txt
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: consolesupport
|
79
|
+
rubygems_version: 1.3.4
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: The ConsoleAppSupport module provides some commonly-desired behavior for command-line programs
|
83
|
+
test_files:
|
84
|
+
- test/test_consoleappsupport.rb
|