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

This PR refactors bundle steps and :bin generation #61

Merged
merged 2 commits into from
Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/simple_script/.ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.5
2.6.5
11 changes: 4 additions & 7 deletions examples/simple_script/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ruby_binary(
deps = [
":lib",
"//lib:foo",
"@bundle//:gems",
"@bundle//:bin",
],
)

Expand All @@ -77,10 +77,7 @@ ruby_test(
main = "spec/spec_helper.rb",
rubyopt = ["-rrspec/autorun"],
deps = [
"@bundle//:awesome_print",
"@bundle//:colored2",
"@bundle//:rspec",
"@bundle//:rspec-its",
"@bundle//:gems",
],
)

Expand All @@ -103,6 +100,7 @@ ruby_test(
main = "@bundle//:bin/rspec",
deps = [
"@bundle//:awesome_print",
"@bundle//:bin",
"@bundle//:colored2",
"@bundle//:rspec",
"@bundle//:rspec-its",
Expand Down Expand Up @@ -138,7 +136,6 @@ ruby_binary(
srcs = [
".relaxed-rubocop-2.4.yml",
".rubocop.yml",
"@bundle//:bin/rubocop",
],
args = [
"-c",
Expand All @@ -150,6 +147,6 @@ ruby_binary(
deps = [
":lib",
"//lib:foo",
"@bundle//:rubocop",
"@bundle//:bin",
],
)
2 changes: 1 addition & 1 deletion examples/simple_script/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ load("@bazelruby_ruby_rules//ruby:defs.bzl", "ruby_bundle")

ruby_bundle(
name = "bundle",
bundler_version = "2.1.2",
excludes = {
"mini_portile": ["test/**/*"],
},
gemfile = "//:Gemfile",
gemfile_lock = "//:Gemfile.lock",
version = "2.0.2",
)
2 changes: 1 addition & 1 deletion ruby/private/binary_wrapper.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def main(args)
loadpaths = create_loadpath_entries(custom_loadpaths, runfiles)
loadpaths += get_repository_imports(runfiles)
loadpaths += ENV['RUBYLIB'].split(':') if ENV.key?('RUBYLIB')
ENV['RUBYLIB'] = loadpaths.join(':')
ENV['RUBYLIB'] = loadpaths.sort.uniq.join(':')

runfiles_envkey, runfiles_envvalue = runfiles_envvar(runfiles)
ENV[runfiles_envkey] = runfiles_envvalue if runfiles_envkey
Expand Down
65 changes: 38 additions & 27 deletions ruby/private/bundle/bundle.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,23 @@ load("//ruby/private/tools:deprecations.bzl", "deprecated_attribute")

# Runs bundler with arbitrary arguments
# eg: run_bundler(runtime_ctx, [ "lock", " --gemfile", "Gemfile.rails5" ])
def run_bundler(runtime_ctx, bundler_arguments):
#print("BUNDLE RUN", bundler_arguments)

def run_bundler(runtime_ctx, bundler_arguments, previous_result):
# Now we are running bundle install
bundler_command = bundler_arguments[0]
bundler_args = []

# add --verbose to all commands except install
if bundler_command != "install":
bundler_args += ["--verbose"]

bundler_args += bundler_arguments[1:]

args = [
runtime_ctx.interpreter, # ruby
"--enable=gems", # bundler must run with rubygems enabled
"-I",
".",
"-I", # Used to tell Ruby where to load the library scripts
BUNDLE_PATH, # Add vendor/bundle to the list of resolvers
BUNDLE_BINARY, # our binary
] + bundler_arguments
] + [bundler_command] + bundler_args

# print("Bundler Command:\n\n", args)

Expand All @@ -41,7 +45,7 @@ def run_bundler(runtime_ctx, bundler_arguments):
# $ bundle config --local | --global config-option config-value
#
# @config_category can be either 'local' or 'global'
def set_bundler_config(runtime_ctx, config_category = "local"):
def set_bundler_config(runtime_ctx, previous_result, config_category = "local"):
# Bundler is deprecating various flags in favor of the configuration.
# HOWEVER — for reasons I can't explain, Bazel runs "bundle install" *prior*
# to setting these flags. So the flags are then useless until we can force the
Expand All @@ -52,16 +56,20 @@ def set_bundler_config(runtime_ctx, config_category = "local"):
bundler_config = {
"deployment": "true",
"standalone": "true",
"force": "false",
"redownload": "false",
"frozen": "true",
"without": "development,test",
"path": BUNDLE_PATH,
"jobs": "20",
"shebang": runtime_ctx.interpreter,
}

for option, value in bundler_config.items():
args = ["config", "--%s" % (config_category), option, value]
last_result = previous_result

result = run_bundler(runtime_ctx, args)
for option, value in bundler_config.items():
args = ["config", "set", "--%s" % (config_category), option, value]
result = run_bundler(runtime_ctx, args, last_result)
last_result = result
if result.return_code:
message = "Failed to set bundle config {} to {}: {}".format(
option,
Expand All @@ -70,8 +78,7 @@ def set_bundler_config(runtime_ctx, config_category = "local"):
)
fail(message)

# The new way to generate binstubs is via the binstubs command, not config option.
return run_bundler(runtime_ctx, ["binstubs", "--path", BUNDLE_BIN_PATH])
return last_result

# This function is called "pure_ruby" because it downloads and unpacks the gem
# file into a given folder, which for gems without C-extensions is the same
Expand All @@ -96,6 +103,8 @@ def install_pure_ruby_gem(runtime_ctx, gem_name, gem_version, folder):
result.stderr,
)
fail(message)
else:
return result

def install_bundler(runtime_ctx, bundler_version):
return install_pure_ruby_gem(
Expand All @@ -105,21 +114,26 @@ def install_bundler(runtime_ctx, bundler_version):
"bundler",
)

def bundle_install(runtime_ctx):
def bundle_install(runtime_ctx, previous_result):
result = run_bundler(
runtime_ctx,
[
"install", # bundle install
"--standalone", # Makes a bundle that can work without depending on Rubygems or Bundler at runtime.
"--binstubs={}".format(BUNDLE_BIN_PATH), # Creates a directory and place any executables from the gem there.
"--path={}".format(BUNDLE_PATH), # The location to install the specified gems to.
"install",
"--binstubs={}".format(BUNDLE_BIN_PATH),
"--path={}".format(BUNDLE_PATH),
"--deployment",
"--standalone",
"--frozen",
],
previous_result,
)

if result.return_code:
fail("bundle install failed: %s%s" % (result.stdout, result.stderr))
else:
return result

def generate_bundle_build_file(runtime_ctx):
def generate_bundle_build_file(runtime_ctx, previous_result):
# Create the BUILD file to expose the gems to the WORKSPACE
# USAGE: ./create_bundle_build_file.rb BUILD.bazel Gemfile.lock repo-name [excludes-json] workspace-name
args = [
Expand Down Expand Up @@ -160,19 +174,16 @@ def _ruby_bundle_impl(ctx):
)

# 1. Install the right version of the Bundler Gem
install_bundler(runtime_ctx, bundler_version)

# Create label for the Bundler executable
bundler = Label("//:" + BUNDLE_BINARY)
result = install_bundler(runtime_ctx, bundler_version)

# 2. Set Bundler config in the .bundle/config file
set_bundler_config(runtime_ctx)
result = set_bundler_config(runtime_ctx, result)

# 3. Run bundle install
bundle_install(runtime_ctx)
result = bundle_install(runtime_ctx, result)

# 4. Generate the BUILD file for the bundle
generate_bundle_build_file(runtime_ctx)
generate_bundle_build_file(runtime_ctx, result)

ruby_bundle = repository_rule(
implementation = _ruby_bundle_impl,
Expand Down
Loading