Skip to content

Commit e9cb2af

Browse files
committed
Add credential helper support for private gem registries
rubygems/rfcs#59
1 parent e697f99 commit e9cb2af

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

bundler/lib/bundler/settings.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class Settings
8989
system_bindir
9090
trust-policy
9191
version
92+
credential-helper
9293
].freeze
9394

9495
DEFAULT_CONFIG = {
@@ -197,7 +198,7 @@ def mirror_for(uri)
197198
end
198199

199200
def credentials_for(uri)
200-
self[uri.to_s] || self[uri.host]
201+
credentials_from_helper(uri) || self[uri.to_s] || self[uri.host]
201202
end
202203

203204
def gem_mirrors
@@ -595,5 +596,18 @@ def self.key_to_s(key)
595596
end
596597
end
597598
end
599+
600+
def credentials_from_helper(uri)
601+
helper_key = "credential-helper.#{uri.host}"
602+
helper_path = self[helper_key]
603+
return unless helper_path
604+
605+
begin
606+
output = `#{helper_path}`.strip
607+
output unless output.empty?
608+
rescue StandardError => e
609+
Bundler.ui.warn "Credential helper failed: #{e.message}"
610+
end
611+
end
598612
end
599613
end

bundler/spec/bundler/settings_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,31 @@
263263
expect(settings.credentials_for(uri)).to eq(credentials)
264264
end
265265
end
266+
267+
context "with credential helper configured" do
268+
let(:helper_path) { "/path/to/helper" }
269+
270+
before do
271+
settings.set_local "credential-helper.gemserver.example.org", helper_path
272+
end
273+
274+
it "uses the credential helper when configured" do
275+
expect(settings).to receive(:`).with(helper_path).and_return("username:password\n")
276+
expect(settings.credentials_for(uri)).to eq("username:password")
277+
end
278+
279+
it "fallback to config when helper fails" do
280+
expect(settings).to receive(:`).with(helper_path).and_raise(StandardError, "Helper failed")
281+
expect(Bundler.ui).to receive(:warn).with("Credential helper failed: Helper failed")
282+
settings.set_local "gemserver.example.org", "fallback:password"
283+
expect(settings.credentials_for(uri)).to eq("fallback:password")
284+
end
285+
286+
it "returns nil when helper fails and no fallback config exists" do
287+
expect(settings).to receive(:`).with(helper_path).and_return("")
288+
expect(settings.credentials_for(uri)).to be_nil
289+
end
290+
end
266291
end
267292

268293
describe "URI normalization" do

0 commit comments

Comments
 (0)