reviewer 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.flayignore +1 -0
  3. data/.github/workflows/main.yml +11 -3
  4. data/.gitignore +5 -0
  5. data/.reviewer.example.yml +27 -23
  6. data/.reviewer.yml +58 -5
  7. data/.rubocop.yml +2 -0
  8. data/.ruby-version +1 -1
  9. data/CHANGELOG.md +14 -0
  10. data/Gemfile +0 -3
  11. data/Gemfile.lock +54 -29
  12. data/README.md +5 -50
  13. data/exe/fmt +1 -1
  14. data/exe/rvw +1 -1
  15. data/lib/reviewer.rb +39 -26
  16. data/lib/reviewer/arguments.rb +25 -9
  17. data/lib/reviewer/arguments/files.rb +37 -5
  18. data/lib/reviewer/arguments/keywords.rb +23 -9
  19. data/lib/reviewer/arguments/tags.rb +26 -3
  20. data/lib/reviewer/batch.rb +64 -0
  21. data/lib/reviewer/command.rb +100 -0
  22. data/lib/reviewer/command/string.rb +72 -0
  23. data/lib/reviewer/command/string/env.rb +40 -0
  24. data/lib/reviewer/command/string/flags.rb +40 -0
  25. data/lib/reviewer/command/string/verbosity.rb +51 -0
  26. data/lib/reviewer/command/verbosity.rb +65 -0
  27. data/lib/reviewer/configuration.rb +24 -4
  28. data/lib/reviewer/conversions.rb +27 -0
  29. data/lib/reviewer/guidance.rb +73 -0
  30. data/lib/reviewer/history.rb +38 -0
  31. data/lib/reviewer/keywords.rb +9 -0
  32. data/lib/reviewer/keywords/git.rb +14 -0
  33. data/lib/reviewer/keywords/git/staged.rb +48 -0
  34. data/lib/reviewer/loader.rb +2 -3
  35. data/lib/reviewer/output.rb +92 -0
  36. data/lib/reviewer/printer.rb +25 -0
  37. data/lib/reviewer/runner.rb +43 -72
  38. data/lib/reviewer/runner/strategies/quiet.rb +90 -0
  39. data/lib/reviewer/runner/strategies/verbose.rb +63 -0
  40. data/lib/reviewer/shell.rb +58 -0
  41. data/lib/reviewer/shell/result.rb +69 -0
  42. data/lib/reviewer/shell/timer.rb +57 -0
  43. data/lib/reviewer/tool.rb +109 -40
  44. data/lib/reviewer/tool/settings.rb +18 -32
  45. data/lib/reviewer/tools.rb +38 -3
  46. data/lib/reviewer/version.rb +1 -1
  47. data/reviewer.gemspec +10 -2
  48. metadata +143 -16
  49. data/lib/reviewer/arguments/keywords/git.rb +0 -16
  50. data/lib/reviewer/arguments/keywords/git/staged.rb +0 -64
  51. data/lib/reviewer/logger.rb +0 -62
  52. data/lib/reviewer/tool/command.rb +0 -80
  53. data/lib/reviewer/tool/env.rb +0 -38
  54. data/lib/reviewer/tool/flags.rb +0 -38
  55. data/lib/reviewer/tool/verbosity.rb +0 -39
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'git/staged'
4
-
5
- module Reviewer
6
- class Arguments
7
- class Keywords
8
- module Git
9
- BASE_COMMAND = [
10
- 'git',
11
- '--no-pager'
12
- ].freeze
13
- end
14
- end
15
- end
16
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Reviewer
4
- class Arguments
5
- class Keywords
6
- module Git
7
- # Provides a convenient interface to get the list of staged files
8
- class Staged
9
- OPTIONS = [
10
- 'diff',
11
- '--staged',
12
- '--name-only'
13
- ].freeze
14
-
15
- attr_reader :stdout, :stderr, :status, :exit_status
16
-
17
- def to_a
18
- stdout.present? ? stdout.split("\n") : []
19
- end
20
-
21
- def to_s
22
- stdout.present? ? stdout : ''
23
- end
24
-
25
- def inspect
26
- {
27
- command: command,
28
- stdout: stdout,
29
- stderr: stderr,
30
- status: status,
31
- results: results
32
- }
33
- end
34
-
35
- def list
36
- @stdout, @stderr, @status = Open3.capture3(command)
37
- @exit_status = @status.exitstatus.to_i
38
-
39
- @status.success? ? to_a : raise_command_line_error
40
- end
41
-
42
- def self.list
43
- new.list
44
- end
45
-
46
- def command
47
- command_parts.join(' ')
48
- end
49
-
50
- private
51
-
52
- def raise_command_line_error
53
- message = "Git Error: #{stderr} (#{command})"
54
- raise SystemCallError.new(message, exit_status)
55
- end
56
-
57
- def command_parts
58
- BASE_COMMAND + OPTIONS
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'colorize'
4
-
5
- module Reviewer
6
- # Clean formatter for logging to $stdout
7
- class StandardOutFormatter < ::Logger::Formatter
8
- # Overrides ::Logger::Formatter `call` to more present output more concisely
9
- # @param _severity [Logger::Severity] Unused - Logger severity for etnry
10
- # @param _time [DateTime] Unused - Timestamp for entry
11
- # @param _progname [String] Unused - Name of the current program for entry
12
- # @param message [String] The string to print to $stdout
13
- #
14
- # @return [type] [description]
15
- def call(_severity, _time, _progname, message)
16
- "#{message}\n"
17
- end
18
- end
19
-
20
- # Logger for $stdout
21
- class Logger < ::Logger
22
- SUCCESS = 'Success'
23
- FAILURE = 'Failure ·'
24
- PROMPT = '$'
25
-
26
- def initialize(formatter = StandardOutFormatter.new)
27
- super($stdout)
28
- @formatter = formatter
29
- end
30
-
31
- def running(tool)
32
- info "\n#{tool.name}".bold + ' · '.light_black + tool.description
33
- end
34
-
35
- def command(cmd)
36
- info "\nReviewer ran this command:"
37
- info cmd.to_s.light_black
38
- end
39
-
40
- def rerunning(tool, cmd)
41
- info "\nRe-running #{tool.name} verbosely:"
42
- info cmd.to_s.light_black
43
- end
44
-
45
- def success(elapsed_time)
46
- info SUCCESS.green.bold + " (#{elapsed_time.round(3)}s)".green
47
- end
48
-
49
- def failure(message)
50
- error "#{FAILURE} #{message}".red.bold
51
- end
52
-
53
- def total_time(elapsed_time)
54
- info "\n➤ Total Time: #{elapsed_time.round(3)}s\n"
55
- end
56
-
57
- def guidance(summary, details)
58
- info "\n#{summary}" if summary
59
- info details.to_s.light_black if details
60
- end
61
- end
62
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Reviewer
4
- class Tool
5
- # Assembles tool tool_settings into a usable command string
6
- class Command
7
- class InvalidTypeError < StandardError; end
8
-
9
- class NotConfiguredError < StandardError; end
10
-
11
- TYPES = %i[install prepare review format].freeze
12
-
13
- attr_reader :command_type, :tool_settings, :verbosity_level
14
-
15
- def initialize(command_type, tool_settings:, verbosity_level: nil)
16
- @command_type = command_type
17
- @tool_settings = tool_settings
18
- @verbosity_level = verbosity_level
19
-
20
- verify_command_type!
21
- end
22
-
23
- def to_s
24
- to_a
25
- .map(&:strip) # Remove extra spaces on the components
26
- .join(' ') # Merge the components
27
- .strip # Strip extra spaces from the end result
28
- end
29
-
30
- def to_a
31
- [
32
- env,
33
- body,
34
- flags,
35
- verbosity
36
- ].compact
37
- end
38
-
39
- def env
40
- Env.new(tool_settings.env).to_s
41
- end
42
-
43
- def body
44
- tool_settings.commands.fetch(command_type)
45
- end
46
-
47
- def flags
48
- # :review commands are the only commands that use flags
49
- # And if no flags are configured, this won't do much
50
- # Flags for 'quiet' are handled separately by design and excluded from this check.
51
- return nil unless review? && tool_settings.flags.any?
52
-
53
- Flags.new(tool_settings.flags).to_s
54
- end
55
-
56
- def verbosity
57
- Verbosity.new(tool_settings.quiet_option, level: verbosity_level).to_s
58
- end
59
-
60
- private
61
-
62
- def review?
63
- command_type == :review
64
- end
65
-
66
- def valid_command?
67
- TYPES.include?(command_type)
68
- end
69
-
70
- def command_defined?
71
- tool_settings.commands.key?(command_type)
72
- end
73
-
74
- def verify_command_type!
75
- raise InvalidTypeError, "'#{body}' is not a supported command type. (Make sure it's not a typo.)" unless valid_command?
76
- raise NotConfiguredError, "The '#{body}' command is not configured for #{tool_settings.name}. (Make sure it's not a typo.)" unless command_defined?
77
- end
78
- end
79
- end
80
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Reviewer
4
- class Tool
5
- # Assembles tool environment variables into a single string or array
6
- class Env
7
- attr_reader :env_pairs
8
-
9
- def initialize(env_pairs)
10
- @env_pairs = env_pairs
11
- end
12
-
13
- def to_s
14
- to_a.compact.join(' ')
15
- end
16
-
17
- def to_a
18
- env = []
19
- env_pairs.each { |key, value| env << env(key, value) }
20
- env
21
- end
22
-
23
- private
24
-
25
- def env(key, value)
26
- return nil if key.to_s.blank? || value.to_s.blank?
27
-
28
- value = needs_quotes?(value) ? "'#{value}'" : value
29
-
30
- "#{key.to_s.strip.upcase}=#{value.to_s.strip};"
31
- end
32
-
33
- def needs_quotes?(value)
34
- value.is_a?(String) && value.include?(' ')
35
- end
36
- end
37
- end
38
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Reviewer
4
- class Tool
5
- # Assembles tool flag settings into a single string or array
6
- class Flags
7
- attr_reader :flag_pairs
8
-
9
- def initialize(flag_pairs)
10
- @flag_pairs = flag_pairs
11
- end
12
-
13
- def to_s
14
- to_a.join(' ')
15
- end
16
-
17
- def to_a
18
- flags = []
19
- flag_pairs.each { |key, value| flags << flag(key, value) }
20
- flags
21
- end
22
-
23
- private
24
-
25
- def flag(key, value)
26
- dash = key.to_s.size == 1 ? '-' : '--'
27
-
28
- value = needs_quotes?(value) ? "'#{value}'" : value
29
-
30
- "#{dash}#{key} #{value}".strip
31
- end
32
-
33
- def needs_quotes?(value)
34
- value.is_a?(String) && value.include?(' ')
35
- end
36
- end
37
- end
38
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Reviewer
4
- class Tool
5
- # Assembles tool settings and provided context for silencing output
6
- class Verbosity
7
- class InvalidLevelError < StandardError; end
8
- # :total_silence = Use the quiet flag and send everything to dev/null.
9
- # For some tools "quiet" means "less noisy" rather than truly silent.
10
- # So in those cases, dev/null handles lingering noise.
11
- # :tool_silence = Just the quiet flag
12
- # :no_silence = Let the output scroll for eternity
13
- LEVELS = %i[total_silence tool_silence no_silence].freeze
14
- SEND_TO_DEV_NULL = '> /dev/null'
15
-
16
- attr_reader :flag, :level
17
-
18
- def initialize(flag, level: :tool_silence)
19
- @flag = flag
20
-
21
- raise InvalidLevelError, "Invalid Verbosity Level: '#{level}'" unless LEVELS.include?(level)
22
-
23
- @level = level
24
- end
25
-
26
- def to_s
27
- to_a.map(&:strip).join(' ').strip
28
- end
29
-
30
- def to_a
31
- case level
32
- when :total_silence then [flag, SEND_TO_DEV_NULL].compact
33
- when :tool_silence then [flag].compact
34
- when :no_silence then []
35
- end
36
- end
37
- end
38
- end
39
- end