configliere 0.3.4 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.document +3 -0
  2. data/.watchr +20 -0
  3. data/CHANGELOG.textile +99 -3
  4. data/Gemfile +26 -0
  5. data/Gemfile.lock +54 -0
  6. data/README.textile +162 -138
  7. data/Rakefile +30 -21
  8. data/VERSION +1 -1
  9. data/bin/configliere +77 -77
  10. data/bin/configliere-decrypt +85 -0
  11. data/bin/configliere-delete +85 -0
  12. data/bin/configliere-dump +85 -0
  13. data/bin/configliere-encrypt +85 -0
  14. data/bin/configliere-list +85 -0
  15. data/bin/configliere-set +85 -0
  16. data/configliere.gemspec +53 -23
  17. data/examples/config_block_script.rb +9 -2
  18. data/examples/encrypted_script.rb +28 -16
  19. data/examples/env_var_script.rb +2 -2
  20. data/examples/help_message_demo.rb +16 -0
  21. data/examples/independent_config.rb +28 -0
  22. data/examples/prompt.rb +23 -0
  23. data/examples/simple_script.rb +28 -15
  24. data/examples/simple_script.yaml +1 -1
  25. data/lib/configliere.rb +22 -24
  26. data/lib/configliere/commandline.rb +135 -116
  27. data/lib/configliere/commands.rb +38 -54
  28. data/lib/configliere/config_block.rb +4 -2
  29. data/lib/configliere/config_file.rb +30 -52
  30. data/lib/configliere/crypter.rb +8 -5
  31. data/lib/configliere/deep_hash.rb +368 -0
  32. data/lib/configliere/define.rb +83 -89
  33. data/lib/configliere/encrypted.rb +17 -18
  34. data/lib/configliere/env_var.rb +5 -7
  35. data/lib/configliere/param.rb +37 -64
  36. data/lib/configliere/prompt.rb +23 -0
  37. data/spec/configliere/commandline_spec.rb +156 -57
  38. data/spec/configliere/commands_spec.rb +75 -30
  39. data/spec/configliere/config_block_spec.rb +10 -1
  40. data/spec/configliere/config_file_spec.rb +83 -55
  41. data/spec/configliere/crypter_spec.rb +3 -2
  42. data/spec/configliere/deep_hash_spec.rb +401 -0
  43. data/spec/configliere/define_spec.rb +121 -42
  44. data/spec/configliere/encrypted_spec.rb +53 -20
  45. data/spec/configliere/env_var_spec.rb +24 -4
  46. data/spec/configliere/param_spec.rb +25 -27
  47. data/spec/configliere/prompt_spec.rb +50 -0
  48. data/spec/configliere_spec.rb +3 -9
  49. data/spec/spec_helper.rb +17 -6
  50. metadata +110 -35
  51. data/lib/configliere/core_ext.rb +0 -2
  52. data/lib/configliere/core_ext/blank.rb +0 -93
  53. data/lib/configliere/core_ext/hash.rb +0 -108
  54. data/lib/configliere/core_ext/sash.rb +0 -170
  55. data/spec/configliere/core_ext/hash_spec.rb +0 -78
  56. data/spec/configliere/core_ext/sash_spec.rb +0 -312
@@ -2,7 +2,7 @@
2
2
  $: << File.dirname(__FILE__)+'/../lib'
3
3
  require 'configliere'
4
4
 
5
- Settings.use :define, :env_var, :commandline
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.param_definitions[:underpants][:default].inspect}
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 #=> {}
@@ -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
+ }
@@ -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, :config_file, :define
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
- :dest_time => '1955-11-05',
11
+ :heavy => true,
11
12
  :delorean => {
12
13
  :power_source => 'plutonium',
13
14
  :roads_needed => true,
14
15
  },
15
- })
16
- puts " #{Settings.inspect}"
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 "\nYou can load values from a file -- in this case, #{config_filename} -- which overrides the defaults:"
29
+ puts "\nValues loaded from the file #{config_filename} merge with the existing defaults:"
30
+
20
31
  Settings.read config_filename
