This module holds several utilities:
1) Methods to convert thor namespaces to constants and vice-versa.
Thor::Utils.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
2) Loading thor files and sandboxing:
Thor::Utils.load_thorfile("~/.thor/foo")
Receives a string and convert it to camel case. camel_case returns CamelCase.
String
String
# File lib/bundler/vendor/thor/util.rb, line 104 104: def self.camel_case(str) 105: return str if str !~ /_/ && str =~ /[A-Z]+.*/ 106: str.split('_').map { |i| i.capitalize }.join 107: end
Receives a namespace and search for it in the Thor::Base subclasses.
namespace | The namespace to search for. |
# File lib/bundler/vendor/thor/util.rb, line 24 24: def self.find_by_namespace(namespace) 25: namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/ 26: Thor::Base.subclasses.find { |klass| klass.namespace == namespace } 27: end
Receives a namespace and tries to retrieve a Thor or Thor::Group class from it. It first searches for a class using the all the given namespace, if it’s not found, removes the highest entry and searches for the class again. If found, returns the highest entry as the class name.
class Foo::Bar < Thor def baz end end class Baz::Foo < Thor::Group end Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default task Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
namespace
# File lib/bundler/vendor/thor/util.rb, line 131 131: def self.find_class_and_task_by_namespace(namespace, fallback = true) 132: if namespace.include?(::) # look for a namespaced task 133: pieces = namespace.split(":") 134: task = pieces.pop 135: klass = Thor::Util.find_by_namespace(pieces.join(":")) 136: end 137: unless klass # look for a Thor::Group with the right name 138: klass, task = Thor::Util.find_by_namespace(namespace), nil 139: end 140: if !klass && fallback # try a task in the default namespace 141: task = namespace 142: klass = Thor::Util.find_by_namespace('') 143: end 144: return klass, task 145: end
Where to look for Thor files.
# File lib/bundler/vendor/thor/util.rb, line 210 210: def self.globs_for(path) 211: ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] 212: end
Receives a path and load the thor file in the path. The file is evaluated inside the sandbox to avoid namespacing conflicts.
# File lib/bundler/vendor/thor/util.rb, line 150 150: def self.load_thorfile(path, content=nil, debug=false) 151: content ||= File.binread(path) 152: 153: begin 154: Thor::Sandbox.class_eval(content, path) 155: rescue Exception => e 156: $stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}" 157: if debug 158: $stderr.puts *e.backtrace 159: else 160: $stderr.puts e.backtrace.first 161: end 162: end 163: end
Receives a constant and converts it to a Thor namespace. Since Thor tasks can be added to a sandbox, this method is also responsable for removing the sandbox namespace.
This method should not be used in general because it’s used to deal with older versions of Thor. On current versions, if you need to get the namespace from a class, just call namespace on it.
constant | The constant to be converted to the thor path. |
String | If we receive Foo::Bar::Baz it returns “foo:bar:baz“ |
# File lib/bundler/vendor/thor/util.rb, line 43 43: def self.namespace_from_thor_class(constant) 44: constant = constant.to_s.gsub(/^Thor::Sandbox::/, "") 45: constant = snake_case(constant).squeeze(":") 46: constant 47: end
Given the contents, evaluate it inside the sandbox and returns the namespaces defined in the sandbox.
contents
Array[Object]
# File lib/bundler/vendor/thor/util.rb, line 58 58: def self.namespaces_in_content(contents, file=__FILE__) 59: old_constants = Thor::Base.subclasses.dup 60: Thor::Base.subclasses.clear 61: 62: load_thorfile(file, contents) 63: 64: new_constants = Thor::Base.subclasses.dup 65: Thor::Base.subclasses.replace(old_constants) 66: 67: new_constants.map!{ |c| c.namespace } 68: new_constants.compact! 69: new_constants 70: end
Return the path to the ruby interpreter taking into account multiple installations and windows extensions.
# File lib/bundler/vendor/thor/util.rb, line 217 217: def self.ruby_command 218: @ruby_command ||= begin 219: ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) 220: ruby << RbConfig::CONFIG['EXEEXT'] 221: 222: # escape string in case path to ruby executable contain spaces. 223: ruby.sub!(/.*\s.*/, '"\&"') 224: ruby 225: end 226: end
Receives a string and convert it to snake case. SnakeCase returns snake_case.
String
String
# File lib/bundler/vendor/thor/util.rb, line 90 90: def self.snake_case(str) 91: return str.downcase if str =~ /^[A-Z_]+$/ 92: str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/ 93: return $+.downcase 94: end
Returns the thor classes declared inside the given class.
# File lib/bundler/vendor/thor/util.rb, line 74 74: def self.thor_classes_in(klass) 75: stringfied_constants = klass.constants.map { |c| c.to_s } 76: Thor::Base.subclasses.select do |subclass| 77: next unless subclass.name 78: stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", '')) 79: end 80: end
Returns the root where thor files are located, dependending on the OS.
# File lib/bundler/vendor/thor/util.rb, line 189 189: def self.thor_root 190: File.join(user_home, ".thor").gsub(/\\/, '/') 191: end
Returns the files in the thor root. On Windows thor_root will be something like this:
C:\Documents and Settings\james\.thor
If we don’t gsub the \ character, Dir.glob will fail.
# File lib/bundler/vendor/thor/util.rb, line 200 200: def self.thor_root_glob 201: files = Dir["#{thor_root}/*"] 202: 203: files.map! do |file| 204: File.directory?(file) ? File.join(file, "main.thor") : file 205: end 206: end
# File lib/bundler/vendor/thor/util.rb, line 165 165: def self.user_home 166: @@user_home ||= if ENV["HOME"] 167: ENV["HOME"] 168: elsif ENV["USERPROFILE"] 169: ENV["USERPROFILE"] 170: elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"] 171: File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"]) 172: elsif ENV["APPDATA"] 173: ENV["APPDATA"] 174: else 175: begin 176: File.expand_path("~") 177: rescue 178: if File::ALT_SEPARATOR 179: "C:/" 180: else 181: "/" 182: end 183: end 184: end 185: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.