bundler-leak 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +59 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +47 -0
  4. data/.github/workflows/test.yml +27 -0
  5. data/.gitignore +1 -2
  6. data/ChangeLog.md +6 -121
  7. data/Gemfile +1 -1
  8. data/README.md +20 -11
  9. data/Rakefile +2 -15
  10. data/bin/setup +4 -0
  11. data/bundler-leak.gemspec +2 -1
  12. data/code-of-conduct.md +77 -0
  13. data/data/ruby-mem-advisory-db.ts +1 -1
  14. data/{bin → exe}/bundle-leak +0 -0
  15. data/{bin → exe}/bundler-leak +0 -0
  16. data/fastruby-logo.png +0 -0
  17. data/gemspec.yml +4 -1
  18. data/lib/bundler/plumber/advisory.rb +22 -12
  19. data/lib/bundler/plumber/cli.rb +9 -8
  20. data/lib/bundler/plumber/database.rb +7 -6
  21. data/lib/bundler/plumber/scanner.rb +2 -9
  22. data/lib/bundler/plumber/version.rb +1 -1
  23. data/pull_request_template.md +7 -0
  24. data/spec/advisory_spec.rb +6 -6
  25. data/spec/bundle/unpatched_gems/Gemfile +0 -35
  26. data/spec/bundle/unpatched_gems/Gemfile.lock +60 -0
  27. data/spec/cli_spec.rb +49 -33
  28. data/spec/database_spec.rb +25 -15
  29. data/spec/integration_spec.rb +16 -12
  30. data/spec/scanner_spec.rb +4 -16
  31. data/spec/spec_helper.rb +23 -5
  32. metadata +38 -37
  33. data/.travis.yml +0 -13
  34. data/data/ruby-mem-advisory-db/.gitignore +0 -1
  35. data/data/ruby-mem-advisory-db/.rspec +0 -1
  36. data/data/ruby-mem-advisory-db/.travis.yml +0 -12
  37. data/data/ruby-mem-advisory-db/CONTRIBUTING.md +0 -69
  38. data/data/ruby-mem-advisory-db/CONTRIBUTORS.md +0 -40
  39. data/data/ruby-mem-advisory-db/Gemfile +0 -9
  40. data/data/ruby-mem-advisory-db/Gemfile.lock +0 -38
  41. data/data/ruby-mem-advisory-db/LICENSE.txt +0 -5
  42. data/data/ruby-mem-advisory-db/README.md +0 -72
  43. data/data/ruby-mem-advisory-db/Rakefile +0 -26
  44. data/data/ruby-mem-advisory-db/gems/celluloid/670.yml +0 -10
  45. data/data/ruby-mem-advisory-db/gems/grape/301.yml +0 -9
  46. data/data/ruby-mem-advisory-db/gems/oj/229.yml +0 -9
  47. data/data/ruby-mem-advisory-db/gems/redcarpet/516.yml +0 -12
  48. data/data/ruby-mem-advisory-db/gems/redis/612.yml +0 -9
  49. data/data/ruby-mem-advisory-db/gems/sidekiq/2598.yml +0 -9
  50. data/data/ruby-mem-advisory-db/gems/sidekiq-statistic/73.yml +0 -9
  51. data/data/ruby-mem-advisory-db/gems/therubyracer/336.yml +0 -13
  52. data/data/ruby-mem-advisory-db/gems/zipruby/PRE-SA-2012-02.yml +0 -9
  53. data/data/ruby-mem-advisory-db/scripts/post-advisories.sh +0 -18
  54. data/data/ruby-mem-advisory-db/spec/advisories_spec.rb +0 -23
  55. data/data/ruby-mem-advisory-db/spec/advisory_example.rb +0 -209
  56. data/data/ruby-mem-advisory-db/spec/gem_example.rb +0 -37
  57. data/data/ruby-mem-advisory-db/spec/library_example.rb +0 -21
  58. data/data/ruby-mem-advisory-db/spec/ruby_example.rb +0 -22
  59. data/data/ruby-mem-advisory-db/spec/spec_helper.rb +0 -1
  60. data/spec/bundle/insecure_sources/Gemfile +0 -39
  61. data/spec/bundle/secure/Gemfile +0 -38
