Skip to content

Commit c1b0037

Browse files
committed
Merge pull request #34 from kbrock/gem_path
Allow user to specify a PATH to search for gem overrides
2 parents f9db319 + 6a9ebc9 commit c1b0037

File tree

4 files changed

+99
-10
lines changed

4 files changed

+99
-10
lines changed

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ original declaration.
7979

8080
## Configuration
8181

82+
### Disabling warnings
83+
8284
To disable warnings that are output to the console when `override_gem` or
8385
`ensure_gem` is in use, you can update a bundler setting:
8486

@@ -95,6 +97,32 @@ $ export BUNDLE_BUNDLER_INJECT__DISABLE_WARN_OVERRIDE_GEM=true
9597
There is a fallback for those that will check the `RAILS_ENV` environment
9698
variable, and will disable the warning when in `"production"`.
9799

100+
### Specifying gem source directories
101+
102+
Many developers checkout gems into a single directory for enhancement.
103+
Instead of specifying the full path of gems every time, specify a gem path
104+
to locate these directories. This can be defined with a bundler setting:
105+
106+
```console
107+
$ bundle config bundler_inject.gem_path ~/src:~/gem_src
108+
```
109+
110+
or use an environment variable:
111+
112+
```console
113+
$ export BUNDLE_BUNDLER_INJECT__GEM_PATH=~/src:~/gem_src
114+
```
115+
116+
An override will find a gem in either of these two directories or in the directory
117+
where the Gemfile override is located.
118+
119+
```Gemfile
120+
# located in ~/src/ansi
121+
override_gem "ansi"
122+
# located in $PWD/mime_override
123+
override_gem "mime/type", path: "mime_override"
124+
```
125+
98126
## What is this sorcery?
99127

100128
While this is technically a bundler plugin, bundler-inject does not use the

lib/bundler/inject/dsl_patch.rb

+26-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def override_gem(name, *args)
88
calling_file = "#{calling_loc.path}:#{calling_loc.lineno}"
99

1010
remove_dependencies_and_sources(dependency)
11-
expand_gem_path(args, calling_file)
11+
expand_gem_path(name, args, calling_file)
1212
gem(name, *args).tap do
1313
warn_override_gem(calling_file, name, args)
1414
end
@@ -59,10 +59,17 @@ def remove_dependencies_and_sources(dependency)
5959
end
6060
end
6161

62-
def expand_gem_path(args, calling_file)
62+
# Determine the path for the gem
63+
#
64+
# This is used when an override has no options or a path is specified
65+
# This path is turned into an absolute path
66+
def expand_gem_path(name, args, calling_file)
67+
args << {:path => name} if args.empty?
6368
return unless args.last.kind_of?(Hash) && args.last[:path]
6469

65-
args.last[:path] = File.expand_path(args.last[:path], File.dirname(calling_file))
70+
possible_paths = [File.dirname(calling_file)] + bundler_inject_gem_path
71+
full_path = possible_paths.map { |p| File.expand_path(args.last[:path], p) }.detect { |f| File.exist?(f) }
72+
args.last[:path] = full_path if full_path
6673
end
6774

6875
def extract_version_opts(args)
@@ -98,6 +105,22 @@ def load_bundler_d(dir)
98105
eval_gemfile(f)
99106
end
100107
end
108+
109+
# Path to search for override gems
110+
#
111+
# The gem path can be set in two ways:
112+
#
113+
# - Via bundler's Bundler::Settings
114+
#
115+
# bundle config bundler_inject.gem_path ~/src:~/gems_src
116+
#
117+
# - Via an environment variable
118+
#
119+
# BUNDLE_BUNDLER_INJECT__GEM_PATH=~/src:~/gems_src
120+
#
121+
def bundler_inject_gem_path
122+
@bundler_inject_gem_path ||= (Bundler.settings["bundler_inject.gem_path"] || "").split(File::PATH_SEPARATOR)
123+
end
101124
end
102125
end
103126
end

spec/bundler_inject_spec.rb

+42-4
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@
117117
expect(err).to match %r{^\*\* override_gem\("ansi", :git=>"https://github.com/rubyworks/ansi"\) at .+/bundler\.d/local_overrides\.rb:1$}
118118
end
119119

