bundler-audit 0.8.0.rc1 → 0.8.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94290135207c14256ac6d7251be3f0641619ec1273c562bb9c14a1b8ee8e28d5
4
- data.tar.gz: 83d1b6b88e88d5c850d7daadde5d3235389c9620ab35414d78f1be13cd54387d
3
+ metadata.gz: 5d68852584664d93222c7f24f8d7d2f42038e32addf0b79953e4f9ea41c4a803
4
+ data.tar.gz: 929bf4dcf07474ce2222d119377e34630572ca68c1d821ff48056d006c6a731c
5
5
  SHA512:
6
- metadata.gz: 28a461def90014d7d1dea437c17637d342bb8a46a08d1874091effa135a9303b621428ecf57d497867db2a9bda4d76bea032197e447edf8730432558ee1208cd
7
- data.tar.gz: 400fb39383074b315b5d2d7e9339da907f24554c99a00358bd309ca7d6101443229997bb49cb54d8d473e4d6acf3793b294c795349dcc3d0615683e283fbd17a
6
+ metadata.gz: 27f710fb3917beda059a73b41729a1c9ab0d2c4b7472b7ede77c2bbfbd1085deb9cb09eb154c7e4a5a1f41f516f50a27f79110e534d943f56170633c9e2338cc
7
+ data.tar.gz: 48800f8b91c823b69606b38a172a58ff37a2ad64ead80f087da80efcd6cbd0991cc716cbbaa9efc3925690f9da47c750e9c218624aa0b02fad209b6b092aab7b
@@ -0,0 +1,3 @@
1
+ github:
2
+ - postmodern
3
+ - reedloden
@@ -13,8 +13,9 @@ jobs:
13
13
  - 2.5
14
14
  - 2.6
15
15
  - 2.7
16
+ - 3.0
16
17
  - jruby
17
- - truffleruby
18
+ - truffleruby-head
18
19
  name: Ruby ${{ matrix.ruby }}
19
20
  steps:
20
21
  - uses: actions/checkout@v2
data/ChangeLog.md CHANGED
@@ -37,14 +37,15 @@
37
37
 
38
38
  #### CLI
39
39
 
40
- * Added `bundle-audit stats`.
41
- * Added `bundle-audit download`.
42
- * `bundle-audit check`:
40
+ * Require [thor] ~> 1.0.
41
+ * Added `bundler-audit stats`.
42
+ * Added `bundler-audit download`.
43
+ * `bundler-audit check`:
43
44
  * Now accepts a optional `DIR` argument for the project directory.
44
- * `bundle-audit check` will now print an explicit error message and exit,
45
+ * `bundler-audit check` will now print an explicit error message and exit,
45
46
  if the given `DIR` does not exist.
46
- * Will now auto-download/auto-update [ruby-advisory-db] to
47
- ensure the latest advisory information.
47
+ * Will now auto-download [ruby-advisory-db] to ensure the latest advisory
48
+ information is used on first run.
48
49
  * Now supports a `--database` option for specifying a path
49
50
  to an alternative [ruby-advisory-db] copy.
50
51
  * Now supports a `--gemfile-lock` option for specifying a
@@ -53,6 +54,9 @@
53
54
  desired format. `text` and `json` are supported, but other custom formats
54
55
  can be loaded. See {Bundler::Audit::CLI::Formats}.
55
56
  * Now supports a `--output` option for writing the report output to a file.
57
+ * Prints both CVE and GHSA IDs.
58
+ * Print all error messages to stderr.
59
+ * No longer print number of advisories in `bundler-audit version`.
56
60
 
57
61
  ### 0.7.0.1 / 2020-06-12
58
62
 
@@ -91,9 +95,9 @@
91
95
 
92
96
  #### CLI
93
97
 
94
- * Added the `--update` option to `bundle-audit check`.
95
- * `bundle-audit update` now returns a non-zero exit status on error.
96
- * `bundle-audit update` only updates `~/.local/share/ruby-advisory-db`, if it is a git
98
+ * Added the `--update` option to `bundler-audit check`.
99
+ * `bundler-audit update` now returns a non-zero exit status on error.
100
+ * `bundler-audit update` only updates `~/.local/share/ruby-advisory-db`, if it is a git
97
101
  repository.
98
102
 
99
103
  ### 0.4.0 / 2015-06-30
