Module: Ocran::GemSpecQueryable
- Defined in:
- lib/ocran/gem_spec_queryable.rb
Constant Summary collapse
- GEM_SCRIPT_RE =
/\.rbw?$/- GEM_EXTRA_RE =
%r{( # Auxiliary files in the root of the gem ^(\.\/)?(History|Install|Manifest|README|CHANGES|Licen[sc]e|Contributors|ChangeLog|BSD|GPL).*$ | # Installation files in the root of the gem ^(\.\/)?(Rakefile|setup.rb|extconf.rb)$ | # Documentation/test directories in the root of the gem ^(\.\/)?(doc|ext|examples|test|tests|benchmarks|spec)\/ | # Directories anywhere (^|\/)(\.autotest|\.svn|\.cvs|\.git)(\/|$) | # Unlikely extensions \.(rdoc|c|cpp|c\+\+|cxx|h|hxx|hpp|obj|o|a)$ )}xi- GEM_NON_FILE_RE =
/(#{GEM_EXTRA_RE}|#{GEM_SCRIPT_RE})/
Class Method Summary collapse
-
.detect_gems_from(features, verbose: false) ⇒ Object
Fall back to gem detection.
-
.find_gem_path(path) ⇒ Object
find_gem_path method searches for the path of the gem containing the specified path.
-
.find_spec(path) ⇒ Object
find_spec method searches and returns a Gem::Specification object based on the specified path.
-
.find_spec_file(path) ⇒ Object
find_spec_file method searches for the path of the gemspec file of the gem containing the specified path.
- .gem_inclusion_set(spec_name, gem_options) ⇒ Object
- .scanning_gemfile(gemfile_path) ⇒ Object
Instance Method Summary collapse
- #extra_files ⇒ Object
- #find_gem_files(file_sets, features_from_gems) ⇒ Object
- #gem_root ⇒ Object
-
#gem_root_files ⇒ Object
Find the selected files.
- #resource_files ⇒ Object
- #script_files ⇒ Object
Class Method Details
.detect_gems_from(features, verbose: false) ⇒ Object
Fall back to gem detection
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/ocran/gem_spec_queryable.rb', line 87 def detect_gems_from(features, verbose: false) features.inject([]) do |gems, feature| if gems.any? { |spec| feature.subpath?(spec.gem_dir) } # Skip if found in known Gem dir elsif (spec = GemSpecQueryable.find_spec(feature)) gems << spec else puts "Failed to load gemspec for #{feature}" if verbose end gems end end |
.find_gem_path(path) ⇒ Object
find_gem_path method searches for the path of the gem containing the specified path. The 'path' argument is a file or directory path. It checks each gem's installation path in Gem.path to see if the specified path is a subpath. Returns the gem's path if found, or nil if not found.
31 32 33 34 35 |
# File 'lib/ocran/gem_spec_queryable.rb', line 31 def find_gem_path(path) return unless defined?(Gem) Gem.path.find { |gem_path| Pathname(path).subpath?(gem_path) } end |
.find_spec(path) ⇒ Object
find_spec method searches and returns a Gem::Specification object based on the specified path. Internally, it uses find_spec_file to obtain the path to the gemspec file, and if that file exists, it calls Gem::Specification.load to load the gem's specifications. Returns the loaded Gem::Specification object, or nil if the gemspec file does not exist.
64 65 66 67 68 69 |
# File 'lib/ocran/gem_spec_queryable.rb', line 64 def find_spec(path) return unless defined?(Gem) spec_file = find_spec_file(path) spec_file && Gem::Specification.load(spec_file) end |
.find_spec_file(path) ⇒ Object
find_spec_file method searches for the path of the gemspec file of the gem containing the specified path. The 'path' argument is a file or directory path. It searches within the "gems" directory in each directory listed in Gem.path to check if the specified path is a subpath. If the gemspec file exists, it returns its path; otherwise, it returns nil.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ocran/gem_spec_queryable.rb', line 43 def find_spec_file(path) return unless defined?(Gem) feature = Pathname(path) Gem.path.each do |gem_path| gems_dir = File.join(gem_path, "gems") next unless feature.subpath?(gems_dir) full_name = feature.relative_path_from(gems_dir).each_filename.first spec_path = File.join(gem_path, "specifications", "#{full_name}.gemspec") return spec_path if File.exist?(spec_path) end nil end |
.gem_inclusion_set(spec_name, gem_options) ⇒ Object
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 |
# File 'lib/ocran/gem_spec_queryable.rb', line 101 def gem_inclusion_set(spec_name, ) include = [:loaded, :files] .each do |negate, option, list| next unless list.nil? || list.include?(spec_name) case option when :minimal include = [:loaded] when :guess include = [:loaded, :files] when :all include = [:scripts, :files] when :full include = [:scripts, :files, :extras] when :spec include = [:spec] when :scripts, :files, :extras if negate include.delete(option) else include.push(option) end else raise "Invalid Gem content detection option: #{option}" end end include.uniq! include end |
.scanning_gemfile(gemfile_path) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/ocran/gem_spec_queryable.rb', line 71 def scanning_gemfile(gemfile_path) # Ensure the necessary libraries are loaded to scan the Gemfile. # This is particularly useful in custom-built Ruby environments or # where certain libraries might be excluded. %w[rubygems bundler].each do |lib| require lib rescue LoadError raise "Couldn't scan Gemfile, unable to load #{lib}" end ENV["BUNDLE_GEMFILE"] = gemfile_path.to_s # Bundler.load.specs includes the spec for Bundler itself Bundler.load.specs.to_a end |
Instance Method Details
#extra_files ⇒ Object
144 145 146 |
# File 'lib/ocran/gem_spec_queryable.rb', line 144 def extra_files gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix =~ GEM_EXTRA_RE } end |
#find_gem_files(file_sets, features_from_gems) ⇒ Object
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 |
# File 'lib/ocran/gem_spec_queryable.rb', line 154 def find_gem_files(file_sets, features_from_gems) actual_files = file_sets.flat_map do |set| case set when :spec files.map { |file| Pathname(file) } when :loaded # Some distros expose gem files under additional paths via symlinks # (e.g. Fedora symlinks /usr/share/ruby/psych.rb into the psych gem # directory) and $LOADED_FEATURES records the symlink path. Resolve # each feature to its realpath so such files count as gem files and # are packed inside the gem directory. Packing them at the symlink # location instead would break require_relative, which resolves # against the realpath on the build host but not in the packed app. features_from_gems.filter_map do |feature| if feature.subpath?(gem_dir) feature else real = begin feature.realpath rescue SystemCallError next end real if real.subpath?(gem_dir) end end when :files resource_files when :extras extra_files when :scripts script_files else raise "Invalid file set: #{set}. Please specify a valid file set (:spec, :loaded, :files, :extras, :scripts)." end end actual_files.uniq actual_files end |
#gem_root ⇒ Object
132 |
# File 'lib/ocran/gem_spec_queryable.rb', line 132 def gem_root = Pathname(gem_dir) |
#gem_root_files ⇒ Object
Find the selected files. Default gems (e.g. fiddle, singleton on Homebrew or distro-packaged Ruby) may have a gemspec without a materialized gem directory - their files live in Ruby's stdlib and are packed via the load path instead.
138 |
# File 'lib/ocran/gem_spec_queryable.rb', line 138 def gem_root_files = gem_root.directory? ? gem_root.find.select(&:file?) : [] |
#resource_files ⇒ Object
148 149 150 151 152 |
# File 'lib/ocran/gem_spec_queryable.rb', line 148 def resource_files files = gem_root_files.select { |path| path.relative_path_from(gem_root).to_posix !~ GEM_NON_FILE_RE } files << Pathname(gem_build_complete_path) if File.exist?(gem_build_complete_path) files end |
#script_files ⇒ Object
140 141 142 |
# File 'lib/ocran/gem_spec_queryable.rb', line 140 def script_files gem_root_files.select { |path| path.extname =~ GEM_SCRIPT_RE } end |