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

Provide a hermetic bundle command #41

Closed
alexeagle opened this issue Dec 3, 2023 · 12 comments
Closed

Provide a hermetic bundle command #41

alexeagle opened this issue Dec 3, 2023 · 12 comments

Comments

@alexeagle
Copy link
Collaborator

Without installing any ruby stuff on my machine, I'd like to be able to edit the Gemfile and Gemfile.lock files in a correct way by running sth like bazel run @ruby//:gem -- install rails, without worrying about version skew with a different version of gem than Bazel will use.

@alexeagle
Copy link
Collaborator Author

I see that the interpreter ships with a gem binary so I think this is pretty simple, we just need an alias target or something and documentation about how to invoke the dist/bin/gem binary in the rules_ruby_dist external repo

@p0deje
Copy link
Member

p0deje commented Dec 3, 2023

Gem is not used to install dependencies in Gemfile/Gemfile.lock. Instead, one should use the following:

bazel run @rules_ruby_dist//:bundle -- add rails

This doesn't work at the moment though, I'll fix it.

@alexeagle
Copy link
Collaborator Author

Existing documentation tells developers to run gem install though https://guides.rubyonrails.org/getting_started.html#creating-a-new-rails-project-installing-rails-installing-rails
so we should allow the most similar command under Bazel too.

@alexeagle
Copy link
Collaborator Author

OH I see, it really doesn't, rails is just doing something sneaky to run it later? From that link

This will create a Rails application called Blog in a blog directory and install the gem dependencies that are already mentioned in Gemfile using bundle install.

@p0deje
Copy link
Member

p0deje commented Dec 3, 2023

Yes, installing Rails gem globally in this manual is just to make a rails new command - this will create a proper project with Gemfile containing rails gem.

@p0deje
Copy link
Member

p0deje commented Dec 4, 2023

I just tested and the following works:

$ bazel run @bundle//:bin/bundle -- add rails
# a lot of output with installing rails

$ git diff --stat
 examples/gem/Gemfile       |   2 ++
 examples/gem/Gemfile.lock  | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 147 insertions(+), 2 deletions(-)

I've seen issues doing this on JRuby, but it works fine on MRI.

@alexeagle
Copy link
Collaborator Author

alexeagle commented Dec 4, 2023

That feels like a bootstrap issue, how would I get a @bundle external repo if I haven't installed anything yet? Does it mean I have to touch Gemfile Gemfile.lock first so there are empty files to include in an rb_bundle() repo rule?

Similarly, if I'm in a state where bundle install is failing, then there's no way to run the bundle command, for example I wanted to run bundle platform to understand why I don't get a pre-compiled gem in a certain situation.

@alexeagle alexeagle changed the title Provide a hermetic gem command Provide a hermetic bundle command Dec 4, 2023
@p0deje
Copy link
Member

p0deje commented Dec 5, 2023

@alexeagle Yes, we should still expose ruby/gem commands. However, gem should only be used for bootstrapping - for everything else bundle is a proper choice.

@p0deje
Copy link
Member

p0deje commented Jan 16, 2024

@alexeagle Are there any great examples of rulesets exposing interpreter binaries? In case of Ruby, we cannot simply export bin/ directory because PATH/GEM_PATH (and potentially other variables) needs to be exported.

@RyanDraves
Copy link
Contributor

@alexeagle Are there any great examples of rulesets exposing interpreter binaries? In case of Ruby, we cannot simply export bin/ directory because PATH/GEM_PATH (and potentially other variables) needs to be exported.

I don't have examples off-hand, but I've usually seen tools exposed exposed as @module//<tool>_binary or something similar.

#48 seems to have gotten rid of support for this bin/ export, which is unfortunate because I was having success using a script that calls

bazel run @bundle//:bin/bundle -- $@

but that doesn't seem supported anymore.

For those following along and wanting the tool to be exposed, I got it working by digging for the target corresponding to the binary and wrapping it into a script to jump out of the sandbox:

BUILD

sh_binary(
    name = "bundle",
    srcs = ["jump_script.sh"],
    # Version grabbed from `bazel query "@bundle//:*"`
    data = ["@bundle//:bundler-2.2.33"],
    args = ["$(locations @bundle//:bundler-2.2.33)"],
)
jump_script.sh

#!/bin/bash
# Grabs a hermetically installed tool and hops back into the workspace
# Borrowed from https://stackoverflow.com/a/72816931

set -e

LAUNCH_WORKING_DIRECTORY=$(pwd)

if test "${BUILD_WORKING_DIRECTORY+x}"; then
  cd $BUILD_WORKING_DIRECTORY
fi

# I can't figure out a way to deal with needing `$locations` over `$location`, so the final path is hardcoded + the number of arguments to skip (1 extra path) is hardcoded
$LAUNCH_WORKING_DIRECTORY/$1/bin/bundle "${@:3}"

which lets me know run (or wrap into a separate script) bazel run //:bundle --

@p0deje
Copy link
Member

p0deje commented Jan 18, 2024

#48 seems to have gotten rid of support for this bin/ export, which is unfortunate because I was having success using a script that calls

Indeed it no longer works, though for a transition period, you could still use rb_bundle(...) which still behaves exactly as before. Eventually, I'll implement all the binstubs support. That's actually the first thing on my list.

For those following along and wanting the tool to be exposed, I got it working by digging for the target corresponding to the binary and wrapping it into a script to jump out of the sandbox:

Thanks for sharing, I'll see if I could generalize this solution.

@p0deje
Copy link
Member

p0deje commented Jan 19, 2024

I managed to have binaries for the toolchain (@ruby), it would look like this:

    bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
    bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
    bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
    bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

I'm yet to make binaries work for @bundle installations.

p0deje added a commit that referenced this issue Jan 19, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
p0deje added a commit that referenced this issue Jan 19, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby -- -e "puts 123"             -> evaluate Ruby script
bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
p0deje added a commit that referenced this issue Jan 19, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby -- -e "puts 123"             -> evaluate Ruby script
bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
p0deje added a commit that referenced this issue Jan 20, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby -- -e "puts 123"             -> evaluate Ruby script
bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
p0deje added a commit that referenced this issue Jan 20, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby -- -e "puts 123"             -> evaluate Ruby script
bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
p0deje added a commit that referenced this issue Jan 22, 2024
This allows to use gems installed in toolchain directly.
It works by running binaries with `bazel run @ruby//:<binary>`.
Some examples:

bazel run @ruby -- -e "puts 123"             -> evaluate Ruby script
bazel run @ruby//:bundle -- update           -> update gems in Gemfile.lock
bazel run @ruby//:bundle -- add rails        -> add Rails gem to Gemfile
bazel run @ruby//:gem -- install rails       -> install Rails gem to the toolchain
bazel run @ruby//:rails -- new $(pwd)/my_app -> create Rails application to ./my_app directory

Fixes #41
@p0deje p0deje closed this as completed in 40e24bf Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants