configliere 0.3.4 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +3 -0
- data/.watchr +20 -0
- data/CHANGELOG.textile +99 -3
- data/Gemfile +26 -0
- data/Gemfile.lock +54 -0
- data/README.textile +162 -138
- data/Rakefile +30 -21
- data/VERSION +1 -1
- data/bin/configliere +77 -77
- data/bin/configliere-decrypt +85 -0
- data/bin/configliere-delete +85 -0
- data/bin/configliere-dump +85 -0
- data/bin/configliere-encrypt +85 -0
- data/bin/configliere-list +85 -0
- data/bin/configliere-set +85 -0
- data/configliere.gemspec +53 -23
- data/examples/config_block_script.rb +9 -2
- data/examples/encrypted_script.rb +28 -16
- data/examples/env_var_script.rb +2 -2
- data/examples/help_message_demo.rb +16 -0
- data/examples/independent_config.rb +28 -0
- data/examples/prompt.rb +23 -0
- data/examples/simple_script.rb +28 -15
- data/examples/simple_script.yaml +1 -1
- data/lib/configliere.rb +22 -24
- data/lib/configliere/commandline.rb +135 -116
- data/lib/configliere/commands.rb +38 -54
- data/lib/configliere/config_block.rb +4 -2
- data/lib/configliere/config_file.rb +30 -52
- data/lib/configliere/crypter.rb +8 -5
- data/lib/configliere/deep_hash.rb +368 -0
- data/lib/configliere/define.rb +83 -89
- data/lib/configliere/encrypted.rb +17 -18
- data/lib/configliere/env_var.rb +5 -7
- data/lib/configliere/param.rb +37 -64
- data/lib/configliere/prompt.rb +23 -0
- data/spec/configliere/commandline_spec.rb +156 -57
- data/spec/configliere/commands_spec.rb +75 -30
- data/spec/configliere/config_block_spec.rb +10 -1
- data/spec/configliere/config_file_spec.rb +83 -55
- data/spec/configliere/crypter_spec.rb +3 -2
- data/spec/configliere/deep_hash_spec.rb +401 -0
- data/spec/configliere/define_spec.rb +121 -42
- data/spec/configliere/encrypted_spec.rb +53 -20
- data/spec/configliere/env_var_spec.rb +24 -4
- data/spec/configliere/param_spec.rb +25 -27
- data/spec/configliere/prompt_spec.rb +50 -0
- data/spec/configliere_spec.rb +3 -9
- data/spec/spec_helper.rb +17 -6
- metadata +110 -35
- data/lib/configliere/core_ext.rb +0 -2
- data/lib/configliere/core_ext/blank.rb +0 -93
- data/lib/configliere/core_ext/hash.rb +0 -108
- data/lib/configliere/core_ext/sash.rb +0 -170
- data/spec/configliere/core_ext/hash_spec.rb +0 -78
- data/spec/configliere/core_ext/sash_spec.rb +0 -312
data/examples/env_var_script.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
$: << File.dirname(__FILE__)+'/../lib'
|
3
3
|
require 'configliere'
|
4
4
|
|
5
|
-
Settings.use :
|
5
|
+
Settings.use :env_var, :commandline
|
6
6
|
Settings.define :underpants, :env_var => 'UNDERPANTS', :default => "boxers"
|
7
7
|
Settings.resolve!
|
8
8
|
|
@@ -18,7 +18,7 @@ UNDERPANTS="commando" ./env_var_script.rb --underpants=briefs # commandline wins
|
|
18
18
|
}
|
19
19
|
|
20
20
|
puts %Q{Using
|
21
|
-
* the default setting of: #{Settings.
|
21
|
+
* the default setting of: #{Settings.definition_of(:underpants, :default).inspect}
|
22
22
|
* the environment variable: #{ENV['UNDERPANTS'].inspect}
|
23
23
|
* the commandline setting: #{ARGV.grep(/^--underpants/).inspect}
|
24
24
|
your configliere advises that
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.dirname(__FILE__)+"/../lib"
|
3
|
+
require 'configliere'
|
4
|
+
Settings.use :commandline
|
5
|
+
|
6
|
+
Settings.define :logfile, :type => String, :description => "Log file name", :default => 'myapp.log', :required => false
|
7
|
+
Settings.define :debug, :type => :boolean, :description => "Log debug messages to console?", :required => false
|
8
|
+
Settings.define :dest_time, :type => DateTime, :description => "Arrival time", :required => true
|
9
|
+
Settings.define :takes_opt, :flag => 't', :description => "Takes a single-letter flag '-t'"
|
10
|
+
Settings.define :foobaz, :internal => true, :description => "You won't see me"
|
11
|
+
Settings.define 'delorean.power_source', :env_var => 'POWER_SOURCE', :description => 'Delorean subsytem supplying power to the Flux Capacitor.'
|
12
|
+
Settings.define :password, :required => true, :encrypted => true
|
13
|
+
Settings.description = 'This is a sample script to demonstrate the help message. Notice how pretty everything lines up YAY'
|
14
|
+
|
15
|
+
Settings.resolve! rescue nil
|
16
|
+
puts "Run me again with --help to see the auto-generated help message!"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.dirname(__FILE__)+'/../lib'
|
3
|
+
require 'configliere'
|
4
|
+
require 'gorillib/metaprogramming/class_attribute'
|
5
|
+
|
6
|
+
class Wolfman
|
7
|
+
class_attribute :config
|
8
|
+
self.config = Configliere::Param.new.use(:commandline).defaults({
|
9
|
+
:moon => 'full',
|
10
|
+
:nards => true,
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
Wolfman.config.description = 'Run this with commandline args: Wolfman uses them, Settings does not'
|
15
|
+
|
16
|
+
teen_wolf = Wolfman.new
|
17
|
+
teen_wolf.config.defaults(:give_me => 'keg of beer')
|
18
|
+
|
19
|
+
Wolfman.config.resolve!
|
20
|
+
Settings.resolve!
|
21
|
+
|
22
|
+
# run this with ./examples/independent_config.rb --hi=there :
|
23
|
+
puts "If you run this with #{$0} --hi=there, you should expect:"
|
24
|
+
puts '{:moon=>"full", :nards=>true, :give_me=>"keg of beer", :hi=>"there"}'
|
25
|
+
p teen_wolf.config
|
26
|
+
|
27
|
+
puts 'the Settings hash should be empty:'
|
28
|
+
p Settings #=> {}
|
data/examples/prompt.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.dirname(__FILE__)+'/../lib'
|
3
|
+
require 'configliere'
|
4
|
+
|
5
|
+
Settings.use :commandline, :prompt
|
6
|
+
Settings.define :underpants, :description => 'boxers or briefs'
|
7
|
+
Settings.resolve!
|
8
|
+
|
9
|
+
puts %Q{
|
10
|
+
Configliere can prompt for a parameter value if none is given.
|
11
|
+
If you call this with a value for --underpants, you will not see a prompt
|
12
|
+
}
|
13
|
+
|
14
|
+
puts %Q{Using the commandline setting #{ARGV.grep(/^--underpants/).inspect}
|
15
|
+
your configliere advises that the settings are
|
16
|
+
#{Settings.inspect}
|
17
|
+
}
|
18
|
+
|
19
|
+
puts Settings.prompt_for(:underpants)
|
20
|
+
|
21
|
+
puts %Q{Now the Settings are
|
22
|
+
#{Settings.inspect}
|
23
|
+
}
|
data/examples/simple_script.rb
CHANGED
@@ -3,32 +3,45 @@ $: << File.dirname(__FILE__)+'/../lib'
|
|
3
3
|
require 'configliere'
|
4
4
|
|
5
5
|
puts "This is a demo of Configliere in a simple script."
|
6
|
-
Settings.use :commandline
|
6
|
+
Settings.use :commandline
|
7
|
+
|
8
|
+
puts "\n\nSet default values inline:"
|
7
9
|
|
8
|
-
puts "You can set default values:"
|
9
10
|
Settings({
|
10
|
-
:
|
11
|
+
:heavy => true,
|
11
12
|
:delorean => {
|
12
13
|
:power_source => 'plutonium',
|
13
14
|
:roads_needed => true,
|
14
15
|
},
|
15
|
-
|
16
|
-
|
16
|
+
:username => 'marty',
|
17
|
+
})
|
18
|
+
puts "\n #{Settings.inspect}"
|
19
|
+
|
20
|
+
puts "\nYou can define settings' type, default value, and description (that shows up with --help), and more. It's purely optional, but it's very convenient:"
|
21
|
+
|
22
|
+
Settings.define :dest_time, :default => '11-05-1955', :type => Time, :description => "Target date"
|
23
|
+
# This defines a 'deep key': it controls Settings[:delorean][:roads_needed]
|
24
|
+
Settings.define 'delorean.roads_needed', :type => :boolean
|
25
|
+
Settings.define 'username', :env_var => 'DRIVER'
|
26
|
+
puts "\n #{Settings.inspect}"
|
17
27
|
|
18
28
|
config_filename = File.dirname(__FILE__)+'/simple_script.yaml'
|
19
|
-
puts "\
|
29
|
+
puts "\nValues loaded from the file #{config_filename} merge with the existing defaults:"
|
30
|
+
|
20
31
|
Settings.read config_filename
|
21
|
-
Settings.
|
22
|
-
puts " #{Settings.inspect}"
|
32
|
+
puts "\n #{Settings.inspect}"
|
23
33
|
|
24
|
-
puts %Q{\
|
25
|
-
#{$0} --dest_time=2015-11-05 --delorean.roads_needed="" --delorean.power_source="Mr. Fusion"
|
26
|
-
In this case, you used
|
27
|
-
#{$0} #{ARGV.map{|argv| "'#{argv}'"}.join(" ")}
|
28
|
-
and so the final parameter values are}
|
34
|
+
puts %Q{\nFinally, call resolve! to load the commandline you gave (#{ARGV.inspect}), do type conversion (watch what happens to :dest_time), etc:}
|
29
35
|
Settings.resolve!
|
30
|
-
puts " #{Settings.inspect}"
|
36
|
+
puts "\n #{Settings.inspect}"
|
31
37
|
|
32
38
|
saved_filename = '/tmp/simple_script_saved.yaml'
|
33
|
-
puts %Q{\nYou can save the defaults out to a config file
|
39
|
+
puts %Q{\nYou can save the defaults out to a config file -- go look in #{saved_filename}}
|
34
40
|
Settings.save!(saved_filename)
|
41
|
+
|
42
|
+
if ARGV.empty?
|
43
|
+
puts %Q{\nTry running the script again, but supply some commandline args:\n
|
44
|
+
DRIVER=doc #{$0} --dest_time=11-05-2015 --delorean.roads_needed=false --delorean.power_source="Mr. Fusion"}
|
45
|
+
end
|
46
|
+
puts
|
47
|
+
|
data/examples/simple_script.yaml
CHANGED
data/lib/configliere.rb
CHANGED
@@ -1,40 +1,38 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
1
|
+
require 'date' # type conversion
|
2
|
+
require 'time' # type conversion
|
3
|
+
require 'yaml' # read files
|
4
|
+
require 'fileutils' # so save! can mkdir
|
5
|
+
require 'configliere/deep_hash' # magic hash for params
|
6
|
+
require 'configliere/param' # params container
|
7
|
+
require 'configliere/define' # define param behavior
|
8
|
+
require 'configliere/config_file' # read / save! files
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def self.new *args, &block
|
10
|
-
Configliere::Param.new(*args, &block)
|
11
|
-
end
|
10
|
+
# use(:encrypted) will bring in 'digest/sha2' and 'openssl'
|
11
|
+
# use(:prompt) will bring in 'highline', which you must gem install
|
12
|
+
# running the specs requires rspec and spork
|
12
13
|
|
13
|
-
|
14
|
+
module Configliere
|
15
|
+
ALL_MIXINS = [:define, :config_file, :commandline, :encrypted, :env_var, :config_block, :commands, :prompt]
|
14
16
|
def self.use *mixins
|
15
17
|
mixins = ALL_MIXINS if mixins.include?(:all) || mixins.empty?
|
16
18
|
mixins.each do |mixin|
|
17
|
-
|
18
|
-
if mixin.to_sym == :git_style_binaries
|
19
|
-
require "configliere/commands"
|
20
|
-
else
|
21
|
-
require "configliere/#{mixin}"
|
22
|
-
end
|
19
|
+
require "configliere/#{mixin}"
|
23
20
|
end
|
24
21
|
end
|
25
22
|
|
26
|
-
# Base class for Configliere errors.
|
27
|
-
Error = Class.new(StandardError)
|
28
|
-
|
29
23
|
end
|
30
24
|
|
25
|
+
# Base class for Configliere errors.
|
26
|
+
class Configliere::Error < StandardError ; end
|
27
|
+
# Feature is deprecated, has or will leave the building
|
28
|
+
class Configliere::DeprecatedError < Configliere::Error ; end
|
29
|
+
|
31
30
|
# Defines a global config object
|
32
|
-
Settings = Configliere.new unless defined?(Settings)
|
31
|
+
Settings = Configliere::Param.new unless defined?(Settings)
|
33
32
|
|
34
33
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# pattern.
|
34
|
+
# Also define Settings as a function, so you can say
|
35
|
+
# Settings :this => that, :cat => :hat
|
38
36
|
#
|
39
37
|
def Settings *args
|
40
38
|
Settings.defaults(*args)
|
@@ -1,25 +1,32 @@
|
|
1
|
-
# Configliere.use :define
|
2
1
|
module Configliere
|
3
2
|
|
4
3
|
#
|
5
4
|
# Command line tool to manage param info
|
6
5
|
#
|
6
|
+
# @example
|
7
|
+
# Settings.use :commandline
|
8
|
+
#
|
7
9
|
module Commandline
|
8
10
|
attr_accessor :rest
|
9
|
-
|
11
|
+
attr_accessor :description
|
12
|
+
attr_reader :unknown_argvs
|
10
13
|
|
11
14
|
# Processing to reconcile all options
|
12
15
|
#
|
13
16
|
# Configliere::Commandline's resolve!:
|
17
|
+
#
|
14
18
|
# * processes all commandline params
|
15
|
-
# * if the --help param was given, prints out a usage statement
|
16
|
-
#
|
17
|
-
# * lastly, calls the next method in the resolve! chain.
|
19
|
+
# * if the --help param was given, prints out a usage statement describing all #define'd params and exits
|
20
|
+
# * calls up the resolve! chain.
|
18
21
|
#
|
19
22
|
def resolve!
|
20
23
|
process_argv!
|
21
|
-
|
24
|
+
if self[:help]
|
25
|
+
dump_help
|
26
|
+
exit(2)
|
27
|
+
end
|
22
28
|
super()
|
29
|
+
self
|
23
30
|
end
|
24
31
|
|
25
32
|
#
|
@@ -35,6 +42,7 @@ module Configliere
|
|
35
42
|
def process_argv!
|
36
43
|
args = ARGV.dup
|
37
44
|
self.rest = []
|
45
|
+
@unknown_argvs = []
|
38
46
|
until args.empty? do
|
39
47
|
arg = args.shift
|
40
48
|
case
|
@@ -42,69 +50,45 @@ module Configliere
|
|
42
50
|
when arg == '--'
|
43
51
|
self.rest += args
|
44
52
|
break
|
45
|
-
# --param=val
|
53
|
+
# --param=val or --param
|
46
54
|
when arg =~ /\A--([\w\-\.]+)(?:=(.*))?\z/
|
47
55
|
param, val = [$1, $2]
|
48
|
-
param.
|
49
|
-
|
56
|
+
warn "Configliere uses _underscores not dashes for params" if param.include?('-')
|
57
|
+
@unknown_argvs << param.to_sym if (not has_definition?(param))
|
50
58
|
self[param] = parse_value(val)
|
51
59
|
# -abc
|
52
|
-
when arg =~ /\A-(\w+)\z/
|
60
|
+
when arg =~ /\A-(\w\w+)\z/
|
53
61
|
$1.each_char do |flag|
|
54
|
-
param =
|
55
|
-
|
62
|
+
param = find_param_for_flag(flag)
|
63
|
+
unless param then @unknown_argvs << flag ; next ; end
|
64
|
+
self[param] = true
|
56
65
|
end
|
66
|
+
# -a val
|
67
|
+
when arg =~ /\A-(\w)\z/
|
68
|
+
flag = find_param_for_flag($1)
|
69
|
+
unless flag then @unknown_argvs << flag ; next ; end
|
70
|
+
if (not args.empty?) && (args.first !~ /\A-/)
|
71
|
+
val = args.shift
|
72
|
+
else
|
73
|
+
val = nil
|
74
|
+
end
|
75
|
+
self[flag] = parse_value(val)
|
57
76
|
# -a=val
|
58
|
-
|
59
|
-
|
60
|
-
|
77
|
+
when arg =~ /\A-(\w)=(.*)\z/
|
78
|
+
flag, val = [find_param_for_flag($1), $2]
|
79
|
+
unless flag then @unknown_argvs << flag ; next ; end
|
80
|
+
self[flag] = parse_value(val)
|
61
81
|
else
|
62
82
|
self.rest << arg
|
63
83
|
end
|
64
84
|
end
|
85
|
+
@unknown_argvs.uniq!
|
65
86
|
end
|
66
87
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
when val == '' then nil # --flag='' the explicit empty string means nil
|
71
|
-
else val # else just return the value
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Configliere internal params
|
76
|
-
def define_special_params
|
77
|
-
Settings.define :encrypt_pass, :description => "Passphrase to extract encrypted config params.", :internal => true
|
78
|
-
end
|
79
|
-
|
80
|
-
# All commandline name-value params that aren't internal to configliere
|
81
|
-
def normal_params
|
82
|
-
reject{|param, val| param_definitions[param][:internal] }
|
83
|
-
end
|
84
|
-
|
85
|
-
# die with a warning
|
88
|
+
# ===========================================================================
|
89
|
+
#
|
90
|
+
# Recyle out our settings as a commandline
|
86
91
|
#
|
87
|
-
# @param str [String] the string to dump out before exiting
|
88
|
-
# @param exit_code [Integer] UNIX exit code to set, default -1
|
89
|
-
def die str, exit_code=-1
|
90
|
-
dump_help "****\n#{str}\n****"
|
91
|
-
exit exit_code
|
92
|
-
end
|
93
|
-
|
94
|
-
# Retrieve the given param, or prompt for it
|
95
|
-
def param_or_ask attr, hint=nil
|
96
|
-
return self[attr] if include?(attr)
|
97
|
-
require 'highline/import'
|
98
|
-
self[attr] = ask("#{attr}"+(hint ? " for #{hint}?" : '?'))
|
99
|
-
end
|
100
|
-
|
101
|
-
# Retreive the first param defined with the given flag.
|
102
|
-
def param_with_flag flag
|
103
|
-
params_with(:flag).each do |param|
|
104
|
-
return param if param_definitions[param][:flag].to_s == flag.to_s
|
105
|
-
end
|
106
|
-
raise Configliere::Error.new("Unknown option: -#{flag}") if complain_about_bad_flags?
|
107
|
-
end
|
108
92
|
|
109
93
|
# Returns a flag in dashed form, suitable for recycling into the commandline
|
110
94
|
# of an external program.
|
@@ -117,91 +101,126 @@ module Configliere
|
|
117
101
|
# #=> --hello-friend=true
|
118
102
|
#
|
119
103
|
def dashed_flag_for setting_name, flag_name=nil
|
120
|
-
return unless
|
104
|
+
return unless self[setting_name]
|
121
105
|
flag_name ||= setting_name
|
122
|
-
(
|
106
|
+
(self[setting_name] == true ? "--#{flag_name.to_s.gsub(/_/,"-")}" : "--#{flag_name.to_s.gsub(/_/,"-")}=#{self[setting_name]}" )
|
123
107
|
end
|
124
108
|
|
109
|
+
# dashed_flag_for each given setting that has a value
|
125
110
|
def dashed_flags *settings_and_names
|
126
|
-
settings_and_names.map{|args| dashed_flag_for(*args) }
|
111
|
+
settings_and_names.map{|args| dashed_flag_for(*args) }.compact
|
127
112
|
end
|
128
113
|
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
|
114
|
+
# ===========================================================================
|
115
|
+
#
|
116
|
+
# Commandline help
|
117
|
+
#
|
133
118
|
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
@complain_about_bad_flags = true
|
119
|
+
# Write the help string to stderr
|
120
|
+
def dump_help str=nil
|
121
|
+
warn help(str)+"\n"
|
138
122
|
end
|
139
123
|
|
140
|
-
#
|
141
|
-
#
|
142
|
-
def
|
143
|
-
|
124
|
+
# The contents of the help message.
|
125
|
+
# Lists the usage as well as any defined parameters and environment variables
|
126
|
+
def help str=nil
|
127
|
+
buf = []
|
128
|
+
buf << usage
|
129
|
+
buf << "\n"+@description if @description
|
130
|
+
buf << param_lines
|
131
|
+
buf << commands_help if respond_to?(:commands_help)
|
132
|
+
buf << "\n\n"+str if str
|
133
|
+
buf.flatten.compact.join("\n")+"\n"
|
144
134
|
end
|
145
135
|
|
146
|
-
#
|
147
|
-
def
|
148
|
-
|
149
|
-
help += params_with_command_line_help.map do |param, desc|
|
150
|
-
if flag = param_definitions[param][:flag]
|
151
|
-
" -%s, --%-21s %s" % [flag.to_s.first, param.to_s, desc]
|
152
|
-
else
|
153
|
-
" --%-25s %s" % [param.to_s + ':', desc]
|
154
|
-
end
|
155
|
-
end
|
136
|
+
# Usage line
|
137
|
+
def usage
|
138
|
+
%Q{usage: #{raw_script_name} [...--param=val...]}
|
156
139
|
end
|
157
140
|
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
definitions_for(:env_var).reject { |param, desc| param_definitions[param][:no_help] || param_definitions[param][:no_env_help] }
|
141
|
+
# the script basename, for recycling into help messages
|
142
|
+
def raw_script_name
|
143
|
+
File.basename($0)
|
162
144
|
end
|
163
145
|
|
164
|
-
#
|
165
|
-
|
166
|
-
|
167
|
-
|
146
|
+
# die with a warning
|
147
|
+
#
|
148
|
+
# @example
|
149
|
+
# Settings.define :foo, :finally => lambda{ Settings.foo.to_i < 5 or die("too much foo!") }
|
150
|
+
#
|
151
|
+
# @param str [String] the string to dump out before exiting
|
152
|
+
# @param exit_code [Integer] UNIX exit code to set, default -1
|
153
|
+
def die str, exit_code=-1
|
154
|
+
dump_help "****\n#{str}\n****"
|
155
|
+
exit exit_code
|
168
156
|
end
|
169
157
|
|
170
|
-
|
171
|
-
def dump_basic_help extra_msg=nil
|
172
|
-
$stderr.puts [:flags_help, :env_var_help].map { |help| send(help) }.flatten.compact.join("\n") if respond_to?(:descriptions)
|
173
|
-
$stderr.puts "\n\n"+extra_msg unless extra_msg.blank?
|
174
|
-
$stderr.puts ''
|
175
|
-
end
|
158
|
+
protected
|
176
159
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
File.basename($0)
|
160
|
+
# handle --param (true), --param='' (set as ++nil++), --param=hi ('hi')
|
161
|
+
def parse_value val
|
162
|
+
case
|
163
|
+
when val == nil then true # --flag option on its own means 'set that option'
|
164
|
+
when val == '' then nil # --flag='' the explicit empty string means nil
|
165
|
+
else val # else just return the value
|
166
|
+
end
|
185
167
|
end
|
186
168
|
|
187
|
-
#
|
188
|
-
def
|
189
|
-
|
169
|
+
# Retrieve the first param defined with the given flag.
|
170
|
+
def find_param_for_flag(flag)
|
171
|
+
params_with(:flag).each do |param_name, param_flag|
|
172
|
+
return param_name if flag.to_s == param_flag.to_s
|
173
|
+
end
|
174
|
+
nil
|
190
175
|
end
|
191
176
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
177
|
+
def param_lines
|
178
|
+
pdefs = definitions.reject{|name, definition| definition[:internal] }
|
179
|
+
return if pdefs.empty?
|
180
|
+
buf = ["\nParams:"]
|
181
|
+
width = find_width(pdefs.keys)
|
182
|
+
has_flags = (not params_with(:flag).empty?)
|
183
|
+
pdefs.sort_by{|pn, pd| pn.to_s }.each do |name, definition|
|
184
|
+
buf << param_line(name, definition, width, has_flags)
|
185
|
+
end
|
186
|
+
buf
|
187
|
+
end
|
188
|
+
|
189
|
+
# pretty-print a param
|
190
|
+
def param_line(name, definition, width, has_flags)
|
191
|
+
desc = definition_of(name, :description).to_s.strip
|
192
|
+
buf = [' ']
|
193
|
+
buf << (definition[:flag] ? "-#{definition[:flag]}," : " ") if has_flags
|
194
|
+
buf << sprintf("--%-#{width}s", param_with_type(name))
|
195
|
+
buf << (desc.empty? ? name : desc)
|
196
|
+
buf << "[Default: #{definition[:default]}]" if definition[:default]
|
197
|
+
buf << '[Required]' if definition[:required]
|
198
|
+
buf << '[Encrypted]' if definition[:encrypted]
|
199
|
+
buf << "[Env Var: #{definition[:env_var]}]" if definition[:env_var]
|
200
|
+
buf.join(' ')
|
201
|
+
end
|
202
|
+
|
203
|
+
# run through the params and find the width needed to pretty-print them
|
204
|
+
def find_width(param_names)
|
205
|
+
[ 20,
|
206
|
+
param_names.map{|param_name| param_with_type(param_name).length }
|
207
|
+
].flatten.max + 2
|
208
|
+
end
|
209
|
+
|
210
|
+
def param_with_type(param)
|
211
|
+
str = param.to_s
|
212
|
+
type = definition_of(param, :type)
|
213
|
+
case type
|
214
|
+
when :boolean then str += ''
|
215
|
+
when nil then str += '=String'
|
216
|
+
else str += "=#{type}"
|
217
|
+
end
|
218
|
+
str
|
200
219
|
end
|
220
|
+
|
201
221
|
end
|
202
222
|
|
203
|
-
Param.
|
204
|
-
|
205
|
-
include Commandline
|
223
|
+
Param.on_use(:commandline) do
|
224
|
+
extend Configliere::Commandline
|
206
225
|
end
|
207
226
|
end
|