@@ -72,8 +72,10 @@ module Bundler
72
72
  t1 = Dir.chdir(USER_PATH) { Time.parse(`git log --date=iso8601 --pretty="%cd" -1`) }
73
73
  t2 = VENDORED_TIMESTAMP
74
74
 
75
- if t1 >= t2 then USER_PATH
76
- else VENDORED_PATH
75
+ if t1 >= t2
76
+ USER_PATH
77
+ else
78
+ VENDORED_PATH
77
79
  end
78
80
  else
79
81
  VENDORED_PATH
@@ -98,9 +100,8 @@ module Bundler
98
100
  if File.directory?(USER_PATH)
99
101
  if File.directory?(File.join(USER_PATH, ".git"))
100
102
  Dir.chdir(USER_PATH) do
101
- command = %w(git fetch --all)
102
- command = %w(git reset --hard origin/master)
103
- command << '--quiet' if options[:quiet]
103
+ command = "git fetch --all; git reset --hard origin/main"
104
+ command << ' --quiet' if options[:quiet]
104
105
 
105
106
  system *command
106
107
  end
@@ -176,7 +177,7 @@ module Bundler
176
177
  return enum_for(__method__,gem) unless block_given?
177
178
 
178
179
  advisories_for(gem.name) do |advisory|
179
- if advisory.vulnerable?(gem.version)
180
+ if advisory.leaky?(gem.version)
180
181
  yield advisory
181
182
  end
182
183
  end
@@ -80,9 +80,6 @@ module Bundler
80
80
  def scan(options={},&block)
81
81
  return enum_for(__method__, options) unless block
82
82
 
83
- ignore = Set[]
84
- ignore += options[:ignore] if options[:ignore]
85
-
86
83
  scan_specs(options, &block)
87
84
 
88
85
  return self
@@ -118,12 +115,8 @@ module Bundler
118
115
 
119
116
  @lockfile.specs.each do |gem|
120
117
  @database.check_gem(gem) do |advisory|
121
-
122
- # TODO this logic should be modified for rubymem
123
- #unless (ignore.include?(advisory.cve_id) || ignore.include?(advisory.osvdb_id))
124
- # yield UnpatchedGem.new(gem,advisory)
125
- #end
126
- yield UnpatchedGem.new(gem, advisory)
118
+ gem_and_id = "#{advisory.gem}-#{advisory.id}"
119
+ yield UnpatchedGem.new(gem,advisory) unless ignore.include?(gem_and_id)
127
120
  end
128
121
  end
129
122
  end
@@ -19,6 +19,6 @@
19
19
  module Bundler
20
20
  module Plumber
21
21
  # bundler-leak version
22
- VERSION = '0.1.0'
22
+ VERSION = '0.3.0'
23
23
  end
24
24
  end
@@ -0,0 +1,7 @@
1
+ **IMPORTANT: Please read the README before submitting pull requests for this project. Additionally, if your PR closes any open GitHub issues, make sure you include _Closes #XXXX_ in your comment or use the option on the PR's sidebar to add related issues to auto-close the issue that your PR fixes. **
2
+
3
+ **Description:**
4
+
5
+ Please include a summary of the change and which issue is fixed or which feature is introduced. If changes to the behavior are made, clearly describe what changes.
6
+
7
+ I will abide by the [code of conduct](code_of_conduct.md).
@@ -27,7 +27,7 @@ describe Bundler::Plumber::Advisory do
27
27
  subject { described_class.load(path) }
28
28
 
29
29
  describe "load" do
30
- let(:data) { YAML.load_file(path) }
30
+ let(:data) { YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(File.read(path)) : YAML.load_file(path) }
31
31
 
32
32
  describe '#id' do
33
33
  subject { super().id }
@@ -115,12 +115,12 @@ describe Bundler::Plumber::Advisory do
115
115
  end
116
116
  end
117
117
 
118
- describe "#vulnerable?" do
118
+ describe "#leaky?" do
119
119
  context "when passed a version that matches one patched version" do
120
120
  let(:version) { Gem::Version.new('0.12.4') }
121
121
 
122
122
  it "should return false" do
123
- expect(subject.vulnerable?(version)).to be_falsey
123
+ expect(subject.leaky?(version)).to be_falsey
124
124
  end
125
125
  end
126
126
 
@@ -128,7 +128,7 @@ describe Bundler::Plumber::Advisory do
128
128
  let(:version) { Gem::Version.new('2.9.0') }
129
129
 
130
130
  it "should return true" do
131
- expect(subject.vulnerable?(version)).to be_truthy
131
+ expect(subject.leaky?(version)).to be_truthy
132
132
  end
133
133
 
134
134
  context "when unaffected_versions is not empty" do
@@ -138,7 +138,7 @@ describe Bundler::Plumber::Advisory do
138
138
  let(:version) { Gem::Version.new(an_unaffected_version) }
139
139
 
140
140
  it "should return false" do
141
- expect(subject.vulnerable?(version)).to be_falsey
141
+ expect(subject.leaky?(version)).to be_falsey
142
142
  end
143
143
  end
144
144
 
@@ -146,7 +146,7 @@ describe Bundler::Plumber::Advisory do
146
146
  let(:version) { Gem::Version.new('1.2.3') }
147
147
 
148
148
  it "should return true" do
149
- expect(subject.vulnerable?(version)).to be_truthy
149
+ expect(subject.leaky?(version)).to be_truthy
150
150
  end
151
151
  end
152
152
  end
@@ -2,38 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem "celluloid", "0.17.0"
4
4
  gem "therubyracer", "0.12.1"
5
-
6
- # Bundle edge Rails instead:
7
- # gem 'rails', :git => 'git://github.com/rails/rails.git'
8
-
9
- gem 'sqlite3', platform: [:mri, :rbx]
10
-
11
-
12
- # Gems used only for assets and not required
13
- # in production environments by default.
14
- group :assets do
15
- # gem 'sass-rails', '~> 3.2.3'
16
- # gem 'coffee-rails', '~> 3.2.1'
17
-
18
- # See https://github.com/sstephenson/execjs#readme for more supported runtimes
19
- # gem 'therubyracer', :platforms => :ruby
20
-
21
- # gem 'uglifier', '>= 1.0.3'
22
- end
23
-
24
- gem 'jquery-rails'
25
-
26
- # To use ActiveModel has_secure_password
27
- # gem 'bcrypt-ruby', '~> 3.0.0'
28
-
29
- # To use Jbuilder templates for JSON
30
- # gem 'jbuilder'
31
-
32
- # Use unicorn as the app server
33
- # gem 'unicorn'
34
-
35
- # Deploy with Capistrano
36
- # gem 'capistrano'
37
-
38
- # To use debugger
39
- # gem 'debugger'
@@ -0,0 +1,60 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ celluloid (0.17.0)
5
+ bundler
6
+ celluloid-essentials
7
+ celluloid-extras
8
+ celluloid-fsm
9
+ celluloid-pool
10
+ celluloid-supervision
11
+ dotenv
12
+ nenv
13
+ rspec-logsplit (>= 0.1.2)
14
+ timers (~> 4.0.0)
15
+ celluloid-essentials (0.20.2)
16
+ bundler
17
+ dotenv
18
+ nenv
19
+ rspec-logsplit (>= 0.1.2)
20
+ timers (~> 4.0.0)
21
+ celluloid-extras (0.20.0)
22
+ bundler
23
+ dotenv
24
+ nenv
25
+ rspec-logsplit (>= 0.1.2)
26
+ timers (~> 4.0.0)
27
+ celluloid-fsm (0.20.0)
28
+ bundler
29
+ dotenv
30
+ nenv
31
+ rspec-logsplit (>= 0.1.2)
32
+ timers (~> 4.0.0)
33
+ celluloid-pool (0.20.0)
34
+ bundler
35
+ dotenv
36
+ nenv
37
+ rspec-logsplit (>= 0.1.2)
38
+ timers (~> 4.0.0)
39
+ celluloid-supervision (0.20.1)
40
+ bundler
41
+ dotenv
42
+ nenv
43
+ rspec-logsplit (>= 0.1.2)
44
+ timers (~> 4.0.0)
45
+ dotenv (2.7.6)
46
+ hitimes (2.0.0)
47
+ nenv (0.3.0)
48
+ rspec-logsplit (0.1.3)
49
+ therubyracer (0.12.1)
50
+ timers (4.0.4)
51
+ hitimes
52
+
53
+ PLATFORMS
54
+ ruby
55
+
56
+ DEPENDENCIES
57
+ celluloid (= 0.17.0)
58
+
59
+ BUNDLED WITH
60
+ 2.1.4
data/spec/cli_spec.rb CHANGED
@@ -5,33 +5,49 @@ describe Bundler::Plumber::CLI do
5
5
  describe "#update" do
6
6
  context "not --quiet (the default)" do
7
7
  context "when update succeeds" do
8
-
9
- before { expect(Bundler::Plumber::Database).to receive(:update!).and_return(true) }
8
+ before { allow(Bundler::Plumber::Database).to receive(:update!).and_return(true) }
10
9
 
11
10
  it "prints updated message" do
12
- expect { subject.update }.to output(/Updated ruby-mem-advisory-db/).to_stdout
11
+ allow(subject).to(
12
+ receive(:say)
13
+ )
14
+
15
+ subject.update
16
+
17
+ expect(subject).to(
18
+ have_received(:say).with("Updated ruby-mem-advisory-db", :green)
19
+ )
13
20
  end
14
21
 
15
22
  it "prints total advisory count" do
16
23
  database = double
17
- expect(database).to receive(:size).and_return(1234)
18
- expect(Bundler::Plumber::Database).to receive(:new).and_return(database)
24
+ allow(database).to receive(:size).and_return(1234)
25
+ allow(Bundler::Plumber::Database).to receive(:new).and_return(database)
26
+
27
+ allow(subject).to(
28
+ receive(:say)
29
+ )
19
30
 
20
- expect { subject.update }.to output(/ruby-mem-advisory-db: 1234 advisories/).to_stdout
31
+ subject.update
32
+
33
+ expect(subject).to(
34
+ have_received(:say).with("ruby-mem-advisory-db: 1234 advisories", :green)
35
+ )
21
36
  end
22
37
  end
23
38
 
24
39
  context "when update fails" do
25
-
26
- before { expect(Bundler::Plumber::Database).to receive(:update!).and_return(false) }
40
+ before { allow(Bundler::Plumber::Database).to receive(:update!).and_return(false) }
27
41
 
28
42
  it "prints failure message" do
29
- expect do
30
- begin
31
- subject.update
32
- rescue SystemExit
33
- end
34
- end.to output(/Failed updating ruby-mem-advisory-db!/).to_stdout
43
+ allow(subject).to(receive(:say))
44
+ allow(subject).to(receive(:exit))
45
+
46
+ subject.update
47
+
48
+ expect(subject).to(
49
+ have_received(:say).with("Failed updating ruby-mem-advisory-db!", :red)
50
+ )
35
51
  end
36
52
 
37
53
  it "exits with error status code" do
@@ -49,14 +65,14 @@ describe Bundler::Plumber::CLI do
49
65
  end
50
66
 
51
67
  context "--quiet" do