@@ -131,7 +135,7 @@
131
135
 
132
136
  #### CLI
133
137
 
134
- * Added the `bundle-audit update` sub-command.
138
+ * Added the `bundler-audit update` sub-command.
135
139
 
136
140
  ### 0.2.0 / 2013-03-05
137
141
 
data/README.md CHANGED
@@ -159,7 +159,7 @@ bundler-audit also supports a per-project configuration file:
159
159
  * [git]
160
160
  * [ruby] >= 1.9.3
161
161
  * [rubygems] >= 1.8
162
- * [thor] >= 0.18, < 2
162
+ * [thor] ~> 1.0
163
163
  * [bundler] >= 1.2.0, < 3
164
164
 
165
165
  ## Install
data/gemspec.yml CHANGED
@@ -10,5 +10,5 @@ required_ruby_version: ">= 1.9.3"
10
10
  required_rubygems_version: ">= 1.8.0"
11
11
 
12
12
  dependencies:
13
- thor: ">= 0.18, < 2"
13
+ thor: "~> 1.0"
14
14
  bundler: ">= 1.2.0, < 3"
@@ -20,6 +20,7 @@ require 'bundler/audit/version'
20
20
  require 'bundler/audit/cli/formats'
21
21
 
22
22
  require 'thor'
23
+ require 'bundler/audit/cli/thor_ext/shell/basic/say_error'
23
24
  require 'bundler'
24
25
 
25
26
  module Bundler
@@ -42,18 +43,18 @@ module Bundler
42
43
 
43
44
  def check(dir=Dir.pwd)
44
45
  unless File.directory?(dir)
45
- say "No such file or directory: #{dir}", :red
46
+ say_error "No such file or directory: #{dir}", :red
46
47
  exit 1
47
48
  end
48
49
 
49
50
  begin
50
51
  extend Formats.load(options[:format])
51
52
  rescue Formats::FormatNotFound
52
- say "Unknown format: #{options[:format]}", :red
53
+ say_error "Unknown format: #{options[:format]}", :red
53
54
  exit 1
54
55
  end
55
56
 
56
- if !Database.exists?
57
+ if !Database.exists?(options[:database])
57
58
  download(options[:database])
58
59
  elsif options[:update]
59
60
  update(options[:database])
@@ -128,13 +129,14 @@ module Bundler
128
129
  when true
129
130
  say("Updated ruby-advisory-db", :green) unless options.quiet?
130
131
  when false
131
- say "Failed updating ruby-advisory-db!", :red
132
+ say_error "Failed updating ruby-advisory-db!", :red
132
133
  exit 1
133
134
  when nil
134
135
  unless Bundler.git_present?
135
- say "Git is not installed!", :red
136
+ say_error "Git is not installed!", :red
136
137
  exit 1
137
138
  end
139
+
138
140
  say "Skipping update", :yellow
139
141
  end
140
142
 
@@ -143,9 +145,7 @@ module Bundler
143
145
 
144
146
  desc 'version', 'Prints the bundler-audit version'
145
147
  def version
146
- database = Database.new
147
-
148
- puts "#{File.basename($0)} #{VERSION} (advisories: #{database.size})"
148
+ puts "bundler-audit #{VERSION}"
149
149
  end
150
150
 
151
151
  protected
@@ -157,11 +157,6 @@ module Bundler
157
157
  raise(NotImplementedError,"#{self.class}##{__method__} not defined")
158
158
  end
159
159
 
160
- def say(message="", color=nil)
161
- color = nil unless $stdout.tty?
162
- super(message.to_s, color)
163
- end
164
-
165
160
  end
166
161
  end
167
162
  end
@@ -66,12 +66,14 @@ module Bundler
66
66
  say "Version: ", :red
67
67
  say gem.version
68
68
 
69
- say "Advisory: ", :red
70
-
71
69
  if advisory.cve
72
- say "CVE-#{advisory.cve}"
73
- elsif advisory.osvdb
74
- say advisory.osvdb
70
+ say "CVE: ", :red
71
+ say advisory.cve_id
72
+ end
73
+
74
+ if advisory.ghsa
75
+ say "GHSA: ", :red
76
+ say advisory.ghsa_id
75
77
  end
76
78
 
77
79
  say "Criticality: ", :red
