honeybadger 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/lib/honeybadger/cli/heroku.rb +1 -1
  4. data/lib/honeybadger/init/rails.rb +2 -2
  5. data/lib/honeybadger/notice.rb +3 -3
  6. data/lib/honeybadger/plugins/delayed_job/plugin.rb +11 -3
  7. data/lib/honeybadger/rack/request_hash.rb +12 -1
  8. data/lib/honeybadger/rack/user_feedback.rb +1 -5
  9. data/lib/honeybadger/rack/user_informer.rb +1 -1
  10. data/lib/honeybadger/util/request_payload.rb +8 -2
  11. data/lib/honeybadger/util/sanitizer.rb +18 -1
  12. data/lib/honeybadger/version.rb +1 -1
  13. metadata +2 -35
  14. data/vendor/inifile/lib/inifile.rb +0 -628
  15. data/vendor/thor/lib/thor.rb +0 -484
  16. data/vendor/thor/lib/thor/actions.rb +0 -319
  17. data/vendor/thor/lib/thor/actions/create_file.rb +0 -103
  18. data/vendor/thor/lib/thor/actions/create_link.rb +0 -59
  19. data/vendor/thor/lib/thor/actions/directory.rb +0 -118
  20. data/vendor/thor/lib/thor/actions/empty_directory.rb +0 -135
  21. data/vendor/thor/lib/thor/actions/file_manipulation.rb +0 -316
  22. data/vendor/thor/lib/thor/actions/inject_into_file.rb +0 -107
  23. data/vendor/thor/lib/thor/base.rb +0 -656
  24. data/vendor/thor/lib/thor/command.rb +0 -133
  25. data/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +0 -77
  26. data/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -10
  27. data/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -98
  28. data/vendor/thor/lib/thor/error.rb +0 -32
  29. data/vendor/thor/lib/thor/group.rb +0 -281
  30. data/vendor/thor/lib/thor/invocation.rb +0 -178
  31. data/vendor/thor/lib/thor/line_editor.rb +0 -17
  32. data/vendor/thor/lib/thor/line_editor/basic.rb +0 -35
  33. data/vendor/thor/lib/thor/line_editor/readline.rb +0 -88
  34. data/vendor/thor/lib/thor/parser.rb +0 -4
  35. data/vendor/thor/lib/thor/parser/argument.rb +0 -73
  36. data/vendor/thor/lib/thor/parser/arguments.rb +0 -175
  37. data/vendor/thor/lib/thor/parser/option.rb +0 -125
  38. data/vendor/thor/lib/thor/parser/options.rb +0 -218
  39. data/vendor/thor/lib/thor/rake_compat.rb +0 -71
  40. data/vendor/thor/lib/thor/runner.rb +0 -322
  41. data/vendor/thor/lib/thor/shell.rb +0 -81
  42. data/vendor/thor/lib/thor/shell/basic.rb +0 -421
  43. data/vendor/thor/lib/thor/shell/color.rb +0 -149
  44. data/vendor/thor/lib/thor/shell/html.rb +0 -126
  45. data/vendor/thor/lib/thor/util.rb +0 -267
  46. data/vendor/thor/lib/thor/version.rb +0 -3