52
- before do
53
- allow(subject).to receive(:options).and_return(double("Options", quiet?: true))
68
+ subject do
69
+ Bundler::Plumber::CLI.new([], quiet: true)
54
70
  end
55
71
 
56
72
  context "when update succeeds" do
57
73
 
58
74
  before do
59
- expect(Bundler::Plumber::Database).to(
75
+ allow(Bundler::Plumber::Database).to(
60
76
  receive(:update!).with(quiet: true).and_return(true)
61
77
  )
62
78
  end
@@ -67,31 +83,31 @@ describe Bundler::Plumber::CLI do
67
83
  end
68
84
 
69
85
  context "when update fails" do
70
-
71
86
  before do
72
- expect(Bundler::Plumber::Database).to(
87
+ allow(Bundler::Plumber::Database).to(
73
88
  receive(:update!).with(quiet: true).and_return(false)
74
89
  )
90
+ allow(subject).to receive(:exit)
75
91
  end
76
92
 
77
93
  it "prints failure message" do
78
- expect do
79
- begin
80
- subject.update
81
- rescue SystemExit
82
- end
83
- end.to output(/Failed updating ruby-mem-advisory-db!/).to_stdout
94
+ allow(subject).to(
95
+ receive(:say)
96
+ )
97
+
98
+ subject.update
99
+
100
+ expect(subject).to(
101
+ have_received(:say).with("Failed updating ruby-mem-advisory-db!", :red)
102
+ )
84
103
  end
85
104
 
86
105
  it "exits with error status code" do
87
- expect {
88
- # Capture output of `update` only to keep spec output clean.
89
- # The test regarding specific output is above.
90
- expect { subject.update }.to output.to_stdout
91
- }.to raise_error(SystemExit) do |error|
92
- expect(error.success?).to eq(false)
93
- expect(error.status).to eq(1)
94
- end
106
+ allow(subject).to receive(:exit)
107
+
108
+ subject.update
109
+
110
+ expect(subject).to have_received(:exit).with(1)
95
111
  end
96
112
  end
97
113
  end
@@ -14,13 +14,9 @@ describe Bundler::Plumber::Database do
14
14
  expect(File.directory?(subject)).to be_truthy
15
15
  end
16
16
 
17
- it "should prefer the user repo, iff it's as up to date, or more up to date than the vendored one" do
18
- Bundler::Plumber::Database.update!(quiet: false)
17
+ xit "should prefer the user repo, if it's as up to date, or more up to date than the vendored one" do
19
18
 
20
- Dir.chdir(Bundler::Plumber::Database::USER_PATH) do
21
- puts "Timestamp:"
22
- system 'git log --pretty="%cd" -1'
23
- end
19
+ Bundler::Plumber::Database.update!(quiet: false)
24
20
 
25
21
  # As up to date...
26
22
  expect(Bundler::Plumber::Database.path).to eq mocked_user_path
@@ -29,25 +25,39 @@ describe Bundler::Plumber::Database do
29
25
  fake_a_commit_in_the_user_repo
30
26
  expect(Bundler::Plumber::Database.path).to eq mocked_user_path
31
27
 
32
- roll_user_repo_back(20)
28
+ roll_user_repo_back(2)
33
29
  expect(Bundler::Plumber::Database.path).to eq Bundler::Plumber::Database::VENDORED_PATH
34
30
  end
35
31
  end
36
32
 
37
33
  describe "update!" do
38
- it "should create the USER_PATH path as needed" do
34
+ xit "should create the USER_PATH path as needed" do
39
35
  Bundler::Plumber::Database.update!(quiet: false)
40
36
  expect(File.directory?(mocked_user_path)).to be true
41
37
  end
42
38
 
43
- it "should create the repo, then update it given multple successive calls." do
44
- expect_update_to_clone_repo!
45
- Bundler::Plumber::Database.update!(quiet: false)
46
- expect(File.directory?(mocked_user_path)).to be true
39
+ context "when the :quiet option is false" do
40
+ it "should create the repo, then update it given multiple successive calls." do
41
+ expect_update_to_clone_repo!
42
+ Bundler::Plumber::Database.update!(quiet: false)
43
+ expect(File.directory?(mocked_user_path)).to be true
47
44
 
48
- expect_update_to_update_repo!
49
- Bundler::Plumber::Database.update!(quiet: false)
50
- expect(File.directory?(mocked_user_path)).to be true
45
+ expect_update_to_update_repo!
46
+ Bundler::Plumber::Database.update!(quiet: false)
47
+ expect(File.directory?(mocked_user_path)).to be true
48
+ end
49
+ end
50
+
51
+ context "when the :quiet option is true" do
52
+ it "should create the repo, then update it given multiple successive calls." do
53
+ expect_update_to_clone_repo!(quiet: true)
54
+ Bundler::Plumber::Database.update!(quiet: true)
55
+ expect(File.directory?(mocked_user_path)).to be true
56
+
57
+ expect_update_to_update_repo!(quiet: true)
58
+ Bundler::Plumber::Database.update!(quiet: true)
59
+ expect(File.directory?(mocked_user_path)).to be true
60
+ end
51
61
  end
52
62
  end
53
63
 
@@ -4,7 +4,7 @@ describe "CLI" do
4
4
  include Helpers
5
5
 
6
6
  let(:command) do
7
- File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-leak'))
7
+ File.expand_path(File.join(File.dirname(__FILE__),'..','exe','bundler-leak'))
8
8
  end
9
9
 
10
10
  context "when auditing a bundle with unpatched gems" do
@@ -16,38 +16,42 @@ describe "CLI" do
16
16
  end
17
17
 
18
18
  it "should print a warning" do
19
- expect(subject).to include("Vulnerabilities found!")
19
+ expect(subject).to include("Leaks found!")
20
20
  end
21
21
 
22
- it "should print advisory information for the vulnerable gems" do
22
+ it "should print advisory information for the leaky gems" do
23
23
  advisory_pattern = /(Name: [^\n]+
24
24
  Version: \d+.\d+.\d+
25
25
  URL: https?:\/\/(www\.)?.+
26
26
  Title: [^\n]*?
27
- Solution: remove or disable this gem until a patch is available!)+/
27
+ Solution: upgrade to (~>|>=) \d+\.\d+\.\d+(\.\d+)?(, (~>|>=) \d+\.\d+\.\d+(\.\d+)?)*[\s\n]*?)/
28
28
 
29
29
  expect(subject).to match(advisory_pattern)
30
- expect(subject).to include("Vulnerabilities found!")
30
+ expect(subject).to include("Leaks found!")
31
31
  end
32
32
  end
33
33
 
34
- context "when auditing a secure bundle" do
35
- let(:bundle) { 'secure' }
36
- let(:directory) { File.join('spec','bundle',bundle) }
34
+ context "when auditing a bundle with ignored gems" do
35
+ let(:bundle) { 'unpatched_gems' }
36
+ let(:directory) { File.join('spec','bundle', bundle) }
37
+
38
+ let(:command) do
39
+ File.expand_path(File.join(File.dirname(__FILE__),'..','exe','bundler-leak -i celluloid-670'))
40
+ end
37
41
 
38
42
  subject do
39
- Dir.chdir(directory) { sh(command) }
43
+ Dir.chdir(directory) { sh(command, :fail => true) }
40
44
  end
41
45
 
42
- it "should print nothing when everything is fine" do
43
- expect(subject.strip).to eq("No vulnerabilities found")
46
+ it "should not print advisory information for ignored gem" do
47
+ expect(subject).not_to include("Name: celluloid\nVersion: 0.17.0\n")
44
48
  end
45
49
  end
46
50
 
47
51
  describe "update" do
48
52
 
49
53
  let(:update_command) { "#{command} update" }
50
- let(:bundle) { 'secure' }
54
+ let(:bundle) { 'unpatched_gems' }
51
55
  let(:directory) { File.join('spec','bundle',bundle) }
52
56
 
53
57
  subject do
data/spec/scanner_spec.rb CHANGED
@@ -32,30 +32,18 @@ describe Scanner do
32
32
 
33
33
  it "should match unpatched gems to their advisories" do
34
34
  expect(subject.all? { |result|
35
- result.advisory.vulnerable?(result.gem.version)
35
+ result.advisory.leaky?(result.gem.version)
36
36
  }).to be_truthy
37
37
  end
38
38
 
39
39
  context "when the :ignore option is given" do
40
- subject { scanner.scan(:ignore => ['OSVDB-89026']) }
40
+ subject { scanner.scan(:ignore => ['celluloid-670']) }
41
41
 
42
- it "should ignore the specified advisories" do
42
+ it "should ignore the specified leaky gems" do
43
43
  ids = subject.map { |result| result.advisory.id }
44
44
 
45
- expect(ids).not_to include('OSVDB-89026')
45
+ expect(ids).not_to include('670')
46
46
  end
47
47
  end
48
48
  end
49
-
50
- context "when auditing a secure bundle" do
51
- let(:bundle) { 'secure' }
52
- let(:directory) { File.join('spec','bundle',bundle) }
53
- let(:scanner) { described_class.new(directory) }
54
-
55
- subject { scanner.scan.to_a }
56
-
57
- it "should print nothing when everything is fine" do
58
- expect(subject).to be_empty
59
- end
60
- end
61
49
  end
data/spec/spec_helper.rb CHANGED
@@ -7,7 +7,7 @@ require 'bundler/plumber/database'
7
7
 
8
8
  module Helpers
9
9
  def sh(command, options={})
10
- Bundler.with_clean_env do
10
+ with_unbundled_env do
11
11
  result = `#{command} 2>&1`
12
12
  raise "FAILED #{command}\n#{result}" if $?.success? == !!options[:fail]
13
13
  result
@@ -22,17 +22,24 @@ module Helpers
22
22
  File.expand_path('../../tmp/ruby-mem-advisory-db', __FILE__)
23
23
  end
24
24
 
25
- def expect_update_to_clone_repo!
25
+ def expect_update_to_clone_repo!(quiet: false)
26
+ with = ['git', 'clone']
27
+ with << '--quiet' if quiet
28
+ with << Bundler::Plumber::Database::VENDORED_PATH << mocked_user_path
29
+
26
30
  expect(Bundler::Plumber::Database).
27
31
  to receive(:system).
28
- with('git', 'clone', Bundler::Plumber::Database::VENDORED_PATH, mocked_user_path).
32
+ with(*with).
29
33
  and_call_original
30
34
  end
31
35
 
32
- def expect_update_to_update_repo!
36
+ def expect_update_to_update_repo!(quiet: false)
37
+ with = 'git fetch --all; git reset --hard origin/main'
38
+ with << " --quiet" if quiet
39
+
33
40
  expect(Bundler::Plumber::Database).
34
41
  to receive(:system).
35
- with('git', 'reset', '--hard', 'origin/master').
42
+ with(with).
36
43
  and_call_original
37
44
  end
38
45
 
@@ -47,6 +54,17 @@ module Helpers
47
54
  system 'git', 'reset', '--hard', "HEAD~#{num_commits}"
48
55
  end
49
56
  end
57
+
58
+ private
59
+
60
+ def with_unbundled_env
61
+ bundler_ver = Gem::Version.new(Bundler::VERSION)
62
+ if bundler_ver < Gem::Version.new('2.1.0')
63
+ Bundler.with_clean_env { yield }
64
+ else
65
+ Bundler.with_unbundled_env { yield }
66
+ end
67
+ end
50
68
  end
51
69
 
52
70
  include Bundler::Plumber