Permalink
Browse files

Merge pull request #1120 from presidentbeef/handle_lesser_lesses

Try to guess options available for `less`
2 parents 4ceaa20 + 5e5c1ad commit 119bfe6681ad963edaed1986bb64401d4dce561c @presidentbeef committed Nov 20, 2017
Showing with 185 additions and 33 deletions.
  1. +3 −33 lib/brakeman.rb
  2. +110 −0 lib/brakeman/report/pager.rb
  3. +72 −0 test/tests/pager.rb
View
@@ -402,42 +402,12 @@ def self.write_report_to_formats tracker, output_formats
puts tracker.report.format(output_format)
end
else
- page_output tracker.report.format(output_formats.first)
- end
- end
- private_class_method :write_report_to_formats
-
- def self.page_output text
- ci = ENV["CI"]
+ require "brakeman/report/pager"
- if ci.is_a? String and ci.downcase == "true"
- puts text
- elsif system("which less > /dev/null")
- # Adapted from https://github.com/piotrmurach/tty-pager/
- # -R show colors
- # -F exit if output fits on one screen
- # -X do not clear screen after less exits
- write_io = open("|less -RFX", 'w')
- pid = write_io.pid
-
- write_io.write(text)
- write_io.close
-
- Process.waitpid2(pid, Process::WNOHANG)
- else
- load_brakeman_dependency 'highline'
- h = ::HighLine.new
- h.page_at = :auto
- h.say text
+ Brakeman::Pager.new(tracker, :highline).page_report(tracker.report, output_formats.first)
end
- rescue Errno::ECHILD
- # on jruby 9x waiting on pid raises (per tty-pager)
- true
- rescue => e
- warn "[Error] #{e}"
- warn "[Error] Could not use pager. Set --no-pager to avoid this issue."
- puts text
end
+ private_class_method :write_report_to_formats
#Rescan a subset of files in a Rails application.
#
@@ -0,0 +1,110 @@
+module Brakeman
+ class Pager
+ def initialize tracker, pager = :less, output = $stdout
+ @tracker = tracker
+ @pager = pager
+ @output = output
+ end
+
+ def page_report report, format
+ if @pager == :less
+ set_color
+ end
+
+ text = report.format(format)
+
+ if in_ci?
+ no_pager text
+ else
+ page_output text
+ end
+ end
+
+ def page_output text
+ case @pager
+ when :none
+ no_pager text
+ when :highline
+ page_via_highline text
+ when :less
+ if less_available?
+ page_via_less text
+ else
+ page_via_highline text
+ end
+ else
+ no_pager text
+ end
+ end
+
+ def no_pager text
+ @output.puts text
+ end
+
+ def page_via_highline text
+ Brakeman.load_brakeman_dependency 'highline'
+ h = ::HighLine.new($stdin, @output)
+ h.page_at = :auto
+ h.say text
+ end
+
+ def page_via_less text
+ # Adapted from https://github.com/piotrmurach/tty-pager/
+
+ write_io = open("|less #{less_options.join}", 'w')
+ pid = write_io.pid
+
+ write_io.write(text)
+ write_io.close
+
+ Process.waitpid2(pid, Process::WNOHANG)
+ rescue Errno::ECHILD
+ # on jruby 9x waiting on pid raises (per tty-pager)
+ true
+ rescue => e
+ warn "[Error] #{e}"
+ warn "[Error] Could not use pager. Set --no-pager to avoid this issue."
+ no_pager text
+ end
+
+ def in_ci?
+ ci = ENV["CI"]
+
+ ci.is_a? String and ci.downcase == "true"
+ end
+
+ def less_available?
+ return @less_available unless @less_available.nil?
+
+ @less_available = system("which less > /dev/null")
+ end
+
+ def less_options
+ # -R show colors
+ # -F exit if output fits on one screen
+ # -X do not clear screen after less exits
+
+ return @less_options if @less_options
+
+ @less_options = []
+
+ if system("which less > /dev/null")
+ less_help = `less -?`
+
+ ["-R ", "-F ", "-X "].each do |opt|
+ if less_help.include? opt
+ @less_options << opt
+ end
+ end
+ end
+
+ @less_options
+ end
+
+ def set_color
+ unless @tracker and less_options.include? "-R "
+ @tracker.options[:output_color] = false
+ end
+ end
+ end
+end
View
@@ -0,0 +1,72 @@
+require_relative '../test'
+require "brakeman/report/pager"
+
+class ReportPagerTests < Minitest::Test
+ def setup
+ @@text ||= "Here is some text for your tests\n" * 100
+ end
+
+ def test_no_pager
+ out = StringIO.new
+ pager = Brakeman::Pager.new(nil, :none, out)
+
+ pager.page_output(@@text)
+
+ assert_equal @@text, out.string
+ end
+
+ def test_unknown_pager
+ out = StringIO.new
+ pager = Brakeman::Pager.new(nil, :unknown, out)
+
+ pager.page_output(@@text)
+
+ assert_equal @@text, out.string
+ end
+
+ def test_less_sort_of
+ out = StringIO.new
+ pager = Brakeman::Pager.new(nil, :less, out)
+
+ pager.page_output(".")
+ end
+
+ def test_highline
+ out = StringIO.new
+ $stdin = StringIO.new("\r\r\r\r\r\r\r")
+ pager = Brakeman::Pager.new(nil, :highline, out)
+
+ pager.page_output(@@text)
+
+ assert out.string.include? "Here is some text"
+ assert out.string.include? "press enter/return to continue or q to stop"
+ ensure
+ $stdin = STDIN
+ end
+
+ def test_in_ci_test
+ pager = Brakeman::Pager.new(Brakeman::Tracker.new(nil))
+
+ if ENV["CI"]
+ assert pager.in_ci?
+ else
+ refute pager.in_ci?
+ end
+ end
+
+ def test_set_color
+ pager = Brakeman::Pager.new(Brakeman::Tracker.new(nil))
+ pager.set_color
+ end
+
+ def test_output_report
+ out = $stdout = StringIO.new
+ app_path = File.expand_path "#{TEST_PATH}/apps/rails5"
+ tracker = Brakeman.run app_path: app_path, run_checks: [], quiet: true, summary_only: :no_summary
+ pager = Brakeman::Pager.new(tracker)
+
+ pager.page_report(tracker.report, :to_text)
+ ensure
+ $stdout = STDOUT
+ end
+end

0 comments on commit 119bfe6

Please sign in to comment.