bazel-contrib / bazel-contrib/rules_ruby

Allow or document workaround to include workspace-relative paths

Open
#359 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Starlark
Stars
50
Forks
22
Avg merge
9d 23h
Merged PRs (30d)
5

Description

the legacy bazelruby/rules_ruby allowed code to include paths relative to the workspace root, such as

`app/bin/rails`

```
#!/usr/bin/env ruby
APP_PATH = Dir.pwd + "/app/config/application.rb"
require 'app/config/environment'
require 'rails/commands'
```

It seems this is not supported here because there's no `includes` attribute controllable by user of rb_library/rb_test?

Claude says it used to work as follows in bazelruby/rules_ruby:

---
1. includes attribute → incpaths depset

ruby/private/tools/deps.bzl — the transitive_deps() function is the core:

```
# deps.bzl ~line 45
includes = [
paths.join(workspace, inc)
for inc in ctx.attr.includes
]

return struct(
incpaths = depset(
direct = includes, # this rule's includes, workspace-qualified
transitive = deps.incpaths, # collected from all deps
order = "topological",
),
...
)
```
The helper _transitive_srcs pulls ruby_incpaths off the RubyLibraryInfo provider from each dep:
```
def _transitive_srcs(deps):
return struct(
incpaths = [d[RubyLibraryInfo].ruby_incpaths for d in deps if RubyLibraryInfo in d],
...
)
```
Yes, includes is fully transitive — each dep's incpaths depset is unioned in topological order.

---
2. rb_library propagates via RubyLibraryInfo

ruby/private/library.bzl — the provider carries accumulated paths downstream:
```
RubyLibraryInfo(
transitive_ruby_srcs = deps.srcs,
ruby_incpaths = deps.incpaths, # entire transitive depset
rubyopt = deps.rubyopt,
)
```
---
3. rb_binary injects paths into the wrapper template

ruby/private/binary.bzl ~line 65:
```
ctx.actions.expand_template(
template = ctx.file._wrapper_template,
output = executable,
substitutions = {
"{loadpaths}": repr(deps.incpaths.to_list()),
...
},
)
```
---
4. The wrapper script sets RUBYLIB (not -I flags directly)

ruby/private/binary_wrapper.tpl — the launcher uses RUBYLIB, not CLI -I:
```
def create_loadpath_entries(custom, runfiles)
[runfiles] + custom.map { |path| File.join(runfiles, path) }
end

def get_repository_imports(runfiles)
Dir.entries(runfiles)
.reject { |d| [".", ".."].include?(d) }
.map { |d| File.join(runfiles, d) }
.select { |d| File.directory?(d) }
end

def main(args)
custom_loadpaths = {loadpaths} # ← substituted from incpaths.to_list()
runfiles = find_runfiles

loadpaths = create_loadpath_entries(custom_loadpaths, runfiles)
loadpaths += get_repository_imports(runfiles) # ← IMPLICIT entries
loadpaths += ENV['RUBYLIB'].split(':') if ENV.key?('RUBYLIB')
ENV['RUBYLIB'] = loadpaths.sort.uniq.join(':')
end
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.