easy_app_helper 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +47 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +57 -0
- data/Rakefile +1 -0
- data/easy_app_helper.gemspec +26 -0
- data/lib/easy_app_helper/base.rb +211 -0
- data/lib/easy_app_helper/common.rb +87 -0
- data/lib/easy_app_helper/config.rb +137 -0
- data/lib/easy_app_helper/logger.rb +99 -0
- data/lib/easy_app_helper/version.rb +10 -0
- data/lib/easy_app_helper.rb +24 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 030db560ddded5c43b3a7a05d0c50b93a701063c
|
4
|
+
data.tar.gz: 99d2e5c614f4837aa5057f7f429b01eb51956f84
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa9f1af598819d3ccfbc442728ae981d67a37b52aa6a562094566dc2797e865badea91628e6671ebdde0ab7f56c3a5ec7e1719261f9c92272300acd12ff7022d
|
7
|
+
data.tar.gz: 17d17a90a5be2f62125556cc283d719be7e583bda0980c72215022aeb376aee8105496cd12543c9b5ceac92d1ab96f65d02535fddd617f031364580cae466de8
|
data/.gitignore
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
# Standard
|
19
|
+
*~
|
20
|
+
# Standard Rails project
|
21
|
+
/tmp/
|
22
|
+
/log/
|
23
|
+
/db/*.sqlite3
|
24
|
+
# SASS CSS generation
|
25
|
+
/public/stylesheets/.sass-cache/
|
26
|
+
# Netbeans
|
27
|
+
/nbproject/
|
28
|
+
# Sublime Text 2 project
|
29
|
+
*.sublime-project
|
30
|
+
*.sublime-workspace
|
31
|
+
*(copie)*
|
32
|
+
# RVM
|
33
|
+
.rvmrc
|
34
|
+
# VisualRuby
|
35
|
+
.vr_settings.yaml
|
36
|
+
# Emacs
|
37
|
+
*#
|
38
|
+
*\#
|
39
|
+
\#*
|
40
|
+
.#*
|
41
|
+
\#*\#
|
42
|
+
# Geany
|
43
|
+
*.geany
|
44
|
+
# RubyMine
|
45
|
+
.idea
|
46
|
+
#RedCar
|
47
|
+
.redcar
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# EasyAppHelper
|
2
|
+
|
3
|
+
This gem provides a suite of helpers for command line applications.
|
4
|
+
The goal is to be as transparent as possible for application whilst providing consistent helpers that add dedidacted behaviours to your application.
|
5
|
+
|
6
|
+
Currently the only dependency is on "slop" (https://rubygems.org/gems/slop).
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'easy_app_helper'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install easy_app_helper
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
To benefit from the different helpers. Once you installed the gem, the only thing you need to do is:
|
27
|
+
|
28
|
+
require 'easy_app_helper'
|
29
|
+
|
30
|
+
and then in the "main class" of your application, include the modules you want to use and call init_app_helper in the initialize method. Then what you can do with each
|
31
|
+
module is defined by each module.
|
32
|
+
|
33
|
+
The basic behaviour (when you include EasyAppHelper), actually adds basic command line handling (actually handled by slop), and provides the mechanism to enable you
|
34
|
+
to add any other EasyAppHelper module.
|
35
|
+
|
36
|
+
ex:
|
37
|
+
|
38
|
+
require 'easy_app_helper'
|
39
|
+
|
40
|
+
class MyApp
|
41
|
+
include EasyAppHelper
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
init_app_helper "my_app"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
This basically does... nothing.
|
49
|
+
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'easy_app_helper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "easy_app_helper"
|
8
|
+
spec.version = EasyAppHelper::VERSION
|
9
|
+
spec.authors = ["L.Briais"]
|
10
|
+
spec.email = ["lbnetid+rb@gmail.com"]
|
11
|
+
spec.description = %q{Desktop application framework}
|
12
|
+
spec.summary = %q{Provides cool helpers to your desktop application, including configuration and logging features}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "pry"
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "slop"
|
26
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require 'slop'
|
9
|
+
|
10
|
+
# Once this module is included in your class which may be in the "application class",
|
11
|
+
# you probably want to call the init_app_helper method as first statement of your
|
12
|
+
# initialize method.
|
13
|
+
#
|
14
|
+
# This module provides some basic command line options ({using the slop gem}[https://rubygems.org/gems/slop])
|
15
|
+
# and
|
16
|
+
# initializes all included EasyAppHelper modules (which may themselves add their
|
17
|
+
# own command line options). Calling the init_app_helper method is the only thing
|
18
|
+
# required to instanciate the whole framework.
|
19
|
+
#
|
20
|
+
# You can access to any command line option value through the app_config hash attribute.
|
21
|
+
#
|
22
|
+
# If you want to add any extra command line option to the one provided by default
|
23
|
+
# by this module or by any other EasyAppHelper modules, then your class just needs
|
24
|
+
# to respond to add_specifc_command_line_options(opt).
|
25
|
+
# The opt object is a Slop object that enables to define any extra command line
|
26
|
+
# options.
|
27
|
+
#
|
28
|
+
# Passing the --help option to the program will cause this module to display the
|
29
|
+
# inline help and to exit.
|
30
|
+
module EasyAppHelper::Base
|
31
|
+
|
32
|
+
include EasyAppHelper::Common
|
33
|
+
|
34
|
+
|
35
|
+
@app_config = {}
|
36
|
+
|
37
|
+
# Gives access to the application config. This should be the only attribute you will
|
38
|
+
# use once this module is fully configured.
|
39
|
+
attr_accessor :app_config
|
40
|
+
|
41
|
+
# Gives access to the initial command line options. Just for information as already
|
42
|
+
# merged into the app_config.
|
43
|
+
def app_cmd_line_options
|
44
|
+
@slop_definition.nil? ? {} : @slop_definition.to_hash
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method initializes the whole EasyAppHelper helpers framework.
|
48
|
+
# Even if only the first parameter is mandatory, you may pass all of them if you want
|
49
|
+
# consistent inline help to be displayed.
|
50
|
+
def init_app_helper(script_filename,
|
51
|
+
app_name="Undefined application name",
|
52
|
+
app_description="No description available",
|
53
|
+
app_version="unknown")
|
54
|
+
# A brand new config is created.
|
55
|
+
@app_config = {}
|
56
|
+
# Initialize default options, and creates @slop_definition.
|
57
|
+
build_default_command_line_options script_filename, app_name, app_description, app_version
|
58
|
+
# Process all actions on EasyAppHelper modules that change app_config or add command
|
59
|
+
# line options.
|
60
|
+
process_helpers_instanciators script_filename, app_name, app_description, app_version
|
61
|
+
# Provides possibility to the script writer to add its own command line options
|
62
|
+
add_script_specific_cmd_line_options
|
63
|
+
# Parses command line options, and merges with the app_config
|
64
|
+
merge_cmd_line_options_into_config
|
65
|
+
# Performs modules entry points
|
66
|
+
process_helpers_post_config_actions
|
67
|
+
# check if help is requested.
|
68
|
+
check_help_option_invoked
|
69
|
+
# Log useful debug info
|
70
|
+
log_debug_info
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
# Returns the text of the inline help. Generated by Slop.
|
76
|
+
def help
|
77
|
+
@slop_definition.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
# Provides access to a standard logger, fully configured according to command line options
|
81
|
+
# or config files.
|
82
|
+
def logger
|
83
|
+
return @logger unless @logger.nil?
|
84
|
+
return EasyAppHelper::Common::DummyLogger.instance
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
################################################################################
|
89
|
+
private
|
90
|
+
|
91
|
+
# Checks EasyAppHelper modules and perform some actions on them.
|
92
|
+
# - Does it add some command line options? Then add them by calling add_cmd_line_options
|
93
|
+
# - Does it modify app_config? Then call provides_config.
|
94
|
+
def process_helpers_instanciators(script_filename, app_name, app_description, app_version)
|
95
|
+
begin
|
96
|
+
if (ENV['DEBUG_EASY_MODULES'])
|
97
|
+
@logger = Logger.new(STDOUT)
|
98
|
+
@logger.level = Logger::Severity::DEBUG
|
99
|
+
end
|
100
|
+
process_helper_modules_instanciators do |mod|
|
101
|
+
# Command line: Does the module add some command line options ?
|
102
|
+
if mod.respond_to? :add_cmd_line_options
|
103
|
+
mod.add_cmd_line_options self, @slop_definition
|
104
|
+
end
|
105
|
+
# Does the module modify the global configuration
|
106
|
+
if mod.respond_to? :provides_config
|
107
|
+
module_config = mod.provides_config self, script_filename, app_name, app_description, app_version
|
108
|
+
@app_config = EasyAppHelper::Common.override_config app_config, module_config
|
109
|
+
end
|
110
|
+
end
|
111
|
+
ensure
|
112
|
+
unless @logger.nil?
|
113
|
+
@logger = nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Call each post config action for modules if any.
|
119
|
+
def process_helpers_post_config_actions
|
120
|
+
process_helper_modules_instanciators do |mod|
|
121
|
+
if mod.respond_to? :post_config_action
|
122
|
+
mod.post_config_action self
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
# Utility method to process EasyAppHelper modules in order of priority.
|
132
|
+
def process_helper_modules_instanciators
|
133
|
+
self.class.included_modules
|
134
|
+
.map {|mod| mod if mod.name =~ /^EasyAppHelper::/}
|
135
|
+
.compact
|
136
|
+
.map {|mod| mod::Instanciator}
|
137
|
+
.sort {|a,b| a::MODULE_PRIORITY <=> b::MODULE_PRIORITY }
|
138
|
+
.each {|mod| logger.debug "Processing helper module: #{mod.name}"; yield mod}
|
139
|
+
end
|
140
|
+
|
141
|
+
def merge_cmd_line_options_into_config
|
142
|
+
@slop_definition.parse!
|
143
|
+
@app_config = EasyAppHelper::Common.override_config app_config, @slop_definition.to_hash
|
144
|
+
end
|
145
|
+
|
146
|
+
# Builds common used command line options
|
147
|
+
def build_default_command_line_options(script_filename, app_name, app_description, app_version)
|
148
|
+
# Default options
|
149
|
+
@slop_definition = Slop.new do
|
150
|
+
banner "\nUsage: #{script_filename} [options]\n#{app_name} Version: #{app_version}\n\n#{app_description}"
|
151
|
+
separator "-- Generic options -------------------------------------------"
|
152
|
+
on :auto, 'Auto mode. Bypasses questions to user.', :argument => false
|
153
|
+
on :simulate, 'Do not perform the actual underlying actions.', :argument => false
|
154
|
+
on :v, :verbose, 'Enable verbose mode.', :argument => false
|
155
|
+
on :h, :help, 'Displays this help.', :argument => false
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Hook for the script to add its own command line options
|
160
|
+
#
|
161
|
+
# Just need to implement a add_specifc_command_line_options method that tal=ke a slop object as parameter
|
162
|
+
def add_script_specific_cmd_line_options
|
163
|
+
if self.respond_to? :add_specifc_command_line_options
|
164
|
+
@slop_definition.separator "\n-- Script specific options------------------------------------"
|
165
|
+
self.add_specifc_command_line_options @slop_definition
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Check if the help command line option has been passed and if the case,
|
170
|
+
# display the inline help and exits the program.
|
171
|
+
def check_help_option_invoked
|
172
|
+
return unless app_config[:help]
|
173
|
+
puts self.help
|
174
|
+
exit 0
|
175
|
+
end
|
176
|
+
|
177
|
+
# Displays useful debug info after all EasyAppHelper modules initialization.
|
178
|
+
def log_debug_info
|
179
|
+
return unless app_config[:debug] || app_config[:'debug-on-err']
|
180
|
+
size = ENV.keys.map {|k| k.length }.max + 1
|
181
|
+
logger.debug '-' * 80
|
182
|
+
logger.debug " Script environment variables"
|
183
|
+
logger.debug '-' * 80
|
184
|
+
# print formatted environment
|
185
|
+
ENV.sort.each {|k,v| logger.debug "- %-#{size}s %s" % ["#{k}:", v] }
|
186
|
+
logger.debug '-' * 80
|
187
|
+
logger.debug " Script Ruby load path"
|
188
|
+
logger.debug '-' * 80
|
189
|
+
$:.each {|p| logger.debug p}
|
190
|
+
logger.debug '-' * 80
|
191
|
+
logger.debug " Script command line parameters"
|
192
|
+
logger.debug '-' * 80
|
193
|
+
size = app_cmd_line_options.to_hash.keys.map {|k| k.length }.max + 1
|
194
|
+
app_cmd_line_options.to_hash.sort.each {|k,v| logger.debug "- %-#{size}s %s" % ["#{k}:", v] }
|
195
|
+
logger.debug '-' * 80
|
196
|
+
logger.debug " Script global configuration"
|
197
|
+
logger.debug '-' * 80
|
198
|
+
logger.debug "\n" + app_config.to_yaml
|
199
|
+
logger.debug '-' * 80
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
module EasyAppHelper::Base::Instanciator
|
206
|
+
extend EasyAppHelper::Common::Instanciator
|
207
|
+
|
208
|
+
# Default module priority
|
209
|
+
MODULE_PRIORITY = 10
|
210
|
+
|
211
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require 'singleton'
|
9
|
+
require 'logger'
|
10
|
+
|
11
|
+
##
|
12
|
+
# This contains very basic default values and methods.
|
13
|
+
#
|
14
|
+
module EasyAppHelper::Common
|
15
|
+
# Default log-level
|
16
|
+
DEFAULT_LOG_LEVEL = Logger::Severity::WARN
|
17
|
+
|
18
|
+
def self.override_config(h1, h2)
|
19
|
+
EasyAppHelper::Common::HashesMergePolicies.merge_hashes_second_level h1, h2
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# Ancestor of all module instanciators.
|
26
|
+
module EasyAppHelper::Common::Instanciator
|
27
|
+
# Default module priority
|
28
|
+
MODULE_PRIORITY = 10000
|
29
|
+
|
30
|
+
def self.add_cmd_line_options(app, opt)
|
31
|
+
# Does nothing
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.provides_config(app, script_filename, app_name, app_description, app_version)
|
35
|
+
# Does nothing
|
36
|
+
{}
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.post_config_action(app)
|
40
|
+
# Does nothing
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
# This guy will never log something anywhere... :)
|
49
|
+
# It mays be used as the logger until someone replaces by a real one
|
50
|
+
# EasyAppHelper::Logger would do that efficiently
|
51
|
+
class EasyAppHelper::Common::DummyLogger
|
52
|
+
include Singleton
|
53
|
+
def method_missing(method_name, *args, &block)
|
54
|
+
# Do nothing !
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Implements different merge policies for the configs.
|
59
|
+
module EasyAppHelper::Common::HashesMergePolicies
|
60
|
+
# Performs a merge at the second level of hashes.
|
61
|
+
# simple entries and arrays are overriden.
|
62
|
+
def self.merge_hashes_second_level(h1, h2)
|
63
|
+
h2.each do |key, v|
|
64
|
+
if h1[key] and h1[key].is_a?(Hash)
|
65
|
+
# Merges hashes
|
66
|
+
h1[key].merge! h2[key]
|
67
|
+
else
|
68
|
+
# Overrides the rest
|
69
|
+
h1[key] = h2[key] unless h2[key].nil?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
h1
|
73
|
+
end
|
74
|
+
|
75
|
+
# Uses the standard "merge!" method
|
76
|
+
def self.simple_merge(h1, h2)
|
77
|
+
h1.merge! h2
|
78
|
+
end
|
79
|
+
|
80
|
+
# Brutal override
|
81
|
+
def self.complete_override(h1, h2)
|
82
|
+
h1 = nil
|
83
|
+
h1 = h2
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
# Config file format
|
9
|
+
require 'yaml'
|
10
|
+
|
11
|
+
# This module defines:
|
12
|
+
# - Some basic command line options(see --help), with their underlying
|
13
|
+
# mechanism.
|
14
|
+
# - A mechanism (based on Slop) to add your own command line options.
|
15
|
+
# - A generated inline help.
|
16
|
+
# This module provides the following 5 levels of configuration:
|
17
|
+
# - Admin wide YAML config file, for options common to all your EasyAppHelper applications
|
18
|
+
# - System wide YAML config file.
|
19
|
+
# - User YAML config file.
|
20
|
+
# - Command line options.
|
21
|
+
# - Command line supplied YAML config file(any option defined here will override the previous).
|
22
|
+
# All these 5 levels of configuration override with consistent override mechanism.
|
23
|
+
# Config files are in YAML but can have different extensions.
|
24
|
+
module EasyAppHelper::Config
|
25
|
+
|
26
|
+
include EasyAppHelper::Common
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
# If the option --config-file has been specified, it will be loaded and override
|
31
|
+
# current configuration according to rules
|
32
|
+
def load_custom_config
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
module EasyAppHelper::Config::Instanciator
|
40
|
+
extend EasyAppHelper::Common::Instanciator
|
41
|
+
|
42
|
+
# Default module priority
|
43
|
+
MODULE_PRIORITY = 10
|
44
|
+
|
45
|
+
# Where could be stored admin configuration that rules all EasyAppHelper
|
46
|
+
# based applications.
|
47
|
+
ADMIN_CONFIG_POSSIBLE_PLACES = ["/etc"]
|
48
|
+
ADMIN_CONFIG_FILENAME = EasyAppHelper.name
|
49
|
+
|
50
|
+
# Where could be stored system wide configuration
|
51
|
+
SYSTEM_CONFIG_POSSIBLE_PLACES = ["/etc",
|
52
|
+
"/usr/local/etc"]
|
53
|
+
|
54
|
+
# Where could be stored user configuration
|
55
|
+
USER_CONFIG_POSSIBLE_PLACES = ["#{ENV['HOME']}/.config"]
|
56
|
+
|
57
|
+
# Potential extensions a config file can have
|
58
|
+
CONFIG_FILE_POSSIBLE_EXTENSIONS = ['conf', 'yml', 'cfg', 'yaml', 'CFG', 'YML', 'YAML', 'Yaml']
|
59
|
+
|
60
|
+
# Adds a command line options for this module.
|
61
|
+
# - +--config-file+ +filename+ To specify a config file from the command line.
|
62
|
+
def self.add_cmd_line_options(app, slop_definition)
|
63
|
+
slop_definition.separator "\n-- Configuration options -------------------------------------"
|
64
|
+
slop_definition.on 'config-file', 'Specify a config file.', :argument => true
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# Loads the configuration files (admin, system, user).
|
69
|
+
#
|
70
|
+
# Config files may define any type of structure supported by YAML.
|
71
|
+
# The override policy is that, if an entry in the config is a hash and the next
|
72
|
+
# level defines the same hash, they are merged.
|
73
|
+
# For any other type (scalar, array), the overrider... overrides ;)
|
74
|
+
#
|
75
|
+
# Config files can be at different places and have different extensions (see
|
76
|
+
# CONFIG_FILE_POSSIBLE_EXTENSIONS). They have the same base name as the script_filename.
|
77
|
+
def self.provides_config(app, script_filename, app_name, app_description, app_version)
|
78
|
+
config = load_admin_wide_config app
|
79
|
+
config = EasyAppHelper::Common.override_config config, load_system_wide_config(app, script_filename)
|
80
|
+
EasyAppHelper::Common.override_config config, load_user_config(app, script_filename)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.post_config_action(app)
|
84
|
+
return unless app.app_config[:'config-file']
|
85
|
+
begin
|
86
|
+
app.app_config = EasyAppHelper::Common.override_config app.app_config, load_config_file(app, app.app_config[:'config-file'])
|
87
|
+
rescue => e
|
88
|
+
app.logger.error "Problem with \"#{app.app_config[:'config-file']}\" config file!\n#{e.message}\nIgnoring..."
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
################################################################################
|
93
|
+
private
|
94
|
+
|
95
|
+
# Reads config from admin config file.
|
96
|
+
def self.load_admin_wide_config(app)
|
97
|
+
load_config_file app, find_file(ADMIN_CONFIG_POSSIBLE_PLACES, ADMIN_CONFIG_FILENAME)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reads config from system config file.
|
101
|
+
def self.load_system_wide_config(app, script_filename)
|
102
|
+
load_config_file app, find_file(SYSTEM_CONFIG_POSSIBLE_PLACES, script_filename)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Reads config from user config file.
|
106
|
+
def self.load_user_config(app, script_filename)
|
107
|
+
load_config_file app, find_file(USER_CONFIG_POSSIBLE_PLACES, script_filename)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Loads a config file.
|
111
|
+
def self.load_config_file(app, conf_filename)
|
112
|
+
conf = {}
|
113
|
+
return conf if conf_filename.nil?
|
114
|
+
# A file exists
|
115
|
+
begin
|
116
|
+
app.logger.debug "Loading config file \"#{conf_filename}\""
|
117
|
+
conf = Hash[YAML::load(open(conf_filename)).map { |k, v| [k.to_sym, v] }]
|
118
|
+
rescue => e
|
119
|
+
app.logger.error "Invalid config file \"#{conf_filename}\". Not respecting YAML syntax!\n#{e.message}"
|
120
|
+
end
|
121
|
+
conf
|
122
|
+
end
|
123
|
+
|
124
|
+
# Tries to find config files according to places (array) given and possible extensions
|
125
|
+
def self.find_file(places, filename)
|
126
|
+
places.each do |dir|
|
127
|
+
CONFIG_FILE_POSSIBLE_EXTENSIONS.each do |ext|
|
128
|
+
filename_with_path = dir + '/' + filename + '.' + ext
|
129
|
+
if File.exists? filename_with_path
|
130
|
+
return filename_with_path
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
|
11
|
+
# This module provides access to logger(Logger) fully configured according to command line options
|
12
|
+
# or config files.
|
13
|
+
#
|
14
|
+
# It will replace the stupid EasyAppHelper::Common::DummyLogger if the
|
15
|
+
# module is included.
|
16
|
+
#
|
17
|
+
# It brings as well some command line options to manipulate debug.
|
18
|
+
# See --help
|
19
|
+
module EasyAppHelper::Logger
|
20
|
+
|
21
|
+
# This module has the highest priority in order to be processed the first by
|
22
|
+
# the framework and therefore give a chance to other modules to use it to log.
|
23
|
+
MODULE_PRIORITY = 1
|
24
|
+
|
25
|
+
include EasyAppHelper::Common
|
26
|
+
|
27
|
+
|
28
|
+
# Returns the current log_level.
|
29
|
+
def log_level
|
30
|
+
app_config[:"log-level"]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Enables to hot-change the log level.
|
34
|
+
def log_level=(level)
|
35
|
+
app_config[:"log-level"] = level
|
36
|
+
logger.level = level
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Build logger for the application. Depending on config may end-up up to nowhere
|
41
|
+
# (by default), STDOUT, STDERR or a file. See --help or EasyAppHelper::Config#help
|
42
|
+
# for all options.
|
43
|
+
def build_logger
|
44
|
+
@logger = EasyAppHelper::Common::DummyLogger.instance
|
45
|
+
issue_report = nil
|
46
|
+
if app_config[:debug]
|
47
|
+
unless app_config[:"log-file"].nil?
|
48
|
+
begin
|
49
|
+
if File.exists? app_config[:"log-file"]
|
50
|
+
logger_type = File.open(app_config[:"log-file"], File::WRONLY | File::APPEND)
|
51
|
+
else
|
52
|
+
logger_type = File.open(app_config[:"log-file"], File::WRONLY | File::CREAT)
|
53
|
+
end
|
54
|
+
rescue Exception => e
|
55
|
+
logger_type = STDOUT
|
56
|
+
issue_report = e.message
|
57
|
+
end
|
58
|
+
else
|
59
|
+
logger_type = STDOUT
|
60
|
+
end
|
61
|
+
logger_type = STDERR if app_config[:"debug-on-err"]
|
62
|
+
@logger = Logger.new(logger_type)
|
63
|
+
end
|
64
|
+
app_config[:'log-level'] = DEFAULT_LOG_LEVEL if app_config[:'log-level'].nil?
|
65
|
+
logger.level = app_config[:"log-level"]
|
66
|
+
logger.error issue_report if issue_report
|
67
|
+
logger.debug "Logger is created."
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
module EasyAppHelper::Logger::Instanciator
|
75
|
+
extend EasyAppHelper::Common::Instanciator
|
76
|
+
|
77
|
+
# Default module priority
|
78
|
+
MODULE_PRIORITY = 1
|
79
|
+
|
80
|
+
# Adds some command line options for this module.
|
81
|
+
# - +--debug+
|
82
|
+
# - +--debug-on-err+ to have the debugging going to STDERR. Should be used on top of
|
83
|
+
# --debug.
|
84
|
+
# - +--log-file+ +filename+ To log to a specific file.
|
85
|
+
# - +--log-level+ +0-5+ Log level according to Logger::Severity
|
86
|
+
def self.add_cmd_line_options(app, slop_definition)
|
87
|
+
slop_definition.separator "\n-- Debug and logging options ---------------------------------"
|
88
|
+
slop_definition.on :debug, 'Run in debug mode.', :argument => false
|
89
|
+
slop_definition.on 'debug-on-err', 'Run in debug mode with output to stderr.', :argument => false
|
90
|
+
slop_definition.on 'log-level', "Log level from 0 to 5, default #{Logger::Severity::ERROR}.", :argument => true, :as => Integer
|
91
|
+
slop_definition.on 'log-file', 'File to log to.', :argument => true
|
92
|
+
end
|
93
|
+
|
94
|
+
# Creates the application logger
|
95
|
+
def self.post_config_action(app)
|
96
|
+
app.build_logger
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
module EasyAppHelper
|
9
|
+
VERSION = "0.0.5"
|
10
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
################################################################################
|
2
|
+
# EasyAppHelper
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 L.Briais under MIT license
|
5
|
+
# http://opensource.org/licenses/MIT
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require "easy_app_helper/version"
|
9
|
+
require "easy_app_helper/common"
|
10
|
+
require "easy_app_helper/base"
|
11
|
+
require "easy_app_helper/config"
|
12
|
+
require "easy_app_helper/logger"
|
13
|
+
|
14
|
+
|
15
|
+
# This module will provide helpers for your applications. Currently supported
|
16
|
+
# modules are:
|
17
|
+
# - EasyAppHelper::Base included by default.
|
18
|
+
# - EasyAppHelper::Logger adds logging capabilities to your scripts.
|
19
|
+
# - EasyAppHelper::Config provides a consistent configuration framework.
|
20
|
+
module EasyAppHelper
|
21
|
+
include EasyAppHelper::Base
|
22
|
+
end
|
23
|
+
|
24
|
+
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: easy_app_helper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- L.Briais
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: slop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Desktop application framework
|
70
|
+
email:
|
71
|
+
- lbnetid+rb@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- easy_app_helper.gemspec
|
82
|
+
- lib/easy_app_helper.rb
|
83
|
+
- lib/easy_app_helper/base.rb
|
84
|
+
- lib/easy_app_helper/common.rb
|
85
|
+
- lib/easy_app_helper/config.rb
|
86
|
+
- lib/easy_app_helper/logger.rb
|
87
|
+
- lib/easy_app_helper/version.rb
|
88
|
+
homepage: ''
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.0.0.rc.2
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Provides cool helpers to your desktop application, including configuration
|
112
|
+
and logging features
|
113
|
+
test_files: []
|