@@ -1,125 +0,0 @@
1
- class Thor
2
- class Option < Argument #:nodoc:
3
- attr_reader :aliases, :group, :lazy_default, :hide
4
-
5
- VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
6
-
7
- def initialize(name, options = {})
8
- options[:required] = false unless options.key?(:required)
9
- super
10
- @lazy_default = options[:lazy_default]
11
- @group = options[:group].to_s.capitalize if options[:group]
12
- @aliases = Array(options[:aliases])
13
- @hide = options[:hide]
14
- end
15
-
16
- # This parse quick options given as method_options. It makes several
17
- # assumptions, but you can be more specific using the option method.
18
- #
19
- # parse :foo => "bar"
20
- # #=> Option foo with default value bar
21
- #
22
- # parse [:foo, :baz] => "bar"
23
- # #=> Option foo with default value bar and alias :baz
24
- #
25
- # parse :foo => :required
26
- # #=> Required option foo without default value
27
- #
28
- # parse :foo => 2
29
- # #=> Option foo with default value 2 and type numeric
30
- #
31
- # parse :foo => :numeric
32
- # #=> Option foo without default value and type numeric
33
- #
34
- # parse :foo => true
35
- # #=> Option foo with default value true and type boolean
36
- #
37
- # The valid types are :boolean, :numeric, :hash, :array and :string. If none
38
- # is given a default type is assumed. This default type accepts arguments as
39
- # string (--foo=value) or booleans (just --foo).
40
- #
41
- # By default all options are optional, unless :required is given.
42
- #
43
- def self.parse(key, value) # rubocop:disable MethodLength
44
- if key.is_a?(Array)
45
- name, *aliases = key
46
- else
47
- name, aliases = key, []
48
- end
49
-
50
- name = name.to_s
51
- default = value
52
-
53
- type = case value
54
- when Symbol
55
- default = nil
56
- if VALID_TYPES.include?(value)
57
- value
58
- elsif required = (value == :required) # rubocop:disable AssignmentInCondition
59
- :string
60
- end
61
- when TrueClass, FalseClass
62
- :boolean
63
- when Numeric
64
- :numeric
65
- when Hash, Array, String
66
- value.class.name.downcase.to_sym
67
- end
68
- new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
69
- end
70
-
71
- def switch_name
72
- @switch_name ||= dasherized? ? name : dasherize(name)
73
- end
74
-
75
- def human_name
76
- @human_name ||= dasherized? ? undasherize(name) : name
77
- end
78
-
79
- def usage(padding = 0)
80
- sample = if banner && !banner.to_s.empty?
81
- "#{switch_name}=#{banner}"
82
- else
83
- switch_name
84
- end
85
-
86
- sample = "[#{sample}]" unless required?
87
-
88
- if boolean?
89
- sample << ", [#{dasherize("no-" + human_name)}]" unless name == "force"
90
- end
91
-
92
- if aliases.empty?
93
- (" " * padding) << sample
94
- else
95
- "#{aliases.join(', ')}, #{sample}"
96
- end
97
- end
98
-
99
- VALID_TYPES.each do |type|
100
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
101
- def #{type}?
102
- self.type == #{type.inspect}
103
- end
104
- RUBY
105
- end
106
-
107
- protected
108
-
109
- def validate!
110
- fail ArgumentError, "An option cannot be boolean and required." if boolean? && required?
111
- end
112
-
113
- def dasherized?
114
- name.index("-") == 0
115
- end
116
-
117
- def undasherize(str)
118
- str.sub(/^-{1,2}/, "")
119
- end
120
-
121
- def dasherize(str)
122
- (str.length > 1 ? "--" : "-") + str.gsub("_", "-")
123
- end
124
- end
125
- end
@@ -1,218 +0,0 @@
1
- class Thor
2
- class Options < Arguments #:nodoc: # rubocop:disable ClassLength
3
- LONG_RE = /^(--\w+(?:-\w+)*)$/
4
- SHORT_RE = /^(-[a-z])$/i
5
- EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
6
- SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
7
- SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i
8
- OPTS_END = "--".freeze
9
-
10
- # Receives a hash and makes it switches.
11
- def self.to_switches(options)
12
- options.map do |key, value|
13
- case value
14
- when true
15
- "--#{key}"
16
- when Array
17
- "--#{key} #{value.map { |v| v.inspect }.join(' ')}"
18
- when Hash
19
- "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
20
- when nil, false
21
- ""
22
- else
23
- "--#{key} #{value.inspect}"
24
- end
25
- end.join(" ")
26
- end
27
-
28
- # Takes a hash of Thor::Option and a hash with defaults.
29
- #
30
- # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
31
- # an unknown option or a regular argument.
32
- def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false)
33
- @stop_on_unknown = stop_on_unknown
34
- options = hash_options.values
35
- super(options)
36
-
37
- # Add defaults
38
- defaults.each do |key, value|
39
- @assigns[key.to_s] = value
40
- @non_assigned_required.delete(hash_options[key])
41
- end
42
-
43
- @shorts, @switches, @extra = {}, {}, []
44
-
45
- options.each do |option|
46
- @switches[option.switch_name] = option
47
-
48
- option.aliases.each do |short|
49
- name = short.to_s.sub(/^(?!\-)/, "-")
50
- @shorts[name] ||= option.switch_name
51
- end
52
- end
53
- end
54
-
55
- def remaining # rubocop:disable TrivialAccessors
56
- @extra
57
- end
58
-
59
- def peek
60
- return super unless @parsing_options
61
-
62
- result = super
63
- if result == OPTS_END
64
- shift
65
- @parsing_options = false
66
- super
67
- else
68
- result
69
- end
70
- end
71
-
72
- def parse(args) # rubocop:disable MethodLength
73
- @pile = args.dup
74
- @parsing_options = true
75
-
76
- while peek
77
- if parsing_options?
78
- match, is_switch = current_is_switch?
79
- shifted = shift
80
-
81
- if is_switch
82
- case shifted
83
- when SHORT_SQ_RE
84
- unshift($1.split("").map { |f| "-#{f}" })
85
- next
86
- when EQ_RE, SHORT_NUM
87
- unshift($2)
88
- switch = $1
89
- when LONG_RE, SHORT_RE
90
- switch = $1
91
- end
92
-
93
- switch = normalize_switch(switch)
94
- option = switch_option(switch)
95
- @assigns[option.human_name] = parse_peek(switch, option)
96
- elsif @stop_on_unknown
97
- @parsing_options = false
98
- @extra << shifted
99
- @extra << shift while peek
100
- break
101
- elsif match
102
- @extra << shifted
103
- @extra << shift while peek && peek !~ /^-/
104
- else
105
- @extra << shifted
106
- end
107
- else
108
- @extra << shift
109
- end
110
- end
111
-
112
- check_requirement!
113
-
114
- assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
115
- assigns.freeze
116
- assigns
117
- end
118
-
119
- def check_unknown!
120
- # an unknown option starts with - or -- and has no more --'s afterward.
121
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
122
- fail UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
123
- end
124
-
125
- protected
126
-
127
- # Check if the current value in peek is a registered switch.
128
- #
129
- # Two booleans are returned. The first is true if the current value
130
- # starts with a hyphen; the second is true if it is a registered switch.
131
- def current_is_switch?
132
- case peek
133
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
134
- [true, switch?($1)]
135
- when SHORT_SQ_RE
136
- [true, $1.split("").any? { |f| switch?("-#{f}") }]
137
- else
138
- [false, false]
139
- end
140
- end
141
-
142
- def current_is_switch_formatted?
143
- case peek
144
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
145
- true
146
- else
147
- false
148
- end
149
- end
150
-
151
- def current_is_value?
152
- peek && (!parsing_options? || super)
153
- end
154
-
155
- def switch?(arg)
156
- switch_option(normalize_switch(arg))
157
- end
158
-
159
- def switch_option(arg)
160
- if match = no_or_skip?(arg) # rubocop:disable AssignmentInCondition
161
- @switches[arg] || @switches["--#{match}"]
162
- else
163
- @switches[arg]
164
- end
165
- end
166
-
167
- # Check if the given argument is actually a shortcut.
168
- #
169
- def normalize_switch(arg)
170
- (@shorts[arg] || arg).tr("_", "-")
171
- end
172
-
173
- def parsing_options?
174
- peek
175
- @parsing_options
176
- end
177
-
178
- # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
179
- #
180
- def parse_boolean(switch)
181
- if current_is_value?
182
- if ["true", "TRUE", "t", "T", true].include?(peek)
183
- shift
184
- true
185
- elsif ["false", "FALSE", "f", "F", false].include?(peek)
186
- shift
187
- false
188
- else
189
- true
190
- end
191
- else
192
- @switches.key?(switch) || !no_or_skip?(switch)
193
- end
194
- end
195
-
196
- # Parse the value at the peek analyzing if it requires an input or not.
197
- #
198
- def parse_peek(switch, option)
199
- if parsing_options? && (current_is_switch_formatted? || last?)
200
- if option.boolean?
201
- # No problem for boolean types
202
- elsif no_or_skip?(switch)
203
- return nil # User set value to nil
204
- elsif option.string? && !option.required?
205
- # Return the default if there is one, else the human name
206
- return option.lazy_default || option.default || option.human_name
207
- elsif option.lazy_default
208
- return option.lazy_default
209
- else
210
- fail MalformattedArgumentError, "No value provided for option '#{switch}'"
211
- end
212
- end
213
-
214
- @non_assigned_required.delete(option)
215
- send(:"parse_#{option.type}", switch)
216
- end
217
- end
218
- end
@@ -1,71 +0,0 @@
1
- require "rake"
2
- require "rake/dsl_definition"
3
-
4
- class Thor
5
- # Adds a compatibility layer to your Thor classes which allows you to use
6
- # rake package tasks. For example, to use rspec rake tasks, one can do:
7
- #
8
- # require 'thor/rake_compat'
9
- # require 'rspec/core/rake_task'
10
- #
11
- # class Default < Thor
12
- # include Thor::RakeCompat
13
- #
14
- # RSpec::Core::RakeTask.new(:spec) do |t|
15
- # t.spec_opts = ['--options', './.rspec']
16
- # t.spec_files = FileList['spec/**/*_spec.rb']
17
- # end
18
- # end
19
- #
20
- module RakeCompat
21
- include Rake::DSL if defined?(Rake::DSL)
22
-
23
- def self.rake_classes
24
- @rake_classes ||= []
25
- end
26
-
27
- def self.included(base)
28
- # Hack. Make rakefile point to invoker, so rdoc task is generated properly.
29
- rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
30
- Rake.application.instance_variable_set(:@rakefile, rakefile)
31
- rake_classes << base
32
- end
33
- end
34
- end
35
-
36
- # override task on (main), for compatibility with Rake 0.9
37
- instance_eval do
38
- alias rake_namespace namespace
39
-
40
- def task(*)
41
- task = super
42
-
43
- if klass = Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
44
- non_namespaced_name = task.name.split(":").last
45
-
46
- description = non_namespaced_name
47
- description << task.arg_names.map { |n| n.to_s.upcase }.join(" ")
48
- description.strip!
49
-
50
- klass.desc description, Rake.application.last_description || non_namespaced_name
51
- Rake.application.last_description = nil
52
- klass.send :define_method, non_namespaced_name do |*args|
53
- Rake::Task[task.name.to_sym].invoke(*args)
54
- end
55
- end
56
-
57
- task
58
- end
59
-
60
- def namespace(name)
61
- if klass = Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
62
- const_name = Thor::Util.camel_case(name.to_s).to_sym
63
- klass.const_set(const_name, Class.new(Thor))
64
- new_klass = klass.const_get(const_name)
65
- Thor::RakeCompat.rake_classes << new_klass
66
- end
67
-
68
- super
69
- Thor::RakeCompat.rake_classes.pop
70
- end
71
- end
@@ -1,322 +0,0 @@
1
- require "thor"
2
- require "thor/group"
3
- require "thor/core_ext/io_binary_read"
4
-
5
- require "fileutils"
6
- require "open-uri"
7
- require "yaml"
8
- require "digest/md5"
9
- require "pathname"
10
-
11
- class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
12
- map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
13
-
14
- # Override Thor#help so it can give information about any class and any method.
15
- #
16
- def help(meth = nil)
17
- if meth && !self.respond_to?(meth)
18
- initialize_thorfiles(meth)
19
- klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
20
- self.class.handle_no_command_error(command, false) if klass.nil?
21
- klass.start(["-h", command].compact, :shell => shell)
22
- else
23
- super
24
- end
25
- end
26
-
27
- # If a command is not found on Thor::Runner, method missing is invoked and
28
- # Thor::Runner is then responsible for finding the command in all classes.
29
- #
30
- def method_missing(meth, *args)
31
- meth = meth.to_s
32
- initialize_thorfiles(meth)
33
- klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
34
- self.class.handle_no_command_error(command, false) if klass.nil?
35
- args.unshift(command) if command
36
- klass.start(args, :shell => shell)
37
- end
38
-
39
- desc "install NAME", "Install an optionally named Thor file into your system commands"
40
- method_options :as => :string, :relative => :boolean, :force => :boolean
41
- def install(name) # rubocop:disable MethodLength
42
- initialize_thorfiles
43
-
44
- # If a directory name is provided as the argument, look for a 'main.thor'
45
- # command in said directory.
46
- begin
47
- if File.directory?(File.expand_path(name))
48
- base, package = File.join(name, "main.thor"), :directory
49
- contents = open(base) { |input| input.read }
50
- else
51
- base, package = name, :file
52
- contents = open(name) { |input| input.read }
53
- end
54
- rescue OpenURI::HTTPError
55
- raise Error, "Error opening URI '#{name}'"
56
- rescue Errno::ENOENT
57
- fail Error, "Error opening file '#{name}'"
58
- end
59
-
60
- say "Your Thorfile contains:"
61
- say contents
62
-
63
- unless options["force"]
64
- return false if no?("Do you wish to continue [y/N]?")
65
- end
66
-
67
- as = options["as"] || begin
68
- first_line = contents.split("\n")[0]
69
- (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
70
- end
71
-
72
- unless as
73
- basename = File.basename(name)
74
- as = ask("Please specify a name for #{name} in the system repository [#{basename}]:")
75
- as = basename if as.empty?
76
- end
77
-
78
- location = if options[:relative] || name =~ %r{^https?://}
79
- name
80
- else
81
- File.expand_path(name)
82
- end
83
-
84
- thor_yaml[as] = {
85
- :filename => Digest::MD5.hexdigest(name + as),
86
- :location => location,
87
- :namespaces => Thor::Util.namespaces_in_content(contents, base)
88
- }
89
-
90
- save_yaml(thor_yaml)
91
- say "Storing thor file in your system repository"
92
- destination = File.join(thor_root, thor_yaml[as][:filename])
93
-
94
- if package == :file
95
- File.open(destination, "w") { |f| f.puts contents }
96
- else
97
- FileUtils.cp_r(name, destination)
98
- end
99
-
100
- thor_yaml[as][:filename] # Indicate success
101
- end
102
-
103
- desc "version", "Show Thor version"
104
- def version
105
- require "thor/version"
106
- say "Thor #{Thor::VERSION}"
107
- end
108
-
109
- desc "uninstall NAME", "Uninstall a named Thor module"
110
- def uninstall(name)
111
- fail Error, "Can't find module '#{name}'" unless thor_yaml[name]
112
- say "Uninstalling #{name}."
113
- FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}"))
114
-
115
- thor_yaml.delete(name)
116
- save_yaml(thor_yaml)
117
-
118
- puts "Done."
119
- end
120
-
121
- desc "update NAME", "Update a Thor file from its original location"
122
- def update(name)
123
- fail Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
124
-
125
- say "Updating '#{name}' from #{thor_yaml[name][:location]}"
126
-
127
- old_filename = thor_yaml[name][:filename]
128
- self.options = options.merge("as" => name)
129
-
130
- if File.directory? File.expand_path(name)
131
- FileUtils.rm_rf(File.join(thor_root, old_filename))
132
-
133
- thor_yaml.delete(old_filename)
134
- save_yaml(thor_yaml)
135
-
136
- filename = install(name)
137
- else
138
- filename = install(thor_yaml[name][:location])
139
- end
140
-
141
- unless filename == old_filename
142
- File.delete(File.join(thor_root, old_filename))
143
- end
144
- end
145
-
146
- desc "installed", "List the installed Thor modules and commands"
147
- method_options :internal => :boolean
148
- def installed
149
- initialize_thorfiles(nil, true)
150
- display_klasses(true, options["internal"])
151
- end
152
-
153
- desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
154
- method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
155
- def list(search = "")
156
- initialize_thorfiles
157
-
158
- search = ".*#{search}" if options["substring"]
159
- search = /^#{search}.*/i
160
- group = options[:group] || "standard"
161
-
162
- klasses = Thor::Base.subclasses.select do |k|
163
- (options[:all] || k.group == group) && k.namespace =~ search
164
- end
165
-
166
- display_klasses(false, false, klasses)
167
- end
168
-
169
- private
170
-
171
- def self.banner(command, all = false, subcommand = false)
172
- "thor " + command.formatted_usage(self, all, subcommand)
173
- end
174
-
175
- def thor_root
176
- Thor::Util.thor_root
177
- end
178
-
179
- def thor_yaml
180
- @thor_yaml ||= begin
181
- yaml_file = File.join(thor_root, "thor.yml")
182
- yaml = YAML.load_file(yaml_file) if File.exist?(yaml_file)
183
- yaml || {}
184
- end
185
- end
186
-
187
- # Save the yaml file. If none exists in thor root, creates one.
188
- #
189
- def save_yaml(yaml)
190
- yaml_file = File.join(thor_root, "thor.yml")
191
-
192
- unless File.exist?(yaml_file)
193
- FileUtils.mkdir_p(thor_root)
194
- yaml_file = File.join(thor_root, "thor.yml")
195
- FileUtils.touch(yaml_file)
196
- end
197
-
198
- File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
199
- end
200
-
201
- def self.exit_on_failure?
202
- true
203
- end
204
-
205
- # Load the Thorfiles. If relevant_to is supplied, looks for specific files
206
- # in the thor_root instead of loading them all.
207
- #
208
- # By default, it also traverses the current path until find Thor files, as
209
- # described in thorfiles. This look up can be skipped by supplying
210
- # skip_lookup true.
211
- #
212
- def initialize_thorfiles(relevant_to = nil, skip_lookup = false)
213
- thorfiles(relevant_to, skip_lookup).each do |f|
214
- Thor::Util.load_thorfile(f, nil, options[:debug]) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
215
- end
216
- end
217
-
218
- # Finds Thorfiles by traversing from your current directory down to the root
219
- # directory of your system. If at any time we find a Thor file, we stop.
220
- #
221
- # We also ensure that system-wide Thorfiles are loaded first, so local
222
- # Thorfiles can override them.
223
- #
224
- # ==== Example
225
- #
226
- # If we start at /Users/wycats/dev/thor ...
227
- #
228
- # 1. /Users/wycats/dev/thor
229
- # 2. /Users/wycats/dev
230
- # 3. /Users/wycats <-- we find a Thorfile here, so we stop
231
- #
232
- # Suppose we start at c:\Documents and Settings\james\dev\thor ...
233
- #
234
- # 1. c:\Documents and Settings\james\dev\thor
235
- # 2. c:\Documents and Settings\james\dev
236
- # 3. c:\Documents and Settings\james
237
- # 4. c:\Documents and Settings
238
- # 5. c:\ <-- no Thorfiles found!
239
- #
240
- def thorfiles(relevant_to = nil, skip_lookup = false)
241
- thorfiles = []
242
-
243
- unless skip_lookup
244
- Pathname.pwd.ascend do |path|
245
- thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten
246
- break unless thorfiles.empty?
247
- end
248
- end
249
-
250
- files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob)
251
- files += thorfiles
252
- files -= ["#{thor_root}/thor.yml"]
253
-
254
- files.map! do |file|
255
- File.directory?(file) ? File.join(file, "main.thor") : file
256
- end
257
- end
258
-
259
- # Load Thorfiles relevant to the given method. If you provide "foo:bar" it
260
- # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
261
- # namespaces registered.
262
- #
263
- def thorfiles_relevant_to(meth)
264
- lookup = [meth, meth.split(":")[0...-1].join(":")]
265
-
266
- files = thor_yaml.select do |k, v|
267
- v[:namespaces] && !(v[:namespaces] & lookup).empty?
268
- end
269
-
270
- files.map { |k, v| File.join(thor_root, "#{v[:filename]}") }
271
- end
272
-
273
- # Display information about the given klasses. If with_module is given,
274
- # it shows a table with information extracted from the yaml file.
275
- #
276
- def display_klasses(with_modules = false, show_internal = false, klasses = Thor::Base.subclasses)
277
- klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
278
-
279
- fail Error, "No Thor commands available" if klasses.empty?
280
- show_modules if with_modules && !thor_yaml.empty?
281
-
282
- list = Hash.new { |h, k| h[k] = [] }
283
- groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
284
-
285
- # Get classes which inherit from Thor
286
- (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_commands(false) }
287
-
288
- # Get classes which inherit from Thor::Base
289
- groups.map! { |k| k.printable_commands(false).first }
290
- list["root"] = groups
291
-
292
- # Order namespaces with default coming first
293
- list = list.sort { |a, b| a[0].sub(/^default/, "") <=> b[0].sub(/^default/, "") }
294
- list.each { |n, commands| display_commands(n, commands) unless commands.empty? }
295
- end
296
-
297
- def display_commands(namespace, list) #:nodoc:
298
- list.sort! { |a, b| a[0] <=> b[0] }
299
-
300
- say shell.set_color(namespace, :blue, true)
301
- say "-" * namespace.size
302
-
303
- print_table(list, :truncate => true)
304
- say
305
- end
306
- alias_method :display_tasks, :display_commands
307
-
308
- def show_modules #:nodoc:
309
- info = []
310
- labels = %w[Modules Namespaces]
311
-
312
- info << labels
313
- info << ["-" * labels[0].size, "-" * labels[1].size]
314
-
315
- thor_yaml.each do |name, hash|
316
- info << [name, hash[:namespaces].join(", ")]
317
- end
318
-
319
- print_table info
320
- say ""
321
- end
322
- end