@@ -0,0 +1,33 @@
1
+ class Thor
2
+ module Shell
3
+ class Basic
4
+ #
5
+ # Prints an error message to `stderr`.
6
+ #
7
+ # @param [String] message
8
+ # The message to print to `stderr`.
9
+ #
10
+ # @param [Symbol, nil] color
11
+ # Optional ANSI color.
12
+ #
13
+ # @param [Boolean] force_new_line
14
+ # Controls whether a newline character will be appended to the output.
15
+ #
16
+ def say_error(message,color=nil,force_new_line=(message.to_s !~ /( |\t)\Z/))
17
+ return if quiet?
18
+
19
+ buffer = prepare_message(message,*color)
20
+ buffer << $/ if force_new_line && !message.to_s.end_with?($/)
21
+
22
+ stderr.print(buffer)
23
+ stderr.flush
24
+ end
25
+ end
26
+
27
+ module_eval <<-METHOD, __FILE__, __LINE__ + 1
28
+ def say_error(*args,&block)
29
+ shell.say_error(*args,&block)
30
+ end
31
+ METHOD
32
+ end
33
+ end
@@ -52,6 +52,10 @@ module Bundler
52
52
 
53
53
  doc = YAML.parse(File.new(file_path))
54
54
 
55
+ unless doc.kind_of?(YAML::Nodes::Document)
56
+ raise(InvalidConfigurationError,"Configuration found in '#{file_path}' is not YAML")
57
+ end
58
+
55
59
  unless doc.root.kind_of?(YAML::Nodes::Mapping)
56
60
  raise(InvalidConfigurationError,"Configuration found in '#{file_path}' is not a Hash")
57
61
  end
@@ -18,6 +18,6 @@
18
18
  module Bundler
19
19
  module Audit
20
20
  # bundler-audit version
21
- VERSION = '0.8.0.rc1'
21
+ VERSION = '0.8.0.rc2'
22
22
  end
23
23
  end
@@ -76,8 +76,32 @@ describe Bundler::Audit::CLI::Formats::Text do
76
76
  expect(output_lines).to include("Version: #{gem.version}")
77
77
  end
78
78
 
79
- it "must print 'Advisory: CVE-YYYY-NNNN'" do
80
- expect(output_lines).to include("Advisory: CVE-#{advisory.cve}")
79
+ context "when the advisory has a CVE ID" do
80
+ it "must print 'CVE: CVE-YYYY-NNNN'" do
81
+ expect(output_lines).to include("CVE: CVE-#{advisory.cve}")
82
+ end
83
+ end
84
+
85
+ context "when the advisory does not have a CVE ID" do
86
+ before { advisory.cve = nil }
87
+
88
+ it "must not print 'CVE: CVE-YYYY-NNNN'" do
89
+ expect(output_lines).to_not include("CVE: CVE-#{advisory.cve}")
90
+ end
91
+ end
92
+
93
+ context "when the advisory has a GHSA ID" do
94
+ it "must print 'GHSA: GHSA-xxxx-xxxx-xxxx'" do
95
+ expect(output_lines).to include("GHSA: GHSA-#{advisory.ghsa}")
96
+ end
97
+ end
98
+
99
+ context "when the advisory does not have a GHSA ID" do
100
+ before { advisory.ghsa = nil }
101
+
102
+ it "must not print 'GHSA: GHSA-xxxx-xxxx-xxxx'" do
103
+ expect(output_lines).to_not include("GHSA: GHSA-#{advisory.ghsa}")
104
+ end
81
105
  end
82
106
 
83
107
  context "when Advisory#criticality is :low" do
data/spec/cli_spec.rb CHANGED
@@ -45,7 +45,7 @@ describe Bundler::Audit::CLI do
45
45
  subject.update
46
46
  rescue SystemExit
47
47
  end
48
- }.to output(/Failed updating ruby-advisory-db!/).to_stdout
48
+ }.to output(/Failed updating ruby-advisory-db!/).to_stderr
49
49
  end
50
50
 
51
51
  it "exits with error status code" do
@@ -73,7 +73,7 @@ describe Bundler::Audit::CLI do
73
73
  subject.update
74
74
  rescue SystemExit
75
75
  end
76
- end.to output(/Git is not installed!/).to_stdout
76
+ end.to output(/Git is not installed!/).to_stderr
77
77
  end
78
78
 
79
79
  it "exits with error status code" do
@@ -90,8 +90,8 @@ describe Bundler::Audit::CLI do
90
90
  end
91
91
 
92
92
  context "--quiet" do
93
- before do
94
- allow(subject).to receive(:options).and_return(double("Options", quiet?: true))
93
+ subject do
94
+ described_class.new([], {quiet: true})
95
95
  end
96
96
 
97
97
  context "when update succeeds" do
@@ -119,7 +119,7 @@ describe Bundler::Audit::CLI do
119
119
  subject.update
120
120
  rescue SystemExit
121
121
  end
122
- }.to output(/Failed updating ruby-advisory-db!/).to_stdout
122
+ }.to_not output.to_stderr
123
123
  end
124
124
 
125
125
  it "exits with error status code" do
@@ -22,6 +22,14 @@ describe Bundler::Audit::Configuration do
22
22
  end
23
23
 
24
24
  context "validations" do
25
+ context "when the file is empty" do
26
+ let(:path) { File.join(fixtures_dir,'bad','empty.yml') }
27
+
28
+ it 'raises a validation error' do
29
+ expect { subject }.to raise_error(described_class::InvalidConfigurationError)
30
+ end
31
+ end
32
+
25
33
  context "when ignore is not an array" do
26
34
  let(:path) { File.join(fixtures_dir,'bad','ignore_is_not_an_array.yml') }
27
35
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  gem: test
3
3
  cve: 2020-1234
4
+ ghsa: aaaa-bbbb-cccc
4
5
  url: https://example.com/
5
6
  title: Test advisory
6
7
  date: 2015-06-16
File without changes
@@ -1,117 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "CLI" do
4
- include Helpers
5
-
6
- let(:command) do
7
- File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-audit'))
8
- end
9
-
10
- context "when auditing a bundle with unpatched gems" do
11
- let(:bundle) { 'unpatched_gems' }
12
- let(:directory) { File.join('spec','bundle',bundle) }
13
-
14
- subject do
15
- Dir.chdir(directory) { sh(command, :fail => true) }
16
- end
17
-
18
- it "should print a warning" do
19
- expect(subject).to include("Vulnerabilities found!")
20
- end
21
-
22
- it "should print advisory information for the vulnerable gems" do
23
- advisory_pattern = %r{(Name: [^\n]+
24
- Version: \d+\.\d+\.\d+(\.\d+)?
25
- Advisory: CVE-[0-9]{4}-[0-9]{4}
26
- Criticality: (Critical|High|Medium|Low|None|Unknown)
27
- URL: https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#!?&//=]*)
28
- Title: [^\n]*?
29
- Solution: upgrade to (~>|>=) \d+\.\d+\.\d+(\.\d+)?(, (~>|>=) \d+\.\d+\.\d+(\.\d+)?)*[\s\n]*?)}
30
-
31
- expect(subject).to match(advisory_pattern)
32
- expect(subject).to include("Vulnerabilities found!")
33
- end
34
- end
35
-
36
- context "when auditing a bundle with ignored gems" do
37
- let(:bundle) { 'unpatched_gems' }
38
- let(:directory) { File.join('spec','bundle',bundle) }
39
-
40
- let(:command) do
41
- File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-audit -i CVE-2013-0156'))
42
- end
43
-
44
- subject do
45
- Dir.chdir(directory) { sh(command, :fail => true) }
46
- end
47
-
48
- it "should not print advisory information for ignored gem" do
49
- expect(subject).not_to include("CVE-2013-0156")
50
- end
51
- end
52
-
53
- context "when auditing a bundle with insecure sources" do
54
- let(:bundle) { 'insecure_sources' }
55
- let(:directory) { File.join('spec','bundle',bundle) }
56
-
57
- subject do
58
- Dir.chdir(directory) { sh(command, :fail => true) }
59
- end
60
-
61
- it "should print warnings about insecure sources" do
62
- expect(subject).to include(%{
63
- Insecure Source URI found: git://github.com/rails/jquery-rails.git
64
- Insecure Source URI found: http://rubygems.org/
65
- }.strip)
66
- end
3
+ describe "bin/bundler-audit" do
4
+ let(:name) { 'bundler-audit' }
5
+ let(:path) do
6
+ File.expand_path(File.join(File.dirname(__FILE__),'..','bin',name))
67
7
  end
68
8
 
