1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
# frozen_string_literal: true
require_relative "../command"
require_relative "../version_option"
class Gem::Commands::ContentsCommand < Gem::Command
include Gem::VersionOption
def initialize
super "contents", "Display the contents of the installed gems",
specdirs: [], lib_only: false, prefix: true,
show_install_dir: false
add_version_option
add_option("--all",
"Contents for all gems") do |all, options|
options[:all] = all
end
add_option("-s", "--spec-dir a,b,c", Array,
"Search for gems under specific paths") do |spec_dirs, options|
options[:specdirs] = spec_dirs
end
add_option("-l", "--[no-]lib-only",
"Only return files in the Gem's lib_dirs") do |lib_only, options|
options[:lib_only] = lib_only
end
add_option("--[no-]prefix",
"Don't include installed path prefix") do |prefix, options|
options[:prefix] = prefix
end
add_option("--[no-]show-install-dir",
"Show only the gem install dir") do |show, options|
options[:show_install_dir] = show
end
@path_kind = nil
@spec_dirs = nil
@version = nil
end
def arguments # :nodoc:
"GEMNAME name of gem to list contents for"
end
def defaults_str # :nodoc:
"--no-lib-only --prefix"
end
def description # :nodoc:
<<-EOF
The contents command lists the files in an installed gem. The listing can
be given as full file names, file names without the installed directory
prefix or only the files that are requireable.
EOF
end
def usage # :nodoc:
"#{program_name} GEMNAME [GEMNAME ...]"
end
def execute
@version = options[:version] || Gem::Requirement.default
@spec_dirs = specification_directories
@path_kind = path_description @spec_dirs
names = gem_names
names.each do |name|
found =
if options[:show_install_dir]
gem_install_dir name
else
gem_contents name
end
terminate_interaction 1 unless found || names.length > 1
end
end
def files_in(spec)
if spec.default_gem?
files_in_default_gem spec
else
files_in_gem spec
end
end
def files_in_gem(spec)
gem_path = spec.full_gem_path
extra = "/{#{spec.require_paths.join ","}}" if options[:lib_only]
glob = "#{gem_path}#{extra}/**/*"
prefix_re = %r{#{Regexp.escape(gem_path)}/}
Dir[glob].map do |file|
[gem_path, file.sub(prefix_re, "")]
end
end
def files_in_default_gem(spec)
spec.files.map do |file|
if file.start_with?("#{spec.bindir}/")
[RbConfig::CONFIG["bindir"], file.delete_prefix("#{spec.bindir}/")]
else
gem spec.name, spec.version
require_path = spec.require_paths.find do |path|
file.start_with?("#{path}/")
end
requirable_part = file.delete_prefix("#{require_path}/")
resolve = $LOAD_PATH.resolve_feature_path(requirable_part)&.last
next unless resolve
[resolve.delete_suffix(requirable_part), requirable_part]
end
end.compact
end
def gem_contents(name)
spec = spec_for name
return false unless spec
files = files_in spec
show_files files
true
end
def gem_install_dir(name)
spec = spec_for name
return false unless spec
say spec.gem_dir
true
end
def gem_names # :nodoc:
if options[:all]
Gem::Specification.map(&:name)
else
get_all_gem_names
end
end
def path_description(spec_dirs) # :nodoc:
if spec_dirs.empty?
"default gem paths"
else
"specified path"
end
end
def show_files(files)
files.sort.each do |prefix, basename|
absolute_path = File.join(prefix, basename)
next if File.directory? absolute_path
if options[:prefix]
say absolute_path
else
say basename
end
end
end
def spec_for(name)
spec = Gem::Specification.find_all_by_name(name, @version).first
return spec if spec
say "Unable to find gem '#{name}' in #{@path_kind}"
if Gem.configuration.verbose
say "\nDirectories searched:"
@spec_dirs.sort.each {|dir| say dir }
end
nil
end
def specification_directories # :nodoc:
options[:specdirs].map do |i|
[i, File.join(i, "specifications")]
end.flatten
end
end
|