consoleappsupport 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|