69
- context "when auditing a secure bundle" do
70
- let(:bundle) { 'secure' }
71
- let(:directory) { File.join('spec','bundle',bundle) }
9
+ let(:command) { "#{path} version" }
72
10
 
73
- subject do
74
- Dir.chdir(directory) { sh(command) }
75
- end
11
+ subject { sh(command) }
76
12
 
77
- it "should print nothing when everything is fine" do
78
- expect(subject.strip).to eq("No vulnerabilities found")
79
- end
13
+ it "must invoke the CLI class" do
14
+ expect(subject).to eq("bundler-audit #{Bundler::Audit::VERSION}#{$/}")
80
15
  end
16
+ end
81
17
 
82
- context "when auditing a non-existent Gemfile.lock file" do
83
- let(:bundle) { 'secure' }
84
- let(:directory) { File.join('spec','bundle',bundle) }
85
- let(:root) { File.expand_path(directory) }
86
-
87
- let(:gemfile_lock) { 'Gemfile.foo.lock' }
88
- let(:command) { "#{super()} --gemfile-lock #{gemfile_lock}" }
89
-
90
- subject do
91
- Dir.chdir(directory) { sh(command, :fail => true) }
92
- end
93
-
94
- it "should print an error message" do
95
- expect(subject.strip).to eq("Could not find #{gemfile_lock.inspect} in #{root.inspect}")
96
- end
18
+ describe "bin/bundle-audit" do
19
+ let(:name) { 'bundle-audit' }
20
+ let(:path) do
21
+ File.expand_path(File.join(File.dirname(__FILE__),'..','bin',name))
97
22
  end
98
23
 
99
- describe "update" do
100
- let(:update_command) { "#{command} update" }
101
- let(:bundle) { 'secure' }
102
- let(:directory) { File.join('spec','bundle',bundle) }
24
+ let(:command) { "#{path} version" }
103
25
 
104
- subject do
105
- Dir.chdir(directory) { sh(update_command) }
106
- end
26
+ subject { sh(command) }
107
27
 
108
- context "when advisories update successfully" do
109
- it "should print status" do
110
- expect(subject).not_to include("Fail")
111
- expect(subject).to include("Updating ruby-advisory-db ...\n")
112
- expect(subject).to include("Updated ruby-advisory-db\n")
113
- expect(subject).to match(/ruby-advisory-db:\n advisories:\s+[1-9]\d+ advisories/)
114
- end
115
- end
28
+ it "must invoke the CLI class" do
29
+ expect(subject).to eq("bundler-audit #{Bundler::Audit::VERSION}#{$/}")
116
30
  end
117
31
  end
metadata CHANGED
@@ -1,35 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0.rc1
4
+ version: 0.8.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-23 00:00:00.000000000 Z
11
+ date: 2021-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0.18'
20
- - - "<"
17
+ - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: '2'
19
+ version: '1.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '0.18'
30
- - - "<"
24
+ - - "~>"
31
25
  - !ruby/object:Gem::Version
32
- version: '2'
26
+ version: '1.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: bundler
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -62,6 +56,7 @@ extra_rdoc_files:
62
56
  - README.md
63
57
  files:
64
58
  - ".document"
59
+ - ".github/FUNDING.yml"
65
60
  - ".github/workflows/ruby.yml"
66
61
  - ".gitignore"
67
62
  - ".rspec"
@@ -81,6 +76,7 @@ files:
81
76
  - lib/bundler/audit/cli/formats.rb
82
77
  - lib/bundler/audit/cli/formats/json.rb
83
78
  - lib/bundler/audit/cli/formats/text.rb
79
+ - lib/bundler/audit/cli/thor_ext/shell/basic/say_error.rb
84
80
  - lib/bundler/audit/configuration.rb
85
81
  - lib/bundler/audit/database.rb
86
82
  - lib/bundler/audit/report.rb
@@ -110,6 +106,7 @@ files:
110
106
  - spec/database_spec.rb
111
107
  - spec/fixtures/advisory/CVE-2020-1234.yml
112
108
  - spec/fixtures/advisory/not_a_hash.yml
109
+ - spec/fixtures/config/bad/empty.yml
113
110
  - spec/fixtures/config/bad/ignore_contains_a_non_string.yml
114
111
  - spec/fixtures/config/bad/ignore_is_not_an_array.yml
115
112
  - spec/fixtures/config/valid.yml