cleo_quality_review 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cleo_quality_review/changes_diff.rb +8 -9
- data/lib/cleo_quality_review/git_diff_base.rb +27 -0
- data/lib/cleo_quality_review/options.rb +11 -3
- data/lib/cleo_quality_review/prompt_builder.rb +2 -2
- data/lib/cleo_quality_review/run.rb +11 -0
- data/lib/cleo_quality_review/run_artifacts.rb +2 -0
- data/lib/cleo_quality_review/runner.rb +28 -10
- data/lib/cleo_quality_review/target_resolver.rb +7 -9
- data/lib/cleo_quality_review/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ef174aa218590b9a2f32114c94e9ef21c73d6809e87524750d66adc70562f0b
|
|
4
|
+
data.tar.gz: d25eae8497f8b87506231b4586614729b58b93634c3ed37a935d5029abcd3056
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a3c8d5bf0d7748a797b7c82c74ff5f1e914147b16b45b13e342e49268eb5e355dcb9885953725c16f118254ff48c728782289fcf291c49478ca0aca002f071bd
|
|
7
|
+
data.tar.gz: 436193715042ed3165c0ecf04026a70e0681a96bbd5bb6adc9c842662ae405e8b5409b408c5597c21884590374b1029ef94c3230bded8667117c978511d40ce9
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "digest"
|
|
4
4
|
|
|
5
|
-
require_relative "
|
|
5
|
+
require_relative "git_diff_base"
|
|
6
6
|
|
|
7
7
|
module CleoQualityReview
|
|
8
8
|
##
|
|
@@ -11,9 +11,13 @@ module CleoQualityReview
|
|
|
11
11
|
##
|
|
12
12
|
# @param [Array<String>] target_files files included in the review
|
|
13
13
|
# @param [CommandRunner] command_runner for executing git commands
|
|
14
|
-
|
|
14
|
+
# @param [String] base_ref git ref to compare against
|
|
15
|
+
# @param [Boolean] strict_base whether unresolved refs should raise
|
|
16
|
+
def initialize(target_files:, command_runner:, base_ref: GitDiffBase::DEFAULT_BASE_REF, strict_base: false)
|
|
15
17
|
@target_files = target_files
|
|
16
18
|
@command_runner = command_runner
|
|
19
|
+
@base_ref = base_ref || GitDiffBase::DEFAULT_BASE_REF
|
|
20
|
+
@strict_base = strict_base
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
##
|
|
@@ -30,7 +34,7 @@ module CleoQualityReview
|
|
|
30
34
|
|
|
31
35
|
private
|
|
32
36
|
|
|
33
|
-
attr_reader :command_runner, :target_files
|
|
37
|
+
attr_reader :command_runner, :target_files, :base_ref, :strict_base
|
|
34
38
|
|
|
35
39
|
def tracked_changes_diff
|
|
36
40
|
command = ["git", "diff", diff_base]
|
|
@@ -56,12 +60,7 @@ module CleoQualityReview
|
|
|
56
60
|
end
|
|
57
61
|
|
|
58
62
|
def diff_base
|
|
59
|
-
@diff_base ||=
|
|
60
|
-
result = command_runner.run("git", "merge-base", TargetResolver::BASE_REF, "HEAD")
|
|
61
|
-
base = result.stdout.strip
|
|
62
|
-
|
|
63
|
-
result.success? && !base.empty? ? base : TargetResolver::BASE_REF
|
|
64
|
-
end
|
|
63
|
+
@diff_base ||= GitDiffBase.resolve(command_runner: command_runner, base_ref: base_ref, strict: strict_base)
|
|
65
64
|
end
|
|
66
65
|
end
|
|
67
66
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CleoQualityReview
|
|
4
|
+
##
|
|
5
|
+
# Resolves git comparison bases for changed-file and diff capture flows
|
|
6
|
+
module GitDiffBase
|
|
7
|
+
DEFAULT_BASE_REF = "origin/main"
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# @param [CommandRunner] command_runner for executing git commands
|
|
13
|
+
# @param [String] base_ref git ref to compare against
|
|
14
|
+
# @param [Boolean] strict whether unresolved refs should raise
|
|
15
|
+
# @return [String] merge-base SHA, or the base ref when non-strict resolution fails
|
|
16
|
+
def resolve(command_runner:, base_ref:, strict:)
|
|
17
|
+
result = command_runner.run("git", "merge-base", base_ref, "HEAD")
|
|
18
|
+
base = result.stdout.strip
|
|
19
|
+
|
|
20
|
+
return base if result.success? && !base.empty?
|
|
21
|
+
|
|
22
|
+
raise ArgumentError, "Could not resolve quality review base ref: #{base_ref}" if strict
|
|
23
|
+
|
|
24
|
+
base_ref
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require "optparse"
|
|
4
4
|
|
|
5
|
+
require_relative "git_diff_base"
|
|
6
|
+
|
|
5
7
|
module CleoQualityReview
|
|
6
8
|
##
|
|
7
9
|
# Parses command-line options for the quality review CLI
|
|
@@ -23,7 +25,7 @@ module CleoQualityReview
|
|
|
23
25
|
# @return [Array<String>] checks to exclude
|
|
24
26
|
# @!attribute [r] changed
|
|
25
27
|
# @return [Boolean] whether to filter to changed files only
|
|
26
|
-
ParseResult = Struct.new(:format, :checks, :files, :exclude, :changed, :log, :review_id, :review_file, keyword_init: true) do
|
|
28
|
+
ParseResult = Struct.new(:format, :checks, :files, :exclude, :changed, :base, :log, :review_id, :review_file, keyword_init: true) do
|
|
27
29
|
##
|
|
28
30
|
# @return [String] validated review_id
|
|
29
31
|
# @raise [OptionParser::MissingArgument] if review_id is blank
|
|
@@ -58,6 +60,7 @@ module CleoQualityReview
|
|
|
58
60
|
@files = []
|
|
59
61
|
@exclude = []
|
|
60
62
|
@changed = false
|
|
63
|
+
@base = GitDiffBase::DEFAULT_BASE_REF
|
|
61
64
|
@log = false
|
|
62
65
|
@review_id = nil
|
|
63
66
|
@review_file = nil
|
|
@@ -78,6 +81,7 @@ module CleoQualityReview
|
|
|
78
81
|
files: files,
|
|
79
82
|
exclude: exclude,
|
|
80
83
|
changed: changed,
|
|
84
|
+
base: base,
|
|
81
85
|
log: log,
|
|
82
86
|
review_id: review_id,
|
|
83
87
|
review_file: review_file,
|
|
@@ -86,7 +90,7 @@ module CleoQualityReview
|
|
|
86
90
|
|
|
87
91
|
private
|
|
88
92
|
|
|
89
|
-
attr_reader :argv, :format, :checks, :files, :exclude, :changed, :log, :review_id, :review_file
|
|
93
|
+
attr_reader :argv, :format, :checks, :files, :exclude, :changed, :base, :log, :review_id, :review_file
|
|
90
94
|
|
|
91
95
|
def parser
|
|
92
96
|
OptionParser.new do |opts|
|
|
@@ -132,9 +136,13 @@ module CleoQualityReview
|
|
|
132
136
|
files.concat(values)
|
|
133
137
|
end
|
|
134
138
|
|
|
135
|
-
opts.on("--changed", "Only check files changed from
|
|
139
|
+
opts.on("--changed", "Only check files changed from the base ref") do
|
|
136
140
|
@changed = true
|
|
137
141
|
end
|
|
142
|
+
|
|
143
|
+
opts.on("--base REF", "Git ref to compare changed files against") do |value|
|
|
144
|
+
@base = value
|
|
145
|
+
end
|
|
138
146
|
end
|
|
139
147
|
|
|
140
148
|
def register_output_options(opts)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "
|
|
3
|
+
require_relative "git_diff_base"
|
|
4
4
|
|
|
5
5
|
module CleoQualityReview
|
|
6
6
|
##
|
|
@@ -46,7 +46,7 @@ module CleoQualityReview
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def diff_section
|
|
49
|
-
fenced("Git diff against #{
|
|
49
|
+
fenced("Git diff against #{run.base_ref || GitDiffBase::DEFAULT_BASE_REF}", "diff", artifacts.changes_diff)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def check_outputs_section
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "git_diff_base"
|
|
4
|
+
|
|
3
5
|
module CleoQualityReview
|
|
4
6
|
##
|
|
5
7
|
# Value object representing a quality review run with its configuration and results
|
|
@@ -25,6 +27,7 @@ module CleoQualityReview
|
|
|
25
27
|
Run = Struct.new(
|
|
26
28
|
:timestamp,
|
|
27
29
|
:review_id,
|
|
30
|
+
:base_ref,
|
|
28
31
|
:format,
|
|
29
32
|
:checks,
|
|
30
33
|
:target_files,
|
|
@@ -42,6 +45,7 @@ module CleoQualityReview
|
|
|
42
45
|
{
|
|
43
46
|
timestamp: timestamp,
|
|
44
47
|
review_id: review_id,
|
|
48
|
+
base_ref: comparison_base_ref,
|
|
45
49
|
format: format,
|
|
46
50
|
checks: checks,
|
|
47
51
|
target_files: target_files,
|
|
@@ -68,11 +72,18 @@ module CleoQualityReview
|
|
|
68
72
|
def manifest_data
|
|
69
73
|
{
|
|
70
74
|
review_id: review_id,
|
|
75
|
+
base_ref: comparison_base_ref,
|
|
71
76
|
timestamp: timestamp,
|
|
72
77
|
checks: checks,
|
|
73
78
|
target_files: target_files,
|
|
74
79
|
ruby_files: ruby_files,
|
|
75
80
|
}
|
|
76
81
|
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def comparison_base_ref
|
|
86
|
+
base_ref || GitDiffBase::DEFAULT_BASE_REF
|
|
87
|
+
end
|
|
77
88
|
end
|
|
78
89
|
end
|
|
@@ -5,6 +5,7 @@ require "fileutils"
|
|
|
5
5
|
|
|
6
6
|
require_relative "result"
|
|
7
7
|
require_relative "run"
|
|
8
|
+
require_relative "git_diff_base"
|
|
8
9
|
require_relative "run_artifacts/raw_check_outputs"
|
|
9
10
|
|
|
10
11
|
module CleoQualityReview
|
|
@@ -79,6 +80,7 @@ module CleoQualityReview
|
|
|
79
80
|
Run.new(
|
|
80
81
|
timestamp: manifest.fetch("timestamp"),
|
|
81
82
|
review_id: manifest.fetch("review_id"),
|
|
83
|
+
base_ref: manifest.fetch("base_ref", GitDiffBase::DEFAULT_BASE_REF),
|
|
82
84
|
format: format,
|
|
83
85
|
checks: manifest.fetch("checks", []),
|
|
84
86
|
target_files: target_files,
|
|
@@ -6,6 +6,7 @@ require "json"
|
|
|
6
6
|
require_relative "changes_diff"
|
|
7
7
|
require_relative "checks"
|
|
8
8
|
require_relative "command_runner"
|
|
9
|
+
require_relative "git_diff_base"
|
|
9
10
|
require_relative "run"
|
|
10
11
|
require_relative "run_artifacts"
|
|
11
12
|
require_relative "target_resolver"
|
|
@@ -16,12 +17,13 @@ module CleoQualityReview
|
|
|
16
17
|
class Runner
|
|
17
18
|
##
|
|
18
19
|
# Grouped values resolved at the start of an analysis run
|
|
19
|
-
AnalysisContext = Struct.new(:timestamp, :target, :changes, :review_id, :check_classes, keyword_init: true) do
|
|
20
|
+
AnalysisContext = Struct.new(:timestamp, :base_ref, :target, :changes, :review_id, :check_classes, keyword_init: true) do
|
|
20
21
|
##
|
|
21
22
|
# @return [Hash] run construction attributes derived from this context
|
|
22
23
|
def run_attributes
|
|
23
24
|
{
|
|
24
25
|
timestamp: timestamp,
|
|
26
|
+
base_ref: base_ref,
|
|
25
27
|
review_id: review_id,
|
|
26
28
|
checks: check_classes.map(&:check_name),
|
|
27
29
|
target_files: target.files,
|
|
@@ -69,21 +71,26 @@ module CleoQualityReview
|
|
|
69
71
|
|
|
70
72
|
AnalysisContext.new(
|
|
71
73
|
timestamp: timestamp,
|
|
74
|
+
base_ref: base_ref,
|
|
72
75
|
target: target,
|
|
73
76
|
changes: changes,
|
|
74
|
-
review_id: review_id_for(changes, check_classes),
|
|
77
|
+
review_id: review_id_for(changes, check_classes, base_ref: base_ref),
|
|
75
78
|
check_classes: check_classes,
|
|
76
79
|
)
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
def resolve_target
|
|
80
83
|
files = options.files
|
|
81
|
-
|
|
82
|
-
TargetResolver.new(command_runner: command_runner).resolve(files, changed: changed)
|
|
84
|
+
TargetResolver.new(command_runner: command_runner, base_ref: base_ref).resolve(files, changed: changed_mode?)
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
def changes_diff(target)
|
|
86
|
-
ChangesDiff.new(
|
|
88
|
+
ChangesDiff.new(
|
|
89
|
+
target_files: target.files,
|
|
90
|
+
command_runner: command_runner,
|
|
91
|
+
base_ref: base_ref,
|
|
92
|
+
strict_base: changed_mode?,
|
|
93
|
+
)
|
|
87
94
|
end
|
|
88
95
|
|
|
89
96
|
def prepare_artifacts(context)
|
|
@@ -146,13 +153,24 @@ module CleoQualityReview
|
|
|
146
153
|
artifacts.write_run(run)
|
|
147
154
|
end
|
|
148
155
|
|
|
149
|
-
def review_id_for(changes, check_classes)
|
|
156
|
+
def review_id_for(changes, check_classes, base_ref:)
|
|
157
|
+
payload = {
|
|
158
|
+
diff: changes.to_s,
|
|
159
|
+
checks: check_classes.map(&:check_name).sort,
|
|
160
|
+
}
|
|
161
|
+
payload[:base_ref] = base_ref unless base_ref == GitDiffBase::DEFAULT_BASE_REF
|
|
162
|
+
|
|
150
163
|
Digest::SHA256.hexdigest(
|
|
151
|
-
JSON.generate(
|
|
152
|
-
diff: changes.to_s,
|
|
153
|
-
checks: check_classes.map(&:check_name).sort,
|
|
154
|
-
),
|
|
164
|
+
JSON.generate(payload),
|
|
155
165
|
)
|
|
156
166
|
end
|
|
167
|
+
|
|
168
|
+
def changed_mode?
|
|
169
|
+
options.changed || options.files.empty?
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def base_ref
|
|
173
|
+
options.base || GitDiffBase::DEFAULT_BASE_REF
|
|
174
|
+
end
|
|
157
175
|
end
|
|
158
176
|
end
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "configuration"
|
|
4
|
+
require_relative "git_diff_base"
|
|
4
5
|
|
|
5
6
|
module CleoQualityReview
|
|
6
7
|
##
|
|
7
8
|
# Resolves target files for quality review based on git changes and configuration
|
|
8
9
|
class TargetResolver
|
|
9
|
-
BASE_REF =
|
|
10
|
+
BASE_REF = GitDiffBase::DEFAULT_BASE_REF
|
|
10
11
|
|
|
11
12
|
##
|
|
12
13
|
# Value object containing resolved file lists
|
|
@@ -20,9 +21,11 @@ module CleoQualityReview
|
|
|
20
21
|
##
|
|
21
22
|
# @param [CommandRunner] command_runner for executing git commands
|
|
22
23
|
# @param [Configuration] configuration file filtering configuration
|
|
23
|
-
|
|
24
|
+
# @param [String] base_ref git ref to compare changed files against
|
|
25
|
+
def initialize(command_runner:, configuration: Configuration.load, base_ref: GitDiffBase::DEFAULT_BASE_REF)
|
|
24
26
|
@command_runner = command_runner
|
|
25
27
|
@configuration = configuration
|
|
28
|
+
@base_ref = base_ref || GitDiffBase::DEFAULT_BASE_REF
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
##
|
|
@@ -41,7 +44,7 @@ module CleoQualityReview
|
|
|
41
44
|
|
|
42
45
|
private
|
|
43
46
|
|
|
44
|
-
attr_reader :command_runner, :configuration
|
|
47
|
+
attr_reader :command_runner, :configuration, :base_ref
|
|
45
48
|
|
|
46
49
|
def resolve_target_files(files, changed:)
|
|
47
50
|
candidates = resolve_candidates(files, changed: changed)
|
|
@@ -91,12 +94,7 @@ module CleoQualityReview
|
|
|
91
94
|
end
|
|
92
95
|
|
|
93
96
|
def diff_base
|
|
94
|
-
@diff_base ||=
|
|
95
|
-
result = command_runner.run("git", "merge-base", BASE_REF, "HEAD")
|
|
96
|
-
base = result.stdout.strip
|
|
97
|
-
|
|
98
|
-
result.success? && !base.empty? ? base : BASE_REF
|
|
99
|
-
end
|
|
97
|
+
@diff_base ||= GitDiffBase.resolve(command_runner: command_runner, base_ref: base_ref, strict: true)
|
|
100
98
|
end
|
|
101
99
|
|
|
102
100
|
def expand_target_paths(paths)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cleo_quality_review
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gavin Morrice
|
|
@@ -92,6 +92,7 @@ files:
|
|
|
92
92
|
- lib/cleo_quality_review/configuration.rb
|
|
93
93
|
- lib/cleo_quality_review/diff_map.rb
|
|
94
94
|
- lib/cleo_quality_review/formatter.rb
|
|
95
|
+
- lib/cleo_quality_review/git_diff_base.rb
|
|
95
96
|
- lib/cleo_quality_review/github_review_builder.rb
|
|
96
97
|
- lib/cleo_quality_review/github_review_publisher.rb
|
|
97
98
|
- lib/cleo_quality_review/llm_client.rb
|