Auto 4.0.0.alpha.1-x86-mingw32

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.
Files changed (65) hide show
  1. data/.yardopts +7 -0
  2. data/Gemfile +19 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +109 -0
  5. data/Rakefile +41 -0
  6. data/bin/auto +110 -0
  7. data/bin/auto-conf +45 -0
  8. data/conf/example.json +100 -0
  9. data/conf/example.yml +125 -0
  10. data/docs/Contributing.md +77 -0
  11. data/docs/Events.md +103 -0
  12. data/docs/Todo.md +21 -0
  13. data/docs/Upgrade.md +16 -0
  14. data/ext/dsl_base.c +49 -0
  15. data/ext/libauto/auto.h +20 -0
  16. data/ext/libauto/extconf.rb +16 -0
  17. data/ext/libauto/libauto.c +29 -0
  18. data/ext/libauto/libauto.h +28 -0
  19. data/ext/libauto/logger.c +177 -0
  20. data/ext/libauto/logger.h +44 -0
  21. data/lib/auto.rb +43 -0
  22. data/lib/auto/api.rb +7 -0
  23. data/lib/auto/api/events.rb +166 -0
  24. data/lib/auto/api/object.rb +29 -0
  25. data/lib/auto/api/plugin.rb +155 -0
  26. data/lib/auto/api/timers.rb +93 -0
  27. data/lib/auto/bot.rb +338 -0
  28. data/lib/auto/config.rb +181 -0
  29. data/lib/auto/configure.rb +410 -0
  30. data/lib/auto/configure/shell.rb +154 -0
  31. data/lib/auto/dsl/base.rb +74 -0
  32. data/lib/auto/dsl/irc.rb +13 -0
  33. data/lib/auto/irc.rb +8 -0
  34. data/lib/auto/irc/common.rb +63 -0
  35. data/lib/auto/irc/library.rb +89 -0
  36. data/lib/auto/irc/object/channel.rb +21 -0
  37. data/lib/auto/irc/object/entity.rb +90 -0
  38. data/lib/auto/irc/object/message.rb +99 -0
  39. data/lib/auto/irc/object/user.rb +139 -0
  40. data/lib/auto/irc/protocol.rb +164 -0
  41. data/lib/auto/irc/protocol/numerics.rb +60 -0
  42. data/lib/auto/irc/sasl/diffie_hellman.rb +36 -0
  43. data/lib/auto/irc/sasl/mech.rb +15 -0
  44. data/lib/auto/irc/sasl/mech/dh_blowfish.rb +83 -0
  45. data/lib/auto/irc/sasl/mech/plain.rb +39 -0
  46. data/lib/auto/irc/server.rb +301 -0
  47. data/lib/auto/irc/state/channel_manager.rb +6 -0
  48. data/lib/auto/irc/state/support.rb +142 -0
  49. data/lib/auto/irc/state/user_manager.rb +6 -0
  50. data/lib/auto/irc/std/commands.rb +99 -0
  51. data/lib/auto/irc/std/numerics.rb +216 -0
  52. data/lib/auto/rubyext/integer.rb +25 -0
  53. data/lib/auto/rubyext/string.rb +10 -0
  54. data/lib/auto/version.rb +18 -0
  55. data/lib/libauto.so +0 -0
  56. data/spec/api_events_spec.rb +68 -0
  57. data/spec/config_json_spec.rb +116 -0
  58. data/spec/config_other_spec.rb +29 -0
  59. data/spec/config_yaml_spec.rb +136 -0
  60. data/spec/helper.rb +19 -0
  61. data/spec/irc_object_entity_spec.rb +51 -0
  62. data/spec/logger_spec.rb +30 -0
  63. data/spec/plugin_base_spec.rb +35 -0
  64. data/spec/timers_spec.rb +42 -0
  65. metadata +238 -0