120-
it "with a path" do
121-
with_path_based_gem("https://github.com/rubyworks/ansi") do |path|
120+
it "with an absolute path" do
121+
with_path_based_gem("https://github.com/rubyworks/ansi", "the_gem") do |path|
122122
write_bundler_d_file <<~F
123123
override_gem "ansi", :path => #{path.to_s.inspect}
124124
F
@@ -129,8 +129,8 @@
129129
end
130130
end
131131

132-
it "with a path that includes ~" do
133-
with_path_based_gem("https://github.com/rubyworks/ansi") do |path|
132+
it "with a full path that includes ~" do
133+
with_path_based_gem("https://github.com/rubyworks/ansi", "the_gem") do |path|
134134
path = Pathname.new("~/#{path.relative_path_from(Pathname.new("~").expand_path)}")
135135

136136
write_bundler_d_file <<~F
@@ -143,6 +143,44 @@
143143
end
144144
end
145145

146+
it "with a filename path in a gem_path location" do
147+
with_path_based_gem("https://github.com/rubyworks/ansi", "the_gem") do |path|
148+
write_bundler_d_file <<~F
149+
override_gem "ansi", :path => "the_gem"
150+
F
151+
bundle(:update, :env => {"BUNDLE_BUNDLER_INJECT__GEM_PATH" => path.dirname.to_s})
152+
153+
expect(lockfile_specs).to eq [["ansi", "1.5.0"]]
154+
expect(err).to match %r{^\*\* override_gem\("ansi", :path=>#{path.expand_path.to_s.inspect}\) at .+/bundler\.d/local_overrides\.rb:1$}
155+
end
156+
end
157+
158+
it "with no path in a gem_path location" do
159+
with_path_based_gem("https://github.com/rubyworks/ansi", "ansi") do |path|
160+
write_bundler_d_file <<~F
161+
override_gem "ansi"
162+
F
163+
bundle(:update, :env => {"BUNDLE_BUNDLER_INJECT__GEM_PATH" => path.dirname.to_s})
164+
165+
expect(lockfile_specs).to eq [["ansi", "1.5.0"]]
166+
expect(err).to match %r{^\*\* override_gem\("ansi", :path=>#{path.expand_path.to_s.inspect}\) at .+/bundler\.d/local_overrides\.rb:1$}
167+
end
168+
end
169+
170+
it "with no path in a gem_path location and multiple paths" do
171+
with_path_based_gem("https://github.com/rubyworks/ansi", "ansi") do |path|
172+
Dir.mktmpdir do |empty_dir|
173+
write_bundler_d_file <<~F
174+
override_gem "ansi"
175+
F
176+
bundle(:update, :env => {"BUNDLE_BUNDLER_INJECT__GEM_PATH" => "/nonexistent-directory/:#{empty_dir.to_s}:#{path.dirname.to_s}"})
177+
178+
expect(lockfile_specs).to eq [["ansi", "1.5.0"]]
179+
expect(err).to match %r{^\*\* override_gem\("ansi", :path=>#{path.expand_path.to_s.inspect}\) at .+/bundler\.d/local_overrides\.rb:1$}
180+
end
181+
end
182+
end
183+
146184
it "when the gem doesn't exist" do
147185
write_bundler_d_file <<~F
148186
override_gem "omg"

spec/support/helpers.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,14 @@ def rm_global_bundler_d_dir
9393
FileUtils.rm_rf(Helpers.global_bundler_d_dir)
9494
end
9595

96-
def with_path_based_gem(source_repo)
96+
def with_path_based_gem(source_repo, dir_name)
9797
Dir.mktmpdir do |path|
9898
path = Pathname.new(path)
9999
Dir.chdir(path) do
100-
out, status = Open3.capture2e("git clone --depth 1 #{source_repo} the_gem")
100+
out, status = Open3.capture2e("git clone --depth 1 #{source_repo} #{dir_name}")
101101
raise "An error occured while cloning #{source_repo.inspect}...\n#{out}" unless status.exitstatus == 0
102102
end
103-
path = path.join("the_gem")
103+
path = path.join(dir_name)
104104

105105
yield path
106106
end

0 commit comments

Comments
 (0)