configliere 0.3.4 → 0.4.4
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/.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
|