# # Copyright (c) 2013-2019 Hal Brodigan (postmodern.mod3 at gmail.com) # # bundler-audit is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # bundler-audit is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with bundler-audit. If not, see . # require 'bundler/audit/scanner' require 'bundler/audit/version' require 'bundler/audit/presenter/plain' require 'bundler/audit/presenter/junit' require 'thor' require 'bundler' require 'bundler/vendored_thor' module Bundler module Audit class CLI < ::Thor DEFAULT_PRESENTER = 'plain' Error = Class.new(RuntimeError) PresenterUnkown = Class.new(Error) PresenterInvalid = Class.new(Error) default_task :check map '--version' => :version desc 'check', 'Checks the Gemfile.lock for insecure dependencies' method_option :quiet, :type => :boolean, :aliases => '-q' method_option :verbose, :type => :boolean, :aliases => '-v' method_option :ignore, :type => :array, :aliases => '-i' method_option :update, :type => :boolean, :aliases => '-u' method_option :format, :type => :string, :aliases => '-p', :default => DEFAULT_PRESENTER def check update if options[:update] scanner = Scanner.new presenter = presenter_klass(options[:format]).new(self.shell, options) scanner.scan(:ignore => options.ignore) do |result| case result when Scanner::InsecureSource presenter.push_warning "Insecure Source URI found: #{result.source}" when Scanner::UnpatchedGem presenter.push_advisory result end end presenter.print_report exit presenter.exit_code rescue Error => e say e.message, :red exit 1 end desc 'update', 'Updates the ruby-advisory-db' method_option :quiet, :type => :boolean, :aliases => '-q' def update say("Updating ruby-advisory-db ...") unless options.quiet? case Database.update!(quiet: options.quiet?) when true say("Updated ruby-advisory-db", :green) unless options.quiet? when false say "Failed updating ruby-advisory-db!", :red exit 1 when nil say "Skipping update", :yellow end unless options.quiet? puts("ruby-advisory-db: #{Database.new.size} advisories") end end desc 'version', 'Prints the bundler-audit version' def version database = Database.new puts "#{File.basename($0)} #{VERSION} (advisories: #{database.size})" end protected def say(message="", color=nil) color = nil unless $stdout.tty? super(message.to_s, color) end def presenter_klass(presenter_string) presenter_name = presenter_string.capitalize.to_sym raise PresenterUnkown, "Unknown Presenter '#{presenter_name}'" unless Presenter.const_defined? presenter_name Presenter.const_get presenter_name rescue NameError raise PresenterInvalid, "Invalid Presenter Name '#{presenter_name}'" end end end end