Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does bundler cache gems into local install path? #6102

Closed
blowfishpro opened this issue Dec 6, 2022 · 6 comments
Closed

Why does bundler cache gems into local install path? #6102

blowfishpro opened this issue Dec 6, 2022 · 6 comments
Labels

Comments

@blowfishpro
Copy link

blowfishpro commented Dec 6, 2022

Describe the problem as clearly as you can

When the path option is set, bundler puts a cache of all the .gem files into the local install path (e.g. vendor/bundle) even though they are not needed for deployment.

Did you try upgrading rubygems & bundler?

yes (rubygems 3.3.26 and bundler 2.3.26)

Post steps to reproduce the problem

Tested in the official Ruby 3.1.2 Docker library image (ruby:3.1.2)

gem update --system --no-doc
mkdir /tmp/example
cd /tmp/example
bundle init
bundle add rake
bundle config set --local path vendor/bundle

Which command did you run?

bundle install
ls vendor/bundle/ruby/3.1.0/cache/

What were you expecting to happen?

vendor/bundle contains only the installed gems, not the packaged .gem files

What actually happened?

.gem files appear to be cached into vendor/bundle/ruby/3.1.0/cache/.

After removing them and running some tests they do not appear to be needed for bundler to work correctly. While harmless in principle, they can potentially add a lot of disk usage. This is not ideal when trying to package for deployment (e.g. in a docker container).

I tried various combinations of settings and other tricks:

  • global_gem_cache setting
  • BUNDLE_USER_CACHE environment variable
  • deployment setting
  • packaging and then installing in separate steps:
    bundle config set --local no_install true
    bundle cache
    bundle install --local
    in this case the .gem files end up both in vendor/cache and vendor/bundle/ruby/3.1.0/cache/

Is there a way to get rid of this cache other than manually deleting all the .gem files? If bundler needs a cache for downloads that's fine, but it seems like it shouldn't be here.

If not included with the output of your command, run bundle env and paste the output below

Environment

Bundler       2.3.26
  Platforms   ruby, aarch64-linux
Ruby          3.1.2p20 (2022-04-12 revision 4491bb740a9506d76391ac44bb2fe6e483fec952) [aarch64-linux]
  Full Path   /usr/local/bin/ruby
  Config Dir  /usr/local/etc
RubyGems      3.3.26
  Gem Home    /usr/local/bundle
  Gem Path    /root/.local/share/gem/ruby/3.1.0:/usr/local/lib/ruby/gems/3.1.0:/usr/local/bundle
  User Home   /root
  User Path   /root/.local/share/gem/ruby/3.1.0
  Bin Dir     /usr/local/bundle/bin
Tools         
  Git         2.30.2
  RVM         not installed
  rbenv       not installed
  chruby      not installed

Bundler Build Metadata

Built At          2022-11-17
Git SHA           23ec5b8501
Released Version  true

Bundler settings

app_config
  Set via BUNDLE_APP_CONFIG: "/usr/local/bundle"
path
  Set for your local app (/usr/local/bundle/config): "vendor/bundle"
silence_root_warning
  Set via BUNDLE_SILENCE_ROOT_WARNING: true

Gemfile

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

# gem "rails"

gem "rake", "~> 13.0"
Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    rake (13.0.6)

PLATFORMS
  aarch64-linux

DEPENDENCIES
  rake (~> 13.0)

BUNDLED WITH
   2.3.26
@deivid-rodriguez
Copy link
Member

deivid-rodriguez commented Dec 6, 2022

When you configure Bundler to use a path relative to your project, the GEM_HOME location (the location where RubyGems installs and looks for gems) changes from your global Ruby installation to your local folder. That includes specifications, cached packages, install paths and anything else RubyGems needs to work.

I'm guessing the cache is not as necessary with a local install path, but it's just a cache, things should just work without it.

@blowfishpro
Copy link
Author

Right okay. So I guess the second half of my inquiry was really this: is there a way to either:

  • Explicitly clean out the cache using bundler or rubygems commands
  • Control the cache location

@deivid-rodriguez
Copy link
Member

I don't think you can do either of those right now, no.

@h3xx
Copy link

h3xx commented Dec 11, 2023

This functionality is missing and should have a sane default, regardless of where bundler is configured to install its gems.

For example, ~/.bundle/cache/gem-cache/foo-0.0.1.gem

Since the remote files aren't likely to change across bundle install invocations, it should be safe to store them in a shared path.

This behavior would mimic composer and pnpm.

@indirect
Copy link
Member

The historical reason this does not exist is because RubyGems had a single "gem path" for both .gem files and for the installed gems. (For example, as if npm used node_modules for both the .tgz files and the unpacked packages). That led to a "global" install path and a "local" install path, but no shared cache of .gem files between them.

That said, I agree this is a good idea, and it would save both hard drive space and time during future installs. I believe it should probably default to ~/.cache/rubygems/gems, and should be a shared cache for all RubyGems or Bundler installs on the same machine, since the .gem files do not change between Ruby, RubyGems, or Bundler versions.

@indirect
Copy link
Member

I have opened #7249 to track adding such a cache.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants