1require 'English' 2require 'rubygems/command' 3require 'rubygems/version_option' 4 5class Gem::Commands::ContentsCommand < Gem::Command 6 7 include Gem::VersionOption 8 9 def initialize 10 super 'contents', 'Display the contents of the installed gems', 11 :specdirs => [], :lib_only => false, :prefix => true 12 13 add_version_option 14 15 add_option( '--all', 16 "Contents for all gems") do |all, options| 17 options[:all] = all 18 end 19 20 add_option('-s', '--spec-dir a,b,c', Array, 21 "Search for gems under specific paths") do |spec_dirs, options| 22 options[:specdirs] = spec_dirs 23 end 24 25 add_option('-l', '--[no-]lib-only', 26 "Only return files in the Gem's lib_dirs") do |lib_only, options| 27 options[:lib_only] = lib_only 28 end 29 30 add_option( '--[no-]prefix', 31 "Don't include installed path prefix") do |prefix, options| 32 options[:prefix] = prefix 33 end 34 end 35 36 def arguments # :nodoc: 37 "GEMNAME name of gem to list contents for" 38 end 39 40 def defaults_str # :nodoc: 41 "--no-lib-only --prefix" 42 end 43 44 def usage # :nodoc: 45 "#{program_name} GEMNAME [GEMNAME ...]" 46 end 47 48 def execute 49 version = options[:version] || Gem::Requirement.default 50 51 spec_dirs = options[:specdirs].map do |i| 52 [i, File.join(i, "specifications")] 53 end.flatten 54 55 path_kind = if spec_dirs.empty? then 56 spec_dirs = Gem::Specification.dirs 57 "default gem paths" 58 else 59 "specified path" 60 end 61 62 gem_names = if options[:all] then 63 Gem::Specification.map(&:name) 64 else 65 get_all_gem_names 66 end 67 68 gem_names.each do |name| 69 # HACK: find_by_name fails for some reason... ARGH 70 # How many places must we embed our resolve logic? 71 spec = Gem::Specification.find_all_by_name(name, version).last 72 73 unless spec then 74 say "Unable to find gem '#{name}' in #{path_kind}" 75 76 if Gem.configuration.verbose then 77 say "\nDirectories searched:" 78 spec_dirs.sort.each { |dir| say dir } 79 end 80 81 terminate_interaction 1 if gem_names.length == 1 82 end 83 84 if spec.default_gem? 85 files = spec.files.sort.map do |file| 86 case file 87 when /\A#{spec.bindir}\// 88 [Gem::ConfigMap[:bindir], $POSTMATCH] 89 when /\.so\z/ 90 [Gem::ConfigMap[:archdir], file] 91 else 92 [Gem::ConfigMap[:rubylibdir], file] 93 end 94 end 95 else 96 gem_path = spec.full_gem_path 97 extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only] 98 glob = "#{gem_path}#{extra}/**/*" 99 prefix_re = /#{Regexp.escape(gem_path)}\// 100 files = Dir[glob].map do |file| 101 [gem_path, file.sub(prefix_re, "")] 102 end 103 end 104 105 files.sort.each do |prefix, basename| 106 absolute_path = File.join(prefix, basename) 107 next if File.directory? absolute_path 108 109 if options[:prefix] 110 say absolute_path 111 else 112 say basename 113 end 114 end 115 end 116 end 117 118end 119 120