Class: Reviewer::Runner
- Inherits:
-
Object
- Object
- Reviewer::Runner
- Extended by:
- Forwardable
- Defined in:
- lib/reviewer/runner.rb,
lib/reviewer/runner/result.rb,
lib/reviewer/runner/guidance.rb,
lib/reviewer/runner/formatter.rb,
lib/reviewer/runner/failed_files.rb,
lib/reviewer/runner/strategies/captured.rb,
lib/reviewer/runner/strategies/passthrough.rb
Overview
Wrapper for executng a command and printing the results
Defined Under Namespace
Modules: Strategies Classes: FailedFiles, Formatter, Guidance, Result
Instance Attribute Summary collapse
-
#command ⇒ Object
readonly
Returns the value of attribute command.
-
#shell ⇒ Object
readonly
Returns the value of attribute shell.
-
#strategy ⇒ Class
The strategy class for running the command (Captured or Passthrough).
Instance Method Summary collapse
-
#execute_strategy ⇒ void
Runs the relevant strategy to either capture or pass through command output.
-
#failed_files ⇒ Array<String>
Extracts file paths from stdout/stderr for failed-file tracking.
- #failure? ⇒ Boolean
-
#formatter ⇒ Runner::Formatter
Display formatter for runner-specific output (tool summary, success, failure, etc.) Computed rather than stored to avoid exceeding instance variable threshold.
-
#guidance ⇒ Guidance
Uses the result of the runner to determine what, if any, guidance to display to help the user get back on track in the event of an unsuccessful run.
-
#identify_tool ⇒ void
Prints the tool name and description to the console as a frame of reference.
-
#initialize(tool, command_type, strategy = Strategies::Captured, context:) ⇒ self
constructor
Creates a wrapper for running commands through Reviewer in order to provide a more accessible API for recording execution time and interpreting the results of a command in a more generous way so that non-zero exit statuses can still potentially be passing.
-
#missing? ⇒ Boolean
Whether this runner's executable was not found (exit status 127).
-
#output ⇒ Output
The output channel for displaying content, delegated from context.
-
#prepare_command ⇒ Comman
Creates_an instance of the prepare command for a tool.
-
#record_timing ⇒ void
Saves the last 5 elapsed times for the commands used this run by using the raw command as a unique key.
-
#run ⇒ Integer
Executes the command and returns the exit status.
-
#run_prepare_step? ⇒ Boolean
Determines whether a preparation step should be run before the primary command.
-
#show_skipped ⇒ void
Shows that a tool was skipped due to no matching files.
-
#skipped? ⇒ Boolean
Whether this runner was skipped due to no matching files.
-
#streaming? ⇒ Boolean
Whether this runner is operating in streaming mode.
-
#success? ⇒ Boolean
Some review tools return a range of non-zero exit statuses and almost never return 0.
-
#to_result ⇒ Runner::Result
Builds an immutable Result object from the current runner state.
-
#update_last_prepared_at ⇒ Time
Updates the 'last prepared at' timestamp that Reviewer uses to know if a tool's preparation step is stale and needs to be run again.
Constructor Details
#initialize(tool, command_type, strategy = Strategies::Captured, context:) ⇒ self
Creates a wrapper for running commands through Reviewer in order to provide a more accessible API for recording execution time and interpreting the results of a command in a more generous way so that non-zero exit statuses can still potentially be passing.
34 35 36 37 38 39 40 41 |
# File 'lib/reviewer/runner.rb', line 34 def initialize(tool, command_type, strategy = Strategies::Captured, context:) @command = Command.new(tool, command_type, context: context) @strategy = strategy @shell = Shell.new(stream: context.output.printer.stream) @context = context @skipped = false @missing = false end |
Instance Attribute Details
#command ⇒ Object (readonly)
Returns the value of attribute command.
19 20 21 |
# File 'lib/reviewer/runner.rb', line 19 def command @command end |
#shell ⇒ Object (readonly)
Returns the value of attribute shell.
19 20 21 |
# File 'lib/reviewer/runner.rb', line 19 def shell @shell end |
#strategy ⇒ Class
Returns the strategy class for running the command (Captured or Passthrough).
17 18 19 |
# File 'lib/reviewer/runner.rb', line 17 def strategy @strategy end |
Instance Method Details
#execute_strategy ⇒ void
This method returns an undefined value.
Runs the relevant strategy to either capture or pass through command output.
139 140 141 142 143 144 145 |
# File 'lib/reviewer/runner.rb', line 139 def execute_strategy # Run the provided strategy strategy.new(self).tap do |run_strategy| run_strategy.prepare if run_prepare_step? run_strategy.run end end |
#failed_files ⇒ Array<String>
Extracts file paths from stdout/stderr for failed-file tracking
109 110 111 |
# File 'lib/reviewer/runner.rb', line 109 def failed_files FailedFiles.new(stdout, stderr).to_a end |
#failure? ⇒ Boolean
104 |
# File 'lib/reviewer/runner.rb', line 104 def failure? = !success? |
#formatter ⇒ Runner::Formatter
Display formatter for runner-specific output (tool summary, success, failure, etc.) Computed rather than stored to avoid exceeding instance variable threshold.
52 |
# File 'lib/reviewer/runner.rb', line 52 def formatter = @formatter ||= Runner::Formatter.new(output) |
#guidance ⇒ Guidance
Uses the result of the runner to determine what, if any, guidance to display to help the user get back on track in the event of an unsuccessful run.
181 |
# File 'lib/reviewer/runner.rb', line 181 def guidance = @guidance ||= Guidance.new(command: command, result: result, context: @context) |
#identify_tool ⇒ void
This method returns an undefined value.
Prints the tool name and description to the console as a frame of reference. Only displays in streaming mode; non-streaming strategies handle their own output.
117 118 119 120 121 122 123 |
# File 'lib/reviewer/runner.rb', line 117 def identify_tool # If there's an existing result, the runner is being re-run, and identifying the tool would # be redundant. return if result.exists? stream_output { formatter.tool_summary(tool) } end |
#missing? ⇒ Boolean
Whether this runner's executable was not found (exit status 127)
88 |
# File 'lib/reviewer/runner.rb', line 88 def missing? = @missing == true |
#output ⇒ Output
The output channel for displaying content, delegated from context.
46 |
# File 'lib/reviewer/runner.rb', line 46 def output = @context.output |
#prepare_command ⇒ Comman
Creates_an instance of the prepare command for a tool
157 |
# File 'lib/reviewer/runner.rb', line 157 def prepare_command = @prepare_command ||= Command.new(tool, :prepare, context: @context) |
#record_timing ⇒ void
This method returns an undefined value.
Saves the last 5 elapsed times for the commands used this run by using the raw command as a unique key. This enables the ability to compare times across runs while taking into consideration that different iterations of the command may be running on fewer files. So comparing a full run to the average time for a partial run wouldn't be helpful. By using the raw command string, it will always be apples to apples.
172 173 174 175 |
# File 'lib/reviewer/runner.rb', line 172 def record_timing tool.record_timing(prepare_command, timer.prep) tool.record_timing(command, timer.main) end |
#run ⇒ Integer
Executes the command and returns the exit status
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/reviewer/runner.rb', line 62 def run # Skip if files were requested but none match this tool's pattern if command.skip? @skipped = true show_skipped return 0 end # Show which tool is running identify_tool # Use the provided strategy to run the command execute_strategy # Handle the result based on whether the tool was found result.executable_not_found? ? handle_missing : handle_result end |
#run_prepare_step? ⇒ Boolean
Determines whether a preparation step should be run before the primary command. If/when the
primary command is a :prepare command, then it shouldn't run twice. So it skips what would
be a superfluous run of the preparation.
152 |
# File 'lib/reviewer/runner.rb', line 152 def run_prepare_step? = command.type != :prepare && tool.prepare? |
#show_skipped ⇒ void
This method returns an undefined value.
Shows that a tool was skipped due to no matching files. Only displays in streaming mode; non-streaming modes report skips in the final summary.
129 130 131 132 133 134 |
# File 'lib/reviewer/runner.rb', line 129 def show_skipped stream_output do formatter.tool_summary(tool) formatter.skipped end end |
#skipped? ⇒ Boolean
Whether this runner was skipped due to no matching files
83 |
# File 'lib/reviewer/runner.rb', line 83 def skipped? = @skipped == true |
#streaming? ⇒ Boolean
Whether this runner is operating in streaming mode
57 |
# File 'lib/reviewer/runner.rb', line 57 def streaming? = @context.arguments.streaming? |
#success? ⇒ Boolean
Some review tools return a range of non-zero exit statuses and almost never return 0.
(yarn audit is a good example.) Those tools can be configured to accept a non-zero exit
status so they aren't constantly considered to be failing over minor issues.
But when other command types (prepare, install, format) are run, they either succeed or they fail. With no shades of gray in those cases, anything other than a 0 is a failure.
Skipped tools are always considered successful.
98 99 100 101 102 |
# File 'lib/reviewer/runner.rb', line 98 def success? return true if skipped? command.type == :review ? exit_status <= tool.max_exit_status : exit_status.zero? end |
#to_result ⇒ Runner::Result
Builds an immutable Result object from the current runner state
186 187 188 |
# File 'lib/reviewer/runner.rb', line 186 def to_result Result.from_runner(self) end |
#update_last_prepared_at ⇒ Time
Updates the 'last prepared at' timestamp that Reviewer uses to know if a tool's preparation step is stale and needs to be run again.
163 |
# File 'lib/reviewer/runner.rb', line 163 def update_last_prepared_at = tool.last_prepared_at = Time.now |