Class: Autoproj::PackageManagers::GemManager
- Defined in:
- lib/autoproj/package_managers/gem_manager.rb
Overview
Package manager interface for the RubyGems system
Class Attribute Summary collapse
-
.gem_home ⇒ Object
Returns the value of attribute gem_home.
-
.with_doc ⇒ Object
Returns the value of attribute with_doc.
- .with_prerelease(*value) ⇒ Object
Instance Attribute Summary collapse
- #gem_fetcher ⇒ Object
-
#installed_gems ⇒ Object
readonly
The set of gems installed during this autoproj session.
Attributes inherited from Manager
Class Method Summary collapse
-
.cache_dir ⇒ Object
A global cache directory that should be used to avoid re-downloading gems.
-
.default_install_options ⇒ Object
Returns the set of default options that are added to gem.
- .use_cache_dir ⇒ Object
Instance Method Summary collapse
- #build_gem_cmdlines(gems) ⇒ Object
-
#filter_uptodate_packages(gems, options = Hash.new) ⇒ Object
Returns the set of RubyGem packages in
packages
that are not already installed, or that can be upgraded. - #gems_interaction(gems, cmdlines) ⇒ Object
- #guess_gem_program ⇒ Object
-
#initialize(ws) ⇒ GemManager
constructor
A new instance of GemManager.
-
#initialize_environment ⇒ Object
Filters all paths that come from other autoproj installations out of GEM_PATH.
- #install(gems) ⇒ Object
- #parse_package_entry(entry) ⇒ Object
- #pristine(gems) ⇒ Object
Methods inherited from Manager
#call_while_empty?, #configure_manager, #enabled?, #os_dependencies, #silent?, #strict?
Constructor Details
#initialize(ws) ⇒ GemManager
Returns a new instance of GemManager.
105 106 107 108 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 105 def initialize(ws) super(ws) @installed_gems = Set.new end |
Class Attribute Details
.gem_home ⇒ Object
Returns the value of attribute gem_home.
91 92 93 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 91 def gem_home @gem_home end |
.with_doc ⇒ Object
Returns the value of attribute with_doc.
7 8 9 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 7 def with_doc @with_doc end |
.with_prerelease(*value) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 12 def self.with_prerelease(*value) if value.empty? @with_prerelease else begin saved_flag = @with_prerelease @with_prerelease = value.first yield ensure @with_prerelease = saved_flag end end end |
Instance Attribute Details
#gem_fetcher ⇒ Object
117 118 119 120 121 122 123 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 117 def gem_fetcher unless @gem_fetcher Autoproj. " looking for RubyGems updates" @gem_fetcher = Gem::SpecFetcher.fetcher end @gem_fetcher end |
#installed_gems ⇒ Object (readonly)
The set of gems installed during this autoproj session
115 116 117 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 115 def installed_gems @installed_gems end |
Class Method Details
.cache_dir ⇒ Object
A global cache directory that should be used to avoid re-downloading gems
68 69 70 71 72 73 74 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 68 def self.cache_dir return unless (dir = ENV["AUTOBUILD_CACHE_DIR"]) dir = File.join(dir, "gems") FileUtils.mkdir_p dir dir end |
.default_install_options ⇒ Object
Returns the set of default options that are added to gem
By default, we add –no-user-install to un-break distributions like Arch that set –user-install by default (thus disabling the role of GEM_HOME)
101 102 103 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 101 def self. @default_install_options ||= ["--no-user-install", "--no-format-executable"] end |
.use_cache_dir ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 76 def self.use_cache_dir # If there is a cache directory, make sure .gems/cache points to # it (there are no programmatic ways to override this) return unless (cache = cache_dir) gem_cache_dir = File.join(gem_home, "cache") if !File.symlink?(gem_cache_dir) || File.readlink(gem_cache_dir) != cache FileUtils.mkdir_p gem_home FileUtils.rm_rf gem_cache_dir Autoproj.create_symlink(cache, gem_cache_dir) end end |
Instance Method Details
#build_gem_cmdlines(gems) ⇒ Object
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 144 def build_gem_cmdlines(gems) with_version, without_version = gems.partition { |name, v| v } cmdlines = [] cmdlines << without_version.flatten unless without_version.empty? with_version.each do |name, v| cmdlines << [name, "-v", v] end cmdlines end |
#filter_uptodate_packages(gems, options = Hash.new) ⇒ Object
Returns the set of RubyGem packages in packages
that are not already installed, or that can be upgraded
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 200 def filter_uptodate_packages(gems, = Hash.new) = , install_only: !Autobuild.do_update # Don't install gems that are already there ... gems = gems.dup gems.delete_if do |name, version| next(true) if installed_gems.include?(name) version_requirements = Gem::Requirement.new(version || ">= 0") installed = if Gem::Specification.respond_to?(:find_by_name) begin [Gem::Specification.find_by_name(name, version_requirements)] rescue Gem::LoadError [] end else Gem.source_index.find_name(name, version_requirements) end if !installed.empty? && ![:install_only] # Look if we can update the package ... dep = Gem::Dependency.new(name, version_requirements) available = if gem_fetcher.respond_to?(:find_matching) non_prerelease = gem_fetcher.find_matching(dep, true, true).map(&:first) if GemManager.with_prerelease prerelease = gem_fetcher.find_matching(dep, false, true, true).map(&:first) else prerelease = Array.new end (non_prerelease + prerelease) .map { |n, v, _| [n, v] } else # Post RubyGems-2.0 type = if GemManager.with_prerelease then :complete else :released end gem_fetcher.detect(type) do |tuple| tuple.name == name && dep.match?(tuple) end.map { |tuple, _| [tuple.name, tuple.version] } end installed_version = installed.map(&:version).max available_version = available.map { |_, v| v }.max unless available_version if version raise ConfigError.new, "cannot find any gem with the name '#{name}' and version #{version}" else raise ConfigError.new, "cannot find any gem with the name '#{name}'" end end needs_update = (available_version > installed_version) !needs_update else !installed.empty? end end gems end |
#gems_interaction(gems, cmdlines) ⇒ Object
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 271 def gems_interaction(gems, cmdlines) if OSPackageInstaller.force_osdeps return true elsif enabled? return true elsif silent? return false end # We're not supposed to install rubygem packages but silent is not # set, so display information about them anyway puts <<-EOMSG #{Autoproj.color('The build process and/or the packages require some Ruby Gems to be installed', :bold)} #{Autoproj.color('and you required autoproj to not do it itself', :bold)} You can use the --all or --ruby options to autoproj osdeps to install these packages anyway, and/or change to the osdeps handling mode by running an autoproj operation with the --reconfigure option as for instance autoproj build --reconfigure #{' '} The following command line can be used to install them manually #{' '} #{cmdlines.map { |c| c.join(' ') }.join("\n ")} #{' '} Autoproj expects these Gems to be installed in #{GemManager.gem_home} This can be overridden by setting the AUTOPROJ_GEM_HOME environment variable manually EOMSG print " #{Autoproj.color('Press ENTER to continue ', :bold)}" STDOUT.flush STDIN.readline puts false end |
#guess_gem_program ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 125 def guess_gem_program return Autobuild.programs["gem"] if Autobuild.programs["gem"] ruby_bin = RbConfig::CONFIG["RUBY_INSTALL_NAME"] ruby_bindir = RbConfig::CONFIG["bindir"] candidates = ["gem"] candidates << "gem#{$1}" if ruby_bin =~ /^ruby(.+)$/ candidates.each do |gem_name| if File.file?(gem_full_path = File.join(ruby_bindir, gem_name)) Autobuild.programs["gem"] = gem_full_path return end end raise ArgumentError, "cannot find a gem program (tried #{candidates.sort.join(', ')} in #{ruby_bindir})" end |
#initialize_environment ⇒ Object
Filters all paths that come from other autoproj installations out of GEM_PATH
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 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 28 def initialize_environment env = ws.env env.original_env["GEM_PATH"] = (env["GEM_PATH"] || "").split(File::PATH_SEPARATOR).find_all do |p| !Autoproj.in_autoproj_installation?(p) end.join(File::PATH_SEPARATOR) env.inherit "GEM_PATH" env.init_from_env "GEM_PATH" orig_gem_path = env.original_env["GEM_PATH"].split(File::PATH_SEPARATOR) env.system_env["GEM_PATH"] = Gem.default_path env.original_env["GEM_PATH"] = orig_gem_path.join(File::PATH_SEPARATOR) ws.config.each_reused_autoproj_installation do |p| p_gems = File.join(p, ".gems") if File.directory?(p_gems) env.push_path "GEM_PATH", p_gems env.push_path "PATH", File.join(p_gems, "bin") end end @gem_home = (ENV["AUTOPROJ_GEM_HOME"] || File.join(ws.root_dir, ".gems")) env.push_path "GEM_PATH", gem_home env.set "GEM_HOME", gem_home env.push_path "PATH", "#{gem_home}/bin" # Now, reset the directories in our own RubyGems instance Gem.paths = env.resolved_env use_cache_dir end |
#install(gems) ⇒ Object
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 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 172 def install(gems) guess_gem_program base_cmdline = [Autobuild.tool_in_path("ruby", env: ws.env), "-S", Autobuild.tool("gem"), "install", *GemManager.] base_cmdline << "--no-rdoc" << "--no-ri" unless GemManager.with_doc base_cmdline << "--prerelease" if GemManager.with_prerelease cmdlines = build_gem_cmdlines(gems).map do |line| base_cmdline + line end if gems_interaction(gems, cmdlines) Autoproj. " installing/updating RubyGems dependencies: #{gems.map { |g| g.join(' ') }.sort.join(', ')}" cmdlines.each do |c| Autobuild::Subprocess.run "autoproj", "osdeps", *c, env: Hash["GEM_HOME" => Gem.paths.home, "GEM_PATH" => Gem.paths.path.join(":")] end gems.each do |name, v| installed_gems << name end true end end |
#parse_package_entry(entry) ⇒ Object
263 264 265 266 267 268 269 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 263 def parse_package_entry(entry) if entry =~ /^([^><=~]*)([><=~]+.*)$/ [$1.strip, $2.strip] else [entry] end end |
#pristine(gems) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/autoproj/package_managers/gem_manager.rb', line 155 def pristine(gems) guess_gem_program base_cmdline = [Autobuild.tool_in_path("ruby", env: ws.env), "-S", Autobuild.tool("gem")] cmdlines = [ [*base_cmdline, "clean"] ] cmdlines += build_gem_cmdlines(gems).map do |line| base_cmdline + ["pristine", "--extensions"] + line end if gems_interaction(gems, cmdlines) Autoproj. " restoring RubyGems: #{gems.map { |g| g.join(' ') }.sort.join(', ')}" cmdlines.each do |c| Autobuild::Subprocess.run "autoproj", "osdeps", *c end end end |