@@ -0,0 +1,181 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (LICENSE.md).
3
+ autoload :JSON, 'json'
4
+ autoload :Psych, 'psych'
5
+ require 'libauto'
6
+
7
+ # Namespace: Auto
8
+ module Auto
9
+
10
+ # A class which provides a functional, simple configuration interface. It is
11
+ # very useful, as it supports both YAML and JSON for configuration. It
12
+ # determines which is appropriate by looking at file extensions.
13
+ #
14
+ # @api Auto
15
+ # @since 4.0.0
16
+ # @author noxgirl
17
+ # @author swarley
18
+ #
19
+ # @!attribute conf
20
+ # @return [Hash{}] This is the hash which contains the data parsed from
21
+ # the configuration file.
22
+ # @see #[]
23
+ #
24
+ # @!attribute type
25
+ # @return [Symbol] Type of configuration: +:yaml+ or +:json+.
26
+ class Config
27
+
28
+ attr_reader :conf, :type
29
+
30
+ # Produce a new instance, and attempt to parse.
31
+ #
32
+ # @param [String] filepath Path to configuration file.
33
+ #
34
+ # @raise [ConfigError] If the file extension is not recognized (should be +.yml+ or +.json+).
35
+ def initialize filepath
36
+
37
+ $m.debug("Trying to initialize configuration from '#{filepath}'...")
38
+
39
+ # Set path to file.
40
+ @path = filepath
41
+
42
+ # Determine the type: YAML or JSON.
43
+ case File.extname(filepath)
44
+ when ".yml"
45
+ @type = :yaml
46
+ when ".json"
47
+ @type = :json
48
+ else
49
+ raise ConfigError, "Unknown file type on #{filepath}."
50
+ end
51
+
52
+ # Process the configuration.
53
+ parse!
54
+
55
+ end
56
+
57
+ # Rehash the configuration.
58
+ #
59
+ # If an error occurs, it will revert the configuration to its prior state
60
+ # so that everything can continue to function.
61
+ def rehash!
62
+
63
+ $m.debug("Configuration file is rehashing.")
64
+
65
+ # Keep the old configuration in case of issues.
66
+ oldconf = @conf
67
+ @conf = {}
68
+
69
+ # Rehash
70
+ parse!
71
+
72
+ # Ensure it really succeeded.
73
+ if @conf.empty? or @conf.class != Hash
74
+ # Nope. Restore old configuration.
75
+ @conf = oldconf
76
+ $m.error("Failed to rehash the configuration file (parser produced empty config)! Reverting to old configuration.")
77
+ return 0
78
+ end
79
+
80
+ # bot:onRehash
81
+ $m.events.call('bot:onRehash')
82
+
83
+ # This rescue is applicable to anything that happens in here. Since if it is reached, there really was an error in general.
84
+ rescue => e
85
+ $m.error("Failed to rehash configuration file! Reverting to old configuration.", false, e.backtrace)
86
+ @conf = oldconf
87
+ return 0
88
+ end
89
+
90
+ # Return value of @conf[key].
91
+ #
92
+ # @return [Object] Value of @conf[key].
93
+ # @see @conf
94
+ def [] key
95
+ @conf[key]
96
+ end
97
+
98
+ #######
99
+ private
100
+ #######
101
+
102
+ # A constant for detecting comments and strings in JSON files
103
+ COMMENT_REGEXP = %r{(?:/\'(?:[^\'\\]|\\.)*\')|(?:\"(?:[^\"\\]|\\.)*\")|(?://.*\n)|(?:/\*(?m-ix:.)+?\*/)}
104
+
105
+ # Strip comments from JSON configuration text. This will not preserve
106
+ # the string passed to it.
107
+ #
108
+ # @argument [String] text The configuration data to strip.
109
+ #
110
+ # @return [String] The stripped configuration text.
111
+ def strip_js_comments! text
112
+ # Output string
113
+ out = ""
114
+ until (match_data = text.match(COMMENT_REGEXP)).nil?
115
+ off = match_data.offset(0)
116
+ # Check to see if it starts with /, if so then return up to the lower limit, otherwise to the upper.
117
+ out << text[0...off[(match_data.to_s[0] != '/') ? 1 : 0]]
118
+ # Delete the text that we were dealing with.
119
+ text[0...off[1]] = ''
120
+ end
121
+ # Append anything left
122
+ text = (out << text)
123
+ end
124
+
125
+ # The same as strip_js_comments! with original string preservation.
126
+ # @see strip_js_comments!
127
+ def strip_js_comments text
128
+ # Preserve
129
+ strip_js_comments!(text.clone)
130
+ end
131
+
132
+ # Parse the configuration file, and output the data to {#x}.
133
+ #
134
+ # @raise [ConfigError] If the file does not exist.
135
+ # @raise [ConfigError] If the file cannot be processed.
136
+ def parse!
137
+
138
+ # Ensure foremost that the configuration file exists.
139
+ unless File.exists? @path
140
+ raise ConfigError, "Configuration file '#@path' does not exist!"
141
+ end
142
+
143
+ # Get the data from the file.
144
+ f = File.open(@path)
145
+ data = f.read
146
+ f.close
147
+
148
+ conf = {}
149
+ # JSON
150
+ if @type == :json
151
+
152
+ # Strip comments out of the data.
153
+ data = strip_js_comments!(data)
154
+
155
+ # Process the JSON.
156
+ begin
157
+ conf = JSON.parse(data)
158
+ rescue => e
159
+ raise ConfigError, "Failed to process the JSON in '#@path'", e.backtrace
160
+ end
161
+
162
+ else # Must be YAML
163
+
164
+ # Process the YAML.
165
+ begin
166
+ conf = Psych.load data
167
+ rescue => e
168
+ raise ConfigError, "Failed to process the YAML in '#@path'", e.backtrace
169
+ end
170
+
171
+ end
172
+
173
+ @conf = conf
174
+
175
+ end # def parse
176
+
177
+ end # class Config
178
+
179
+ end # module Auto
180
+
181
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,410 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (LICENSE.md).
3
+
4
+ require 'colored'
5
+ require 'highline'
6
+ require 'yaml'
7
+
8
+ $S = '>>>'.blue
9
+
10
+
11
+ # Check To make sure that we have a decent ruby version. There is no reason to support a
12
+ # version that has reached EOL.
13
+ if RUBY_VERSION < "1.9"
14
+ puts <<-EOM
15
+ The version of ruby that you are using is out dated. Please upgrade to a version of at least
16
+ 1.9.1 to run auto. The ruby source code is located here http://ruby-lang.org/en/downloads
17
+ EOM
18
+ end
19
+
20
+ # namespace Auto
21
+ module Auto
22
+
23
+ # A library for configuration generation. It depends upon the highline gem.
24
+ #
25
+ # @version 1.02
26
+ # @author swarley
27
+ # @author noxgirl
28
+ #
29
+ # @!attribute hl
30
+ # @return [HighLine] HighLine instance.
31
+ #
32
+ # @!attribute conf
33
+ # @return [Hash{}] The configuration hash.
34
+ class Configure
35
+
36
+ autoload :Shell, 'auto/configure/shell'
37
+ # Load the shell.
38
+ def shell
39
+ Auto::Configure::Shell.new(@hl)
40
+ end
41
+
42
+ VERSION = '1.02'.freeze
43
+ AUTODIR = File.join(Dir.home, '.config', 'autobot')
44
+
45
+ attr_accessor :hl, :conf
46
+
47
+ # Produce a new instance of Auto::Configure.
48
+ def initialize
49
+
50
+ # Produce a new instance of HighLine.
51
+ @hl = HighLine.new
52
+ # Prepare for configuration.
53
+ @conf = Hash.new
54
+
55
+ end
56
+
57
+ # Initiate configuration.
58
+ def generate
59
+
60
+ greeting = <<-EOM
61
+ Greetings! ^.^
62
+
63
+ I am going to assist you in configuring your installation of Auto. :) I suggest
64
+ that, if you're not already reading it, you consult the installation guide:
65
+ https://github.com/Auto/Auto/wiki/Install-Guide
66
+
67
+ When specifying lists, separate elements by commas.
68
+
69
+ Remember, if you need additional help, you're free to use the mailing list at
70
+ https://groups.google.com/group/autobot-talk, or to join the official IRC
71
+ channel at #auto on irc.freenode.net. :)
72
+
73
+ Let us begin!
74
+ EOM
75
+ puts greeting.yellow.bold
76
+
77
+ conf_libraries
78
+ conf_database
79
+
80
+ dump
81
+
82
+ end
83
+
84
+ # Configure libraries.
85
+ def conf_libraries
86
+ puts ">>> Currently, the only available library is the IRC library. I will load this automatically.".cyan.bold
87
+ @conf['libraries'] = ['irc']
88
+
89
+ conf_irclib
90
+ end
91
+
92
+ # Configure the IRC library.
93
+ def conf_irclib
94
+
95
+ # Create the configuration hash.
96
+ @conf['irc'] = {}
97
+
98
+ # Add the first server.
99
+ conf_irc_add_server
100
+
101
+ # Add subsequent servers.
102
+ another = @hl.agree("#$S Would you like to add another IRC server? ") { |q| q.default = 'n' }
103
+ while another
104
+ conf_irc_add_server
105
+ another = @hl.agree("#$S Would you like to add another IRC server? ") { |q| q.default = 'n' }
106
+ end
107
+
108
+ end
109
+
110
+ # Add an IRC server.
111
+ def conf_irc_add_server
112
+
113
+ # We need a name.
114
+ name = @hl.ask("#$S What is the name of this IRC server? ")
115
+ while @conf['irc'].include? name
116
+ puts "You've already specified that server. Use a different name.".red.bold
117
+ name = @hl.ask("#$S What is the name of this IRC server?")
118
+ end
119
+
120
+ # We need an address.
121
+ address = @hl.ask("#$S What is the address of <%= color('#{name}', :blue, :bold) %>? ")
122
+
123
+ # And a port.
124
+ port = @hl.ask("#$S What is the port of <%= color('#{name}', :blue, :bold) %>? ", Integer) { |q| q.default = 6667 }
125
+
126
+ # Does it use SSL?
127
+ ssl = @hl.agree("#$S Does <%= color('#{address}:#{port}', :blue, :bold) %> use SSL? ") { |q| q.default = 'n' }
128
+
129
+ # What nickname(s) should we use?
130
+ nicks = @hl.ask("#$S What nicknames should I use on <%= color('#{name}', :blue, :bold) %> (list in descending priority)? ",
131
+ ->(str) { str.split(/,\s*/) }) { |q| q.default = 'auto' }
132
+ nicksvalid = true
133
+ nicks.each { |n| nicksvalid = false unless n =~ /^[\w\d\[\]\{\}\^\-\_\`]+$/ }
134
+ until nicksvalid
135
+ puts "You entered an invalid nickname. Try again.".red.bold
136
+ nicks = @hl.ask("#$S What nicknames should I use on <%= color('#{name}', :blue, :bold) %> (list in descending priority)? ",
137
+ ->(str) { str.split(/,\s*/) }) { |q| q.default = 'auto' }
138
+ nicksvalid = true
139
+ nicks.each { |n| nicksvalid = false unless n =~ /^[\w\d\[\]\{\}\^\-\_\`]+$/ }
140
+ end
141
+
142
+ # What username?
143
+ user = @hl.ask("#$S What username should I use on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'auto' }
144
+
145
+ # What GECOS?
146
+ gecos = @hl.ask("#$S What real name or GECOS should I use on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'Auto (http://auto.autoproj.org)' }
147
+
148
+ # Save the data.
149
+ @conf['irc'][name] = {
150
+ 'address' => address,
151
+ 'port' => port,
152
+ 'useSSL' => ssl,
153
+ 'nickname' => nicks,
154
+ 'username' => user,
155
+ 'realName' => gecos
156
+ }
157
+
158
+ # Should we use SASL?
159
+ sasl = @hl.agree("#$S Should I use SASL to authenticate with services on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'n' }
160
+
161
+ if sasl
162
+
163
+ sasl_user = @hl.ask("#$S What username (i.e. accountname) should I use in SASL authentication? ")
164
+ sasl_pass = @hl.ask("#$S What is the password for <%= color('#{sasl_user}', :blue, :bold) %>? ") { |q| q.echo = false }
165
+ sasl_to = @hl.ask("#$S After how many seconds should SASL authentication time out? ", Integer) { |q| q.default = 15 }
166
+
167
+ @conf['irc'][name]['SASL'] = {
168
+ 'username' => sasl_user,
169
+ 'password' => sasl_pass,
170
+ 'timeout' => sasl_to,
171
+ }
172
+
173
+ else
174
+ # Perhaps NickServ or some other service?
175
+ auth = @hl.agree("#$S OK. Should I identify with a service (e.g. NickServ)? ") { |q| q.default = 'n' }
176
+
177
+ if auth
178
+
179
+ service = @hl.ask("#$S What service should I message? ") { |q| q.default = 'NickServ' }
180
+ command = @hl.ask("#$S What command should I use to identify? ") { |q| q.default = 'IDENTIFY' }
181
+ password = @hl.ask("#$S What password should I use? ") { |q| q.echo = false }
182
+
183
+ @conf['irc'][name]['nickIdentify'] = {
184
+ 'service' => service,
185
+ 'command' => command,
186
+ 'password' => password
187
+ }
188
+
189
+ end
190
+
191
+ end
192
+
193
+ # Setup autojoin.
194
+ conf_irc_autojoin name
195
+
196
+ end
197
+
198
+ # Configure autojoin.
199
+ #
200
+ # @param [String] name Name of IRC server.
201
+ def conf_irc_autojoin(name)
202
+ another = @hl.agree("#$S Should I automatically join a channel on <%= color('#{name}', :blue, :bold) %>? ") { |q| q.default = 'y' }
203
+ @conf['irc'][name]['autojoin'] = []
204
+
205
+ while another
206
+ @conf['irc'][name]['autojoin'] << conf_irc_add_channel
207
+ another = @hl.agree("#$S Should I automatically join another channel? ") { |q| q.default = 'n' }
208
+ end
209
+ end
210
+
211
+ # Add an IRC channel.
212
+ #
213
+ # @param [String] server The name of the IRC server.
214
+ def conf_irc_add_channel
215
+
216
+ # What's it called?
217
+ name = @hl.ask("#$S What is the name of the channel? ") { |q| q.default = '#auto' }
218
+
219
+ # Does it use a key?
220
+ usekey = @hl.agree("#$S Does <%= color('#{name}', :blue, :bold) %> use a key (+k)? ") { |q| q.default = 'n' }
221
+ key = nil
222
+
223
+ if usekey
224
+ key = @hl.ask("#$S What is the key? ")
225
+ end
226
+
227
+ {'name' => name, 'key' => key}
228
+ end
229
+
230
+ # Configure the database.
231
+ def conf_database
232
+ @conf['database'] = Hash.new
233
+
234
+ msg = <<-eom
235
+ >> Auto supports three database management systems: SQLite 3, MySQL, and Postgres.
236
+ >> If you use SQLite 3, you need the 'sqlite3' gem.
237
+ >> If you use MySQL, you need the 'mysqlplus' gem.
238
+ >> If you use Postgres, you need the 'pg' gem.
239
+ >> See https://github.com/Auto/Auto/wiki/Install-Guide for more information.
240
+ eom
241
+ puts msg.cyan
242
+
243
+ type = @hl.ask("#$S What database management system should I use? (sqlite, mysql, or postgres) ") do |q|
244
+ q.default = 'sqlite'
245
+ q.validate = /^(sqlite|mysql|postgres)$/
246
+ end
247
+ @conf['database']['type'] = type
248
+
249
+ if type == 'sqlite'
250
+
251
+ file = @hl.ask("#$S What should be the filename of the database? (relative to <%= color('#{AUTODIR}', :blue, :bold) %>) ") do |q|
252
+ q.default = File.join AUTODIR, 'auto.db'
253
+ end
254
+
255
+ unless Dir.exists File.dirname(file)
256
+ puts "Warning: Directory #{File.dirname(file)} does not exist.".red.bold
257
+ end
258
+
259
+ @conf['database']['name'] = file
260
+
261
+ else # mysql and pg
262
+
263
+ address = @hl.ask("#$S What is the host address of the <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'localhost' }
264
+ name = @hl.ask("#$S What is the database name on the <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'auto' }
265
+ username = @hl.ask("#$S What username should I use to connect to <%= color('#{type}', :blue, :bold) %> server? ") { |q| q.default = 'auto' }
266
+ password = @hl.ask("#$S What is the password for <%= color('#{username}', :blue, :bold) %>? ") { |q| q.echo = false }
267
+
268
+ @conf['database'].merge!({
269
+ 'address' => address,
270
+ 'name' => name,
271
+ 'username' => username,
272
+ 'password' => password
273
+ })
274
+
275
+ end
276
+
277
+ end
278
+
279
+ # Dump configuration.
280
+ def dump
281
+
282
+ # A sanity check.
283
+ if @conf.empty?
284
+ puts "Configuration is inexplicably empty: aborting.".red.bold
285
+ exit 1
286
+ end
287
+
288
+ # Produce file.
289
+ data = <<-EOD
290
+ # Configuration file generated by auto-conf
291
+ # version #{Auto::Configure::VERSION}
292
+ # at #{Time.now}
293
+
294
+ #{YAML.dump(@conf)}
295
+ EOD
296
+
297
+ # Produce message.
298
+ final = <<-EOM
299
+ OK! Your configuration file is ready! :D
300
+
301
+ I just need to know one last thing: where to write this fabulous configuration.
302
+
303
+ By default, I will write this to <YOUR_HOME_DIRECTORY>/.config/autobot/auto.yml,
304
+ which is perfect for you if you're using the 'autobot' gem, because this is the
305
+ standard file for which the gem will look when executed.
306
+
307
+ However, if you are running a standalone installation, you probably want to
308
+ write this to your conf/ directory as auto.yml (if you're running #$0 from the
309
+ main directory, "conf/auto.yml"), as the standalone Auto will look for that
310
+ when it is executed.
311
+
312
+ In any event, you are free to write this anywhere you please. Just remember
313
+ that if it is not a default path, you must specify it when running Auto:
314
+
315
+ $ auto --config=path/to/config/file.yml
316
+
317
+ Caution: The specified file will be overwritten if it already exists.
318
+ EOM
319
+ puts final.green.bold
320
+
321
+ # Save our directories of interest into easily accessible variables.
322
+ configdir = File.join(Dir.home, '.config')
323
+
324
+ # Ensure that said directories exist regardless of any other conditions.
325
+ unless Dir.exists? configdir
326
+ puts "~ Creating missing directory #{configdir}".magenta
327
+ Dir.mkdir configdir
328
+ end
329
+ unless Dir.exists? AUTODIR
330
+ puts "~ Creating missing directory #{AUTODIR}".magenta
331
+ Dir.mkdir AUTODIR
332
+ end
333
+
334
+ # Ask for a path.
335
+ path = @hl.ask("#$S To where should the configuration be written? ", String) do |q|
336
+
337
+ # Default is ~/.config/autobot/auto.yml
338
+ q.default = File.join(autodir, 'auto.yml')
339
+
340
+ # A proc to validate the path
341
+ q.validate = proc do |path|
342
+ return false unless path =~ /\.yml$/ # it should end in .yml
343
+ return false unless Dir.exists? File.dirname(path) # the directory should exist
344
+ # We should be able to write to the file:
345
+ begin
346
+ File.open(path, 'w') { |io| io.puts "# Configuration file generated by auto-conf" }
347
+ rescue => e
348
+ return false
349
+ end
350
+ true
351
+ end
352
+
353
+ # A proc to be called in the event of an invalid path
354
+ q.responses[:not_valid] = proc do
355
+
356
+ # Choose an emergency file in ~/.config/autobot/ to which to save.
357
+ emerg_file = File.join(autodir, "auto.yml.#{Time.now.strftime('%s')}")
358
+ puts "Invalid path! Attempting to write to #{emerg_file}.....".red
359
+ File.open(path, 'w') do |io|
360
+ io.write data
361
+ end
362
+
363
+ end
364
+
365
+ end # ask()
366
+
367
+ File.open(path, 'w') { |io| io.write data } # Dump the data into the file.
368
+
369
+ # We're done.
370
+ puts "I have successfully written your configuration file to #{path}. Thank you for using Auto.".green.bold
371
+
372
+ end
373
+
374
+ end # class Configure
375
+
376
+ end # module Auto
377
+
378
+ # This will fix a certain undesirable output.
379
+ #
380
+ # HighLine::Question#append_default appends an ugly manifestation of the
381
+ # default answer.
382
+ #
383
+ # This destroys that provided by HighLine::Question and in lieu uses a prettier
384
+ # one.
385
+ class HighLine
386
+ class Question
387
+ def append_default
388
+ str = ''
389
+ if @default == 'y'
390
+ str = "<%= color('Y', :green) %>/<%= color('n', :red) %>"
391
+ elsif @default == 'n'
392
+ str = "<%= color('y', :green) %>/<%= color('N', :red) %>"
393
+ else
394
+ str = "<%= color('#@default', :bold) %>"
395
+ end
396
+
397
+ if @question =~ /([\t ]+)\Z/
398
+ @question << "[#{str}]#{$1}"
399
+ elsif @question == ""
400
+ @question << "[#{str}] "
401
+ elsif @question[-1, 1] == "\n"
402
+ @question[-2, 0] = " [#{str}]"
403
+ else
404
+ @question << " [#{str}]"
405
+ end
406
+ end
407
+ end
408
+ end
409
+
410
+ # vim: set ts=4 sts=2 sw=2 et: