模块 Bundler::Thor::Util
此模块包含多个实用程序
1) 将 thor 命名空间转换为常量以及反之的方法。
Bundler::Thor::Util.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
2) 加载 thor 文件和沙箱处理
Bundler::Thor::Util.load_thorfile("~/.thor/foo")
公共类方法
camel_case(str) 点击以切换源代码
接收一个字符串并将其转换为驼峰式大小写。camel_case
返回 CamelCase。
参数¶ ↑
字符串
返回¶ ↑
字符串
# File bundler/vendor/thor/lib/thor/util.rb, line 104 def camel_case(str) return str if str !~ /_/ && str =~ /[A-Z]+.*/ str.split("_").map(&:capitalize).join end
escape_globs(path) 点击以切换源代码
escape_html(string) 点击以切换源代码
find_by_namespace(namespace) 点击以切换源代码
接收一个命名空间并在 Bundler::Thor::Base
子类中搜索它。
参数¶ ↑
- 命名空间<字符串>
-
要搜索的命名空间。
# File bundler/vendor/thor/lib/thor/util.rb, line 24 def find_by_namespace(namespace) namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/ Bundler::Thor::Base.subclasses.detect { |klass| klass.namespace == namespace } end
find_class_and_command_by_namespace(namespace, fallback = true) 点击以切换源代码
接收一个命名空间并尝试从中检索一个 Bundler::Thor 或 Bundler::Thor::Group
类。 它首先使用给定的所有命名空间搜索类,如果未找到,则删除最高的条目并再次搜索类。 如果找到,则返回最高条目作为类名。
示例¶ ↑
class Foo::Bar < Bundler::Thor def baz end end class Baz::Foo < Bundler::Thor::Group end Bundler::Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default command Bundler::Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil Bundler::Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
参数¶ ↑
命名空间<字符串>
# File bundler/vendor/thor/lib/thor/util.rb, line 131 def find_class_and_command_by_namespace(namespace, fallback = true) if namespace.include?(":") # look for a namespaced command *pieces, command = namespace.split(":") namespace = pieces.join(":") namespace = "default" if namespace.empty? klass = Bundler::Thor::Base.subclasses.detect { |thor| thor.namespace == namespace && thor.command_exists?(command) } end unless klass # look for a Bundler::Thor::Group with the right name klass = Bundler::Thor::Util.find_by_namespace(namespace) command = nil end if !klass && fallback # try a command in the default namespace command = namespace klass = Bundler::Thor::Util.find_by_namespace("") end [klass, command] end
globs_for(path) 点击以切换源代码
在何处查找 Bundler::Thor 文件。
# File bundler/vendor/thor/lib/thor/util.rb, line 213 def globs_for(path) path = escape_globs(path) ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/**/*.thor"] end
load_thorfile(path, content = nil, debug = false) 点击以切换源代码
接收一个路径并加载该路径中的 thor 文件。 该文件在沙箱内求值,以避免命名空间冲突。
# File bundler/vendor/thor/lib/thor/util.rb, line 153 def load_thorfile(path, content = nil, debug = false) content ||= File.read(path) begin Bundler::Thor::Sandbox.class_eval(content, path) rescue StandardError => e $stderr.puts("WARNING: unable to load thorfile #{path.inspect}: #{e.message}") if debug $stderr.puts(*e.backtrace) else $stderr.puts(e.backtrace.first) end end end
namespace_from_thor_class(constant) 点击以切换源代码
接收一个常量并将其转换为 Bundler::Thor 命名空间。 由于可以将 Bundler::Thor 命令添加到沙箱中,因此此方法还负责删除沙箱命名空间。
通常不应使用此方法,因为它用于处理较旧版本的 Bundler::Thor。 在当前版本中,如果需要从类中获取命名空间,只需调用其 namespace 即可。
参数¶ ↑
- 常量<对象>
-
要转换为 thor 路径的常量。
返回¶ ↑
- 字符串
-
如果我们收到 Foo::Bar::Baz,它会返回 “foo:bar:baz”
# File bundler/vendor/thor/lib/thor/util.rb, line 43 def namespace_from_thor_class(constant) constant = constant.to_s.gsub(/^Bundler::Thor::Sandbox::/, "") constant = snake_case(constant).squeeze(":") constant end
namespaces_in_content(contents, file = __FILE__) 点击以切换源代码
给定内容,在沙箱内对其求值并返回沙箱中定义的命名空间。
参数¶ ↑
内容<字符串>
返回¶ ↑
# File bundler/vendor/thor/lib/thor/util.rb, line 58 def namespaces_in_content(contents, file = __FILE__) old_constants = Bundler::Thor::Base.subclasses.dup Bundler::Thor::Base.subclasses.clear load_thorfile(file, contents) new_constants = Bundler::Thor::Base.subclasses.dup Bundler::Thor::Base.subclasses.replace(old_constants) new_constants.map!(&:namespace) new_constants.compact! new_constants end
ruby_command() 点击以切换源代码
返回 ruby 解释器的路径,其中考虑了多个安装和 windows 扩展名。
# File bundler/vendor/thor/lib/thor/util.rb, line 221 def ruby_command @ruby_command ||= begin ruby_name = RbConfig::CONFIG["ruby_install_name"] ruby = File.join(RbConfig::CONFIG["bindir"], ruby_name) ruby << RbConfig::CONFIG["EXEEXT"] # avoid using different name than ruby (on platforms supporting links) if ruby_name != "ruby" && File.respond_to?(:readlink) begin alternate_ruby = File.join(RbConfig::CONFIG["bindir"], "ruby") alternate_ruby << RbConfig::CONFIG["EXEEXT"] # ruby is a symlink if File.symlink? alternate_ruby linked_ruby = File.readlink alternate_ruby # symlink points to 'ruby_install_name' ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby end rescue NotImplementedError # rubocop:disable Lint/HandleExceptions # just ignore on windows end end # escape string in case path to ruby executable contain spaces. ruby.sub!(/.*\s.*/m, '"\&"') ruby end end
snake_case(str) 点击以切换源代码
thor_classes_in(klass) 点击以切换源代码
返回给定类中声明的 thor 类。
# File bundler/vendor/thor/lib/thor/util.rb, line 74 def thor_classes_in(klass) stringfied_constants = klass.constants.map(&:to_s) Bundler::Thor::Base.subclasses.select do |subclass| next unless subclass.name stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", "")) end end
thor_root() 点击以切换源代码
返回 thor 文件所在的根目录,具体取决于操作系统。
# File bundler/vendor/thor/lib/thor/util.rb, line 192 def thor_root File.join(user_home, ".thor").tr("\\", "/") end
thor_root_glob() 点击以切换源代码
返回 thor 根目录中的文件。在 Windows 上,thor_root
将类似于这样
C:\Documents and Settings\james\.thor
如果我们不 gsub \ 字符,Dir.glob 将失败。
# File bundler/vendor/thor/lib/thor/util.rb, line 203 def thor_root_glob files = Dir["#{escape_globs(thor_root)}/*"] files.map! do |file| File.directory?(file) ? File.join(file, "main.thor") : file end end
user_home() 点击以切换源代码
# File bundler/vendor/thor/lib/thor/util.rb, line 168 def user_home @@user_home ||= if ENV["HOME"] ENV["HOME"] elsif ENV["USERPROFILE"] ENV["USERPROFILE"] elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"] File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"]) elsif ENV["APPDATA"] ENV["APPDATA"] else begin File.expand_path("~") rescue if File::ALT_SEPARATOR "C:/" else "/" end end end end