Skip to content

Commit

Permalink
Raise a GitnotInstalled exception if git is not installed (closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
postmodern committed Sep 13, 2023
1 parent 5f2c1a6 commit 819c8e1
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 25 deletions.
13 changes: 4 additions & 9 deletions lib/bundler/audit/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def download(path=Database.path)

begin
Database.download(path: path, quiet: options.quiet?)
rescue Database::DownloadFailed => error
rescue Database::GitNotInstalled, Database::DownloadFailed => error
say error.message, :red
exit 1
end
Expand All @@ -142,16 +142,11 @@ def update(path=Database.path)
when true
say("Updated ruby-advisory-db", :green) unless options.quiet?
when nil
if Bundler.git_present?
unless options.quiet?
say "Skipping update, ruby-advisory-db is not a git repository", :yellow
end
else
say_error "Git is not installed!", :red
exit 1
unless options.quiet?
say "Skipping update, ruby-advisory-db is not a git repository", :yellow
end
end
rescue Database::UpdateFailed => error
rescue Database::GitNotInstalled, Database::UpdateFailed => error
say error.message, :red
exit 1
end
Expand Down
35 changes: 31 additions & 4 deletions lib/bundler/audit/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ module Audit
#
class Database

#
# @since 0.10.0
#
class GitNotInstalled < RuntimeError
end

class DownloadFailed < RuntimeError
end

Expand Down Expand Up @@ -103,8 +109,9 @@ def self.exists?(path=DEFAULT_PATH)
# @return [Dataase]
# The newly downloaded database.
#
# @raise [DownloadFailed]
# Indicates that the download failed.
# @raise [DownloadFailed, GitNotInstalled]
# * {DownloadFailed} - the `git clone` command failed.
# * {GitNotInstalled} - the `git` command is not installed.
#
# @note
# Requires network access.
Expand All @@ -116,8 +123,11 @@ def self.download(path: DEFAULT_PATH, quiet: false)
command << '--quiet' if quiet
command << URL << path

unless system(*command)
case system(*command)
when false
raise(DownloadFailed,"failed to download #{URL} to #{path.inspect}")
when nil
raise(GitNotInstalled,"the git command is not installed")
end

return new(path)
Expand Down Expand Up @@ -182,6 +192,10 @@ def git?
# @raise [UpdateFailed]
# Could not update the ruby-advisory-db git repository.
#
# @raise [UpdateFailed, GitNotInstalled]
# * {UpdateFailed} - the `git pull` command failed.
# * {GitNotInstalled} - the `git` command is not installed.
#
# @since 0.8.0
#
def update!(quiet: false)
Expand All @@ -191,8 +205,11 @@ def update!(quiet: false)
command << '--quiet' if quiet
command << 'origin' << 'master'

unless system(*command)
case system(*command)
when false
raise(UpdateFailed,"failed to update #{@path.inspect}")
when nil
raise(GitNotInstalled,"the git command is not installed")
end

return true
Expand All @@ -206,12 +223,17 @@ def update!(quiet: false)
# @return [String, nil]
# The commit hash or `nil` if the database is not a git repository.
#
# @raise [GitNotInstalled]
# The `git` command is not installed.
#
# @since 0.9.0
#
def commit_id
if git?
Dir.chdir(@path) do
`git rev-parse HEAD`.chomp
rescue Errno::ENOENT
raise(GitNotInstalled,"the git command is not installed")
end
end
end
Expand All @@ -221,12 +243,17 @@ def commit_id
#
# @return [Time]
#
# @raise [GitNotInstalled]
# The `git` command is not installed.
#
# @since 0.8.0
#
def last_updated_at
if git?
Dir.chdir(@path) do
Time.parse(`git log --date=iso8601 --pretty="%cd" -1`)
rescue Errno::ENOENT
raise(GitNotInstalled,"the git command is not installed")
end
else
File.mtime(@path)
Expand Down
30 changes: 18 additions & 12 deletions spec/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,33 @@
end
end

context "when git is not installed" do
context "when the ruby-advisory-db is not a git repository" do
before do
expect(database).to receive(:update!).and_return(nil)

expect(Bundler).to receive(:git_present?).and_return(false)
end

it "prints failure message" do
it "must print a warning message and then the stats" do
allow(subject).to receive(:stats)

expect {
begin
subject.update
rescue SystemExit
end
}.to output(/Git is not installed!/).to_stderr
subject.update
}.to output(/Skipping update, ruby-advisory-db is not a git repository/).to_stdout
end
end

context "when git is not installed" do
before do
expect(database).to receive(:update!).and_raise(
Bundler::Audit::Database::GitNotInstalled,
"the git command is not installed"
)
end

it "exits with error status code" do
expect {
# Capture output of `update` only to keep spec output clean.
# The test regarding specific output is above.
expect { subject.update }.to output.to_stdout
expect {
subject.update
}.to output("the git command is not installed").to_stderr
}.to raise_error(SystemExit) do |error|
expect(error.success?).to eq(false)
expect(error.status).to eq(1)
Expand Down
52 changes: 52 additions & 0 deletions spec/database_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@
end
end

context "when git is not installed" do
it do
expect(subject).to receive(:system).with('git', 'clone', url, path).and_return(nil)

expect {
subject.download
}.to raise_error(described_class::GitNotInstalled,"the git command is not installed")
end
end

context "with an unknown option" do
it do
expect {
Expand Down Expand Up @@ -131,6 +141,18 @@
end
end

context "when git is not installed" do
before { stub_const("#{described_class}::URL",'https://example.com/') }

it do
expect(subject).to receive(:system).with('git', 'clone', url, path).and_return(nil)

expect {
subject.update!(quiet: false)
}.to raise_error(described_class::GitNotInstalled,"the git command is not installed")
end
end

after { FileUtils.rm_rf(dest_dir) }
end

Expand All @@ -155,6 +177,16 @@
expect(subject.update!(quiet: false)).to eq(false)
end
end

context "when git is not installed" do
it do
expect_any_instance_of(subject).to receive(:system).with('git', 'pull', 'origin', 'master').and_return(nil)

expect {
subject.update!(quiet: false)
}.to raise_error(described_class::GitNotInstalled,"the git command is not installed")
end
end
end
end

Expand Down Expand Up @@ -264,6 +296,16 @@
it "should return the last commit ID" do
expect(subject.commit_id).to be == last_commit
end

context "when git is not installed" do
it do
expect(subject).to receive(:`).with('git rev-parse HEAD').and_raise(Errno::ENOENT)

expect {
subject.commit_id
}.to raise_error(described_class::GitNotInstalled,"the git command is not installed")
end
end
end

context "when the database is a bare directory" do
Expand Down Expand Up @@ -293,6 +335,16 @@
it "should return the timestamp of the last commit" do
expect(subject.last_updated_at).to be == last_commit_timestamp
end

context "when git is not installed" do
it do
expect(subject).to receive(:`).with('git log --date=iso8601 --pretty="%cd" -1').and_raise(Errno::ENOENT)

expect {
subject.last_updated_at
}.to raise_error(described_class::GitNotInstalled,"the git command is not installed")
end
end
end

context "when the database is a bare directory" do
Expand Down

0 comments on commit 819c8e1

Please sign in to comment.