21
- Settings.resolve!
22
- puts " #{Settings.inspect}"
32
+ puts "\n #{Settings.inspect}"
23
33
 
24
- puts %Q{\nTry running the script with commandline parameters, for example
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. These settings have been written to #{saved_filename}}
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
+
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  # Settings for return
3
- :dest_time: 1985-11-05
3
+ :dest_time: 11-05-1985
4
4
  :delorean:
5
5
  :power_source: 1.21 jiggawatts
data/lib/configliere.rb CHANGED
@@ -1,40 +1,38 @@
1
- require 'configliere/core_ext'
2
- require 'configliere/param'
3
- require 'configliere/define'
4
- require 'configliere/config_file'
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
- module Configliere
7
-
8
- # delegates to Configliere::Param
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
- ALL_MIXINS = [:define, :config_file, :commandline, :encrypted, :env_var, :config_block, :commands]
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
- # backwards compatibility
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
- # Allows the
36
- # Config :this => that, :cat => :hat
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
- alias_method :argv, :rest
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 (using
16
- # any +:description+ set with #define) and then exits
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
- dump_help_if_requested
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.gsub!(/\-/, '.') # translate --scoped-flag to --scoped.flag
49
- param = param.to_sym unless (param =~ /\./) # symbolize non-scoped keys
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 = param_with_flag(flag)
55
- self[param] = true if param
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
- # when arg =~ /\A-(\w)=(.*)\z/
59
- # param, val = param_with_flag($1), $2
60
- # self[param] = parse_value(val) if param
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
- def parse_value val
68
- case
69
- when val == nil then true # --flag option on its own means 'set that option'
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 Settings[setting_name]
104
+ return unless self[setting_name]
121
105
  flag_name ||= setting_name
122
- (Settings[setting_name] == true ? "--#{flag_name.to_s.gsub(/_/,"-")}" : "--#{flag_name.to_s.gsub(/_/,"-")}=#{Settings[setting_name]}" )
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
- # Complain about bad flags?
130
- def complain_about_bad_flags?
131
- @complain_about_bad_flags
132
- end
114
+ # ===========================================================================
115
+ #
116
+ # Commandline help
117
+ #
133
118
 
134
- # Force this params object to complain about bad (single-letter)
135
- # flags on the command-line.
136
- def complain_about_bad_flags!
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
- # Return the params for which a line should be printed giving
141
- # their usage.
142
- def params_with_command_line_help
143
- descriptions.reject{ |param, desc| param_definitions[param][:no_command_line_help] }.sort_by{ |param, desc| param.to_s }
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
- # Help on the flags used.
147
- def flags_help
148
- help = ["\nParams"]
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
- # Return the params for which a line should be printing giving
159
- # their dependence on environment variables.
160
- def params_with_env_help
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
- # Help on environment variables.
165
- def env_var_help
166
- return if params_with_env_help.empty?
167
- [ "\nEnvironment Variables can be used to set:"] + params_with_env_help.map{ |param, env| " %-27s %s"%[env.to_s, param]}
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
- # Output the help message to $stderr, along with an optional extra message appended.
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
- def dump_help str=nil
178
- dump_basic_help
179
- dump_command_help if respond_to?(:dump_command_help)
180
- puts str if str
181
- end
182
-
183
- def raw_script_name
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
- # Usage line
188
- def usage
189
- %Q{usage: #{raw_script_name} [...--param=val...]}
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
- protected
193
-
194
- # Ouput the help string if requested
195
- def dump_help_if_requested
196
- return unless self[:help]
197
- $stderr.puts usage
198
- dump_help
199
- exit
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.class_eval do
204
- # include read / save operations
205
- include Commandline
223
+ Param.on_use(:commandline) do
224
+ extend Configliere::Commandline
206
225
  end
207
226
  end