honeybadger 4.12.2 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +713 -673
- data/LICENSE +19 -19
- data/README.md +57 -57
- data/TROUBLESHOOTING.md +3 -3
- data/bin/honeybadger +5 -5
- data/lib/honeybadger/agent.rb +488 -481
- data/lib/honeybadger/backend/base.rb +116 -116
- data/lib/honeybadger/backend/debug.rb +22 -22
- data/lib/honeybadger/backend/null.rb +29 -29
- data/lib/honeybadger/backend/server.rb +62 -62
- data/lib/honeybadger/backend/test.rb +46 -45
- data/lib/honeybadger/backend.rb +27 -27
- data/lib/honeybadger/backtrace.rb +181 -181
- data/lib/honeybadger/breadcrumbs/active_support.rb +119 -119
- data/lib/honeybadger/breadcrumbs/breadcrumb.rb +53 -53
- data/lib/honeybadger/breadcrumbs/collector.rb +82 -82
- data/lib/honeybadger/breadcrumbs/logging.rb +51 -51
- data/lib/honeybadger/breadcrumbs/ring_buffer.rb +44 -44
- data/lib/honeybadger/breadcrumbs.rb +8 -8
- data/lib/honeybadger/cli/deploy.rb +43 -43
- data/lib/honeybadger/cli/exec.rb +143 -143
- data/lib/honeybadger/cli/helpers.rb +28 -28
- data/lib/honeybadger/cli/heroku.rb +129 -129
- data/lib/honeybadger/cli/install.rb +101 -101
- data/lib/honeybadger/cli/main.rb +237 -237
- data/lib/honeybadger/cli/notify.rb +67 -67
- data/lib/honeybadger/cli/test.rb +267 -267
- data/lib/honeybadger/cli.rb +14 -14
- data/lib/honeybadger/config/defaults.rb +336 -327
- data/lib/honeybadger/config/env.rb +42 -42
- data/lib/honeybadger/config/ruby.rb +146 -146
- data/lib/honeybadger/config/yaml.rb +76 -76
- data/lib/honeybadger/config.rb +413 -413
- data/lib/honeybadger/const.rb +20 -20
- data/lib/honeybadger/context_manager.rb +55 -55
- data/lib/honeybadger/conversions.rb +16 -16
- data/lib/honeybadger/init/rails.rb +38 -35
- data/lib/honeybadger/init/rake.rb +66 -66
- data/lib/honeybadger/init/ruby.rb +11 -11
- data/lib/honeybadger/init/sinatra.rb +51 -51
- data/lib/honeybadger/logging.rb +177 -177
- data/lib/honeybadger/notice.rb +579 -568
- data/lib/honeybadger/plugin.rb +210 -210
- data/lib/honeybadger/plugins/breadcrumbs.rb +111 -111
- data/lib/honeybadger/plugins/delayed_job/plugin.rb +56 -56
- data/lib/honeybadger/plugins/delayed_job.rb +22 -22
- data/lib/honeybadger/plugins/faktory.rb +52 -52
- data/lib/honeybadger/plugins/lambda.rb +71 -71
- data/lib/honeybadger/plugins/local_variables.rb +44 -44
- data/lib/honeybadger/plugins/passenger.rb +23 -23
- data/lib/honeybadger/plugins/rails.rb +72 -48
- data/lib/honeybadger/plugins/resque.rb +72 -72
- data/lib/honeybadger/plugins/shoryuken.rb +52 -52
- data/lib/honeybadger/plugins/sidekiq.rb +71 -62
- data/lib/honeybadger/plugins/sucker_punch.rb +18 -18
- data/lib/honeybadger/plugins/thor.rb +32 -32
- data/lib/honeybadger/plugins/warden.rb +19 -19
- data/lib/honeybadger/rack/error_notifier.rb +92 -92
- data/lib/honeybadger/rack/user_feedback.rb +88 -88
- data/lib/honeybadger/rack/user_informer.rb +45 -45
- data/lib/honeybadger/ruby.rb +2 -2
- data/lib/honeybadger/singleton.rb +103 -103
- data/lib/honeybadger/tasks.rb +22 -22
- data/lib/honeybadger/templates/feedback_form.erb +84 -84
- data/lib/honeybadger/util/http.rb +92 -92
- data/lib/honeybadger/util/lambda.rb +32 -32
- data/lib/honeybadger/util/request_hash.rb +73 -73
- data/lib/honeybadger/util/request_payload.rb +41 -41
- data/lib/honeybadger/util/revision.rb +39 -39
- data/lib/honeybadger/util/sanitizer.rb +214 -214
- data/lib/honeybadger/util/sql.rb +34 -34
- data/lib/honeybadger/util/stats.rb +50 -50
- data/lib/honeybadger/version.rb +4 -4
- data/lib/honeybadger/worker.rb +253 -253
- data/lib/honeybadger.rb +11 -11
- data/resources/ca-bundle.crt +3376 -3376
- data/vendor/capistrano-honeybadger/lib/capistrano/honeybadger.rb +5 -5
- data/vendor/capistrano-honeybadger/lib/capistrano/tasks/deploy.cap +89 -89
- data/vendor/capistrano-honeybadger/lib/honeybadger/capistrano/legacy.rb +47 -47
- data/vendor/capistrano-honeybadger/lib/honeybadger/capistrano.rb +2 -2
- data/vendor/cli/inifile.rb +628 -628
- data/vendor/cli/thor/actions/create_file.rb +103 -103
- data/vendor/cli/thor/actions/create_link.rb +59 -59
- data/vendor/cli/thor/actions/directory.rb +118 -118
- data/vendor/cli/thor/actions/empty_directory.rb +135 -135
- data/vendor/cli/thor/actions/file_manipulation.rb +316 -316
- data/vendor/cli/thor/actions/inject_into_file.rb +107 -107
- data/vendor/cli/thor/actions.rb +319 -319
- data/vendor/cli/thor/base.rb +656 -656
- data/vendor/cli/thor/command.rb +133 -133
- data/vendor/cli/thor/core_ext/hash_with_indifferent_access.rb +77 -77
- data/vendor/cli/thor/core_ext/io_binary_read.rb +10 -10
- data/vendor/cli/thor/core_ext/ordered_hash.rb +98 -98
- data/vendor/cli/thor/error.rb +32 -32
- data/vendor/cli/thor/group.rb +281 -281
- data/vendor/cli/thor/invocation.rb +178 -178
- data/vendor/cli/thor/line_editor/basic.rb +35 -35
- data/vendor/cli/thor/line_editor/readline.rb +88 -88
- data/vendor/cli/thor/line_editor.rb +17 -17
- data/vendor/cli/thor/parser/argument.rb +73 -73
- data/vendor/cli/thor/parser/arguments.rb +175 -175
- data/vendor/cli/thor/parser/option.rb +125 -125
- data/vendor/cli/thor/parser/options.rb +218 -218
- data/vendor/cli/thor/parser.rb +4 -4
- data/vendor/cli/thor/rake_compat.rb +71 -71
- data/vendor/cli/thor/runner.rb +322 -322
- data/vendor/cli/thor/shell/basic.rb +421 -421
- data/vendor/cli/thor/shell/color.rb +149 -149
- data/vendor/cli/thor/shell/html.rb +126 -126
- data/vendor/cli/thor/shell.rb +81 -81
- data/vendor/cli/thor/util.rb +267 -267
- data/vendor/cli/thor/version.rb +3 -3
- data/vendor/cli/thor.rb +484 -484
- metadata +10 -5
@@ -1,178 +1,178 @@
|
|
1
|
-
class Thor
|
2
|
-
module Invocation
|
3
|
-
def self.included(base) #:nodoc:
|
4
|
-
base.extend ClassMethods
|
5
|
-
end
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
# This method is responsible for receiving a name and find the proper
|
9
|
-
# class and command for it. The key is an optional parameter which is
|
10
|
-
# available only in class methods invocations (i.e. in Thor::Group).
|
11
|
-
def prepare_for_invocation(key, name) #:nodoc:
|
12
|
-
case name
|
13
|
-
when Symbol, String
|
14
|
-
Thor::Util.find_class_and_command_by_namespace(name.to_s, !key)
|
15
|
-
else
|
16
|
-
name
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Make initializer aware of invocations and the initialization args.
|
22
|
-
def initialize(args = [], options = {}, config = {}, &block) #:nodoc:
|
23
|
-
@_invocations = config[:invocations] || Hash.new { |h, k| h[k] = [] }
|
24
|
-
@_initializer = [args, options, config]
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
# Make the current command chain accessible with in a Thor-(sub)command
|
29
|
-
def current_command_chain
|
30
|
-
@_invocations.values.flatten.map(&:to_sym)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Receives a name and invokes it. The name can be a string (either "command" or
|
34
|
-
# "namespace:command"), a Thor::Command, a Class or a Thor instance. If the
|
35
|
-
# command cannot be guessed by name, it can also be supplied as second argument.
|
36
|
-
#
|
37
|
-
# You can also supply the arguments, options and configuration values for
|
38
|
-
# the command to be invoked, if none is given, the same values used to
|
39
|
-
# initialize the invoker are used to initialize the invoked.
|
40
|
-
#
|
41
|
-
# When no name is given, it will invoke the default command of the current class.
|
42
|
-
#
|
43
|
-
# ==== Examples
|
44
|
-
#
|
45
|
-
# class A < Thor
|
46
|
-
# def foo
|
47
|
-
# invoke :bar
|
48
|
-
# invoke "b:hello", ["Erik"]
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# def bar
|
52
|
-
# invoke "b:hello", ["Erik"]
|
53
|
-
# end
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# class B < Thor
|
57
|
-
# def hello(name)
|
58
|
-
# puts "hello #{name}"
|
59
|
-
# end
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# You can notice that the method "foo" above invokes two commands: "bar",
|
63
|
-
# which belongs to the same class and "hello" which belongs to the class B.
|
64
|
-
#
|
65
|
-
# By using an invocation system you ensure that a command is invoked only once.
|
66
|
-
# In the example above, invoking "foo" will invoke "b:hello" just once, even
|
67
|
-
# if it's invoked later by "bar" method.
|
68
|
-
#
|
69
|
-
# When class A invokes class B, all arguments used on A initialization are
|
70
|
-
# supplied to B. This allows lazy parse of options. Let's suppose you have
|
71
|
-
# some rspec commands:
|
72
|
-
#
|
73
|
-
# class Rspec < Thor::Group
|
74
|
-
# class_option :mock_framework, :type => :string, :default => :rr
|
75
|
-
#
|
76
|
-
# def invoke_mock_framework
|
77
|
-
# invoke "rspec:#{options[:mock_framework]}"
|
78
|
-
# end
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# As you noticed, it invokes the given mock framework, which might have its
|
82
|
-
# own options:
|
83
|
-
#
|
84
|
-
# class Rspec::RR < Thor::Group
|
85
|
-
# class_option :style, :type => :string, :default => :mock
|
86
|
-
# end
|
87
|
-
#
|
88
|
-
# Since it's not rspec concern to parse mock framework options, when RR
|
89
|
-
# is invoked all options are parsed again, so RR can extract only the options
|
90
|
-
# that it's going to use.
|
91
|
-
#
|
92
|
-
# If you want Rspec::RR to be initialized with its own set of options, you
|
93
|
-
# have to do that explicitly:
|
94
|
-
#
|
95
|
-
# invoke "rspec:rr", [], :style => :foo
|
96
|
-
#
|
97
|
-
# Besides giving an instance, you can also give a class to invoke:
|
98
|
-
#
|
99
|
-
# invoke Rspec::RR, [], :style => :foo
|
100
|
-
#
|
101
|
-
def invoke(name = nil, *args)
|
102
|
-
if name.nil?
|
103
|
-
warn "[Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}"
|
104
|
-
return invoke_all
|
105
|
-
end
|
106
|
-
|
107
|
-
args.unshift(nil) if args.first.is_a?(Array) || args.first.nil?
|
108
|
-
command, args, opts, config = args
|
109
|
-
|
110
|
-
klass, command = _retrieve_class_and_command(name, command)
|
111
|
-
fail "Missing Thor class for invoke #{name}" unless klass
|
112
|
-
fail "Expected Thor class, got #{klass}" unless klass <= Thor::Base
|
113
|
-
|
114
|
-
args, opts, config = _parse_initialization_options(args, opts, config)
|
115
|
-
klass.send(:dispatch, command, args, opts, config) do |instance|
|
116
|
-
instance.parent_options = options
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# Invoke the given command if the given args.
|
121
|
-
def invoke_command(command, *args) #:nodoc:
|
122
|
-
current = @_invocations[self.class]
|
123
|
-
|
124
|
-
unless current.include?(command.name)
|
125
|
-
current << command.name
|
126
|
-
command.run(self, *args)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
alias_method :invoke_task, :invoke_command
|
130
|
-
|
131
|
-
# Invoke all commands for the current instance.
|
132
|
-
def invoke_all #:nodoc:
|
133
|
-
self.class.all_commands.map { |_, command| invoke_command(command) }
|
134
|
-
end
|
135
|
-
|
136
|
-
# Invokes using shell padding.
|
137
|
-
def invoke_with_padding(*args)
|
138
|
-
with_padding { invoke(*args) }
|
139
|
-
end
|
140
|
-
|
141
|
-
protected
|
142
|
-
|
143
|
-
# Configuration values that are shared between invocations.
|
144
|
-
def _shared_configuration #:nodoc:
|
145
|
-
{:invocations => @_invocations}
|
146
|
-
end
|
147
|
-
|
148
|
-
# This method simply retrieves the class and command to be invoked.
|
149
|
-
# If the name is nil or the given name is a command in the current class,
|
150
|
-
# use the given name and return self as class. Otherwise, call
|
151
|
-
# prepare_for_invocation in the current class.
|
152
|
-
def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
|
153
|
-
case
|
154
|
-
when name.nil?
|
155
|
-
[self.class, nil]
|
156
|
-
when self.class.all_commands[name.to_s]
|
157
|
-
[self.class, name.to_s]
|
158
|
-
else
|
159
|
-
klass, command = self.class.prepare_for_invocation(nil, name)
|
160
|
-
[klass, command || sent_command]
|
161
|
-
end
|
162
|
-
end
|
163
|
-
alias_method :_retrieve_class_and_task, :_retrieve_class_and_command
|
164
|
-
|
165
|
-
# Initialize klass using values stored in the @_initializer.
|
166
|
-
def _parse_initialization_options(args, opts, config) #:nodoc:
|
167
|
-
stored_args, stored_opts, stored_config = @_initializer
|
168
|
-
|
169
|
-
args ||= stored_args.dup
|
170
|
-
opts ||= stored_opts.dup
|
171
|
-
|
172
|
-
config ||= {}
|
173
|
-
config = stored_config.merge(_shared_configuration).merge!(config)
|
174
|
-
|
175
|
-
[args, opts, config]
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
1
|
+
class Thor
|
2
|
+
module Invocation
|
3
|
+
def self.included(base) #:nodoc:
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# This method is responsible for receiving a name and find the proper
|
9
|
+
# class and command for it. The key is an optional parameter which is
|
10
|
+
# available only in class methods invocations (i.e. in Thor::Group).
|
11
|
+
def prepare_for_invocation(key, name) #:nodoc:
|
12
|
+
case name
|
13
|
+
when Symbol, String
|
14
|
+
Thor::Util.find_class_and_command_by_namespace(name.to_s, !key)
|
15
|
+
else
|
16
|
+
name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Make initializer aware of invocations and the initialization args.
|
22
|
+
def initialize(args = [], options = {}, config = {}, &block) #:nodoc:
|
23
|
+
@_invocations = config[:invocations] || Hash.new { |h, k| h[k] = [] }
|
24
|
+
@_initializer = [args, options, config]
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
# Make the current command chain accessible with in a Thor-(sub)command
|
29
|
+
def current_command_chain
|
30
|
+
@_invocations.values.flatten.map(&:to_sym)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Receives a name and invokes it. The name can be a string (either "command" or
|
34
|
+
# "namespace:command"), a Thor::Command, a Class or a Thor instance. If the
|
35
|
+
# command cannot be guessed by name, it can also be supplied as second argument.
|
36
|
+
#
|
37
|
+
# You can also supply the arguments, options and configuration values for
|
38
|
+
# the command to be invoked, if none is given, the same values used to
|
39
|
+
# initialize the invoker are used to initialize the invoked.
|
40
|
+
#
|
41
|
+
# When no name is given, it will invoke the default command of the current class.
|
42
|
+
#
|
43
|
+
# ==== Examples
|
44
|
+
#
|
45
|
+
# class A < Thor
|
46
|
+
# def foo
|
47
|
+
# invoke :bar
|
48
|
+
# invoke "b:hello", ["Erik"]
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def bar
|
52
|
+
# invoke "b:hello", ["Erik"]
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# class B < Thor
|
57
|
+
# def hello(name)
|
58
|
+
# puts "hello #{name}"
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# You can notice that the method "foo" above invokes two commands: "bar",
|
63
|
+
# which belongs to the same class and "hello" which belongs to the class B.
|
64
|
+
#
|
65
|
+
# By using an invocation system you ensure that a command is invoked only once.
|
66
|
+
# In the example above, invoking "foo" will invoke "b:hello" just once, even
|
67
|
+
# if it's invoked later by "bar" method.
|
68
|
+
#
|
69
|
+
# When class A invokes class B, all arguments used on A initialization are
|
70
|
+
# supplied to B. This allows lazy parse of options. Let's suppose you have
|
71
|
+
# some rspec commands:
|
72
|
+
#
|
73
|
+
# class Rspec < Thor::Group
|
74
|
+
# class_option :mock_framework, :type => :string, :default => :rr
|
75
|
+
#
|
76
|
+
# def invoke_mock_framework
|
77
|
+
# invoke "rspec:#{options[:mock_framework]}"
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# As you noticed, it invokes the given mock framework, which might have its
|
82
|
+
# own options:
|
83
|
+
#
|
84
|
+
# class Rspec::RR < Thor::Group
|
85
|
+
# class_option :style, :type => :string, :default => :mock
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# Since it's not rspec concern to parse mock framework options, when RR
|
89
|
+
# is invoked all options are parsed again, so RR can extract only the options
|
90
|
+
# that it's going to use.
|
91
|
+
#
|
92
|
+
# If you want Rspec::RR to be initialized with its own set of options, you
|
93
|
+
# have to do that explicitly:
|
94
|
+
#
|
95
|
+
# invoke "rspec:rr", [], :style => :foo
|
96
|
+
#
|
97
|
+
# Besides giving an instance, you can also give a class to invoke:
|
98
|
+
#
|
99
|
+
# invoke Rspec::RR, [], :style => :foo
|
100
|
+
#
|
101
|
+
def invoke(name = nil, *args)
|
102
|
+
if name.nil?
|
103
|
+
warn "[Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}"
|
104
|
+
return invoke_all
|
105
|
+
end
|
106
|
+
|
107
|
+
args.unshift(nil) if args.first.is_a?(Array) || args.first.nil?
|
108
|
+
command, args, opts, config = args
|
109
|
+
|
110
|
+
klass, command = _retrieve_class_and_command(name, command)
|
111
|
+
fail "Missing Thor class for invoke #{name}" unless klass
|
112
|
+
fail "Expected Thor class, got #{klass}" unless klass <= Thor::Base
|
113
|
+
|
114
|
+
args, opts, config = _parse_initialization_options(args, opts, config)
|
115
|
+
klass.send(:dispatch, command, args, opts, config) do |instance|
|
116
|
+
instance.parent_options = options
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Invoke the given command if the given args.
|
121
|
+
def invoke_command(command, *args) #:nodoc:
|
122
|
+
current = @_invocations[self.class]
|
123
|
+
|
124
|
+
unless current.include?(command.name)
|
125
|
+
current << command.name
|
126
|
+
command.run(self, *args)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
alias_method :invoke_task, :invoke_command
|
130
|
+
|
131
|
+
# Invoke all commands for the current instance.
|
132
|
+
def invoke_all #:nodoc:
|
133
|
+
self.class.all_commands.map { |_, command| invoke_command(command) }
|
134
|
+
end
|
135
|
+
|
136
|
+
# Invokes using shell padding.
|
137
|
+
def invoke_with_padding(*args)
|
138
|
+
with_padding { invoke(*args) }
|
139
|
+
end
|
140
|
+
|
141
|
+
protected
|
142
|
+
|
143
|
+
# Configuration values that are shared between invocations.
|
144
|
+
def _shared_configuration #:nodoc:
|
145
|
+
{:invocations => @_invocations}
|
146
|
+
end
|
147
|
+
|
148
|
+
# This method simply retrieves the class and command to be invoked.
|
149
|
+
# If the name is nil or the given name is a command in the current class,
|
150
|
+
# use the given name and return self as class. Otherwise, call
|
151
|
+
# prepare_for_invocation in the current class.
|
152
|
+
def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
|
153
|
+
case
|
154
|
+
when name.nil?
|
155
|
+
[self.class, nil]
|
156
|
+
when self.class.all_commands[name.to_s]
|
157
|
+
[self.class, name.to_s]
|
158
|
+
else
|
159
|
+
klass, command = self.class.prepare_for_invocation(nil, name)
|
160
|
+
[klass, command || sent_command]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
alias_method :_retrieve_class_and_task, :_retrieve_class_and_command
|
164
|
+
|
165
|
+
# Initialize klass using values stored in the @_initializer.
|
166
|
+
def _parse_initialization_options(args, opts, config) #:nodoc:
|
167
|
+
stored_args, stored_opts, stored_config = @_initializer
|
168
|
+
|
169
|
+
args ||= stored_args.dup
|
170
|
+
opts ||= stored_opts.dup
|
171
|
+
|
172
|
+
config ||= {}
|
173
|
+
config = stored_config.merge(_shared_configuration).merge!(config)
|
174
|
+
|
175
|
+
[args, opts, config]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -1,35 +1,35 @@
|
|
1
|
-
class Thor
|
2
|
-
module LineEditor
|
3
|
-
class Basic
|
4
|
-
attr_reader :prompt, :options
|
5
|
-
|
6
|
-
def self.available?
|
7
|
-
true
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(prompt, options)
|
11
|
-
@prompt = prompt
|
12
|
-
@options = options
|
13
|
-
end
|
14
|
-
|
15
|
-
def readline
|
16
|
-
$stdout.print(prompt)
|
17
|
-
get_input
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def get_input
|
23
|
-
if echo?
|
24
|
-
$stdin.gets
|
25
|
-
else
|
26
|
-
$stdin.noecho(&:gets)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def echo?
|
31
|
-
options.fetch(:echo, true)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
1
|
+
class Thor
|
2
|
+
module LineEditor
|
3
|
+
class Basic
|
4
|
+
attr_reader :prompt, :options
|
5
|
+
|
6
|
+
def self.available?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(prompt, options)
|
11
|
+
@prompt = prompt
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def readline
|
16
|
+
$stdout.print(prompt)
|
17
|
+
get_input
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def get_input
|
23
|
+
if echo?
|
24
|
+
$stdin.gets
|
25
|
+
else
|
26
|
+
$stdin.noecho(&:gets)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def echo?
|
31
|
+
options.fetch(:echo, true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,88 +1,88 @@
|
|
1
|
-
begin
|
2
|
-
require "readline"
|
3
|
-
rescue LoadError
|
4
|
-
end
|
5
|
-
|
6
|
-
class Thor
|
7
|
-
module LineEditor
|
8
|
-
class Readline < Basic
|
9
|
-
def self.available?
|
10
|
-
Object.const_defined?(:Readline)
|
11
|
-
end
|
12
|
-
|
13
|
-
def readline
|
14
|
-
if echo?
|
15
|
-
::Readline.completion_append_character = nil
|
16
|
-
# Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
|
17
|
-
if complete = completion_proc
|
18
|
-
::Readline.completion_proc = complete
|
19
|
-
end
|
20
|
-
::Readline.readline(prompt, add_to_history?)
|
21
|
-
else
|
22
|
-
super
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def add_to_history?
|
29
|
-
options.fetch(:add_to_history, true)
|
30
|
-
end
|
31
|
-
|
32
|
-
def completion_proc
|
33
|
-
if use_path_completion?
|
34
|
-
proc { |text| PathCompletion.new(text).matches }
|
35
|
-
elsif completion_options.any?
|
36
|
-
proc do |text|
|
37
|
-
completion_options.select { |option| option.start_with?(text) }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def completion_options
|
43
|
-
options.fetch(:limited_to, [])
|
44
|
-
end
|
45
|
-
|
46
|
-
def use_path_completion?
|
47
|
-
options.fetch(:path, false)
|
48
|
-
end
|
49
|
-
|
50
|
-
class PathCompletion
|
51
|
-
attr_reader :text
|
52
|
-
private :text
|
53
|
-
|
54
|
-
def initialize(text)
|
55
|
-
@text = text
|
56
|
-
end
|
57
|
-
|
58
|
-
def matches
|
59
|
-
relative_matches
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def relative_matches
|
65
|
-
absolute_matches.map { |path| path.sub(base_path, "") }
|
66
|
-
end
|
67
|
-
|
68
|
-
def absolute_matches
|
69
|
-
Dir[glob_pattern].map do |path|
|
70
|
-
if File.directory?(path)
|
71
|
-
"#{path}/"
|
72
|
-
else
|
73
|
-
path
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def glob_pattern
|
79
|
-
"#{base_path}#{text}*"
|
80
|
-
end
|
81
|
-
|
82
|
-
def base_path
|
83
|
-
"#{Dir.pwd}/"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
1
|
+
begin
|
2
|
+
require "readline"
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
6
|
+
class Thor
|
7
|
+
module LineEditor
|
8
|
+
class Readline < Basic
|
9
|
+
def self.available?
|
10
|
+
Object.const_defined?(:Readline)
|
11
|
+
end
|
12
|
+
|
13
|
+
def readline
|
14
|
+
if echo?
|
15
|
+
::Readline.completion_append_character = nil
|
16
|
+
# Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
|
17
|
+
if complete = completion_proc
|
18
|
+
::Readline.completion_proc = complete
|
19
|
+
end
|
20
|
+
::Readline.readline(prompt, add_to_history?)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def add_to_history?
|
29
|
+
options.fetch(:add_to_history, true)
|
30
|
+
end
|
31
|
+
|
32
|
+
def completion_proc
|
33
|
+
if use_path_completion?
|
34
|
+
proc { |text| PathCompletion.new(text).matches }
|
35
|
+
elsif completion_options.any?
|
36
|
+
proc do |text|
|
37
|
+
completion_options.select { |option| option.start_with?(text) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def completion_options
|
43
|
+
options.fetch(:limited_to, [])
|
44
|
+
end
|
45
|
+
|
46
|
+
def use_path_completion?
|
47
|
+
options.fetch(:path, false)
|
48
|
+
end
|
49
|
+
|
50
|
+
class PathCompletion
|
51
|
+
attr_reader :text
|
52
|
+
private :text
|
53
|
+
|
54
|
+
def initialize(text)
|
55
|
+
@text = text
|
56
|
+
end
|
57
|
+
|
58
|
+
def matches
|
59
|
+
relative_matches
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def relative_matches
|
65
|
+
absolute_matches.map { |path| path.sub(base_path, "") }
|
66
|
+
end
|
67
|
+
|
68
|
+
def absolute_matches
|
69
|
+
Dir[glob_pattern].map do |path|
|
70
|
+
if File.directory?(path)
|
71
|
+
"#{path}/"
|
72
|
+
else
|
73
|
+
path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def glob_pattern
|
79
|
+
"#{base_path}#{text}*"
|
80
|
+
end
|
81
|
+
|
82
|
+
def base_path
|
83
|
+
"#{Dir.pwd}/"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
require "thor/line_editor/basic"
|
2
|
-
require "thor/line_editor/readline"
|
3
|
-
|
4
|
-
class Thor
|
5
|
-
module LineEditor
|
6
|
-
def self.readline(prompt, options = {})
|
7
|
-
best_available.new(prompt, options).readline
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.best_available
|
11
|
-
[
|
12
|
-
Thor::LineEditor::Readline,
|
13
|
-
Thor::LineEditor::Basic
|
14
|
-
].detect(&:available?)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
1
|
+
require "thor/line_editor/basic"
|
2
|
+
require "thor/line_editor/readline"
|
3
|
+
|
4
|
+
class Thor
|
5
|
+
module LineEditor
|
6
|
+
def self.readline(prompt, options = {})
|
7
|
+
best_available.new(prompt, options).readline
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.best_available
|
11
|
+
[
|
12
|
+
Thor::LineEditor::Readline,
|
13
|
+
Thor::LineEditor::Basic
|
14
|
+
].detect(&:available?)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|