Skip to content

Commit 20c96ef

Browse files
authored
fix: propagate errors (#47)
This follows idiomatic rust [error handling] by using the [anyhow library]. [error handling]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html [anyhow library]: https://crates.io/crates/anyhow * setup non-system python in CI's sdist build job * improve log output for silent errors * remove trailing '/' in endpoint url * add user-agent header; adjust auth haeader value * skip serializing `ReviewComment::start_line` if it is null * add tests; review error handling * fix review dismissal and thread comment updating * use test profiles * upload coverage reports from windows runners to codecov.io
1 parent 4f6d221 commit 20c96ef

31 files changed

+1389
-867
lines changed
File renamed without changes.
File renamed without changes.

.config/nextest.toml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# required minimum nextest version
2+
nextest-version = "0.9.77"
3+
4+
[profile.default]
5+
# A profile to run most tests, except tests that run longer than 10 seconds
6+
default-filter = "not test(#*rate_limit_secondary) - test(#git::test::with_*)"
7+
8+
# This will flag any test that runs longer than 10 seconds. Useful when writing new tests.
9+
slow-timeout = "10s"
10+
11+
[profile.ci]
12+
# A profile to run only tests that use clang-tidy and/or clang-format
13+
# NOTE: This profile is intended to keep CI runtime low. Locally, use default or all profiles
14+
15+
# This is all tests in tests/ folder + unit test for --extra-args.
16+
default-filter = "kind(test) + test(#*use_extra_args)"
17+
18+
# show wich tests were skipped
19+
status-level = "skip"
20+
21+
# show log output from each test
22+
success-output = "final"
23+
failure-output = "immediate-final"
24+
25+
[profile.all]
26+
# A profile to run all tests (including tests that run longer than 10 seconds)
27+
default-filter = "all()"
28+
29+
# Revert slow-timeout to nextest default value.
30+
# Otherwise, default profile value (10s) is inherited.
31+
slow-timeout = "60s"

.github/workflows/bump-n-release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: orhun/git-cliff-action@v4
5555
id: git-cliff
5656
with:
57-
config: cliff.toml
57+
config: .config/cliff.toml
5858
args: --unreleased
5959
env:
6060
OUTPUT: ${{ runner.temp }}/changes.md

.github/workflows/bump_version.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,16 @@ def main():
120120
subprocess.run(["napi", "version"], cwd="node-binding", check=True)
121121
print("Updated version in node-binding/**package.json")
122122

123-
subprocess.run(["git", "cliff", "--tag", Updater.new_version], check=True)
123+
subprocess.run(
124+
[
125+
"git-cliff",
126+
"--config",
127+
".config/cliff.toml",
128+
"--tag",
129+
Updater.new_version,
130+
],
131+
check=True,
132+
)
124133
print("Updated CHANGELOG.md")
125134

126135
subprocess.run(["git", "add", "--all"], check=True)

.github/workflows/python-packaging.yml

+3
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ jobs:
155155
runs-on: ubuntu-latest
156156
steps:
157157
- uses: actions/checkout@v4
158+
- uses: actions/setup-python@v5
159+
with:
160+
python-version: 3.x
158161
- name: Build sdist
159162
uses: PyO3/maturin-action@v1
160163
with:

.github/workflows/run-dev-tests.yml

+12-14
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
if: runner.os == 'Linux'
8989
env:
9090
CLANG_VERSION: '7'
91-
run: just test
91+
run: just test ci
9292

9393
- name: Install clang v8
9494
if: runner.os == 'Linux'
@@ -100,7 +100,7 @@ jobs:
100100
if: runner.os == 'Linux'
101101
env:
102102
CLANG_VERSION: '8'
103-
run: just test
103+
run: just test ci
104104

105105
- name: Install clang v9
106106
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -110,7 +110,7 @@ jobs:
110110
- name: Collect Coverage for clang v9
111111
env:
112112
CLANG_VERSION: '9'
113-
run: just test
113+
run: just test ci
114114

115115
- name: Install clang v10
116116
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -120,7 +120,7 @@ jobs:
120120
- name: Collect Coverage for clang v10
121121
env:
122122
CLANG_VERSION: '10'
123-
run: just test
123+
run: just test ci
124124

125125
- name: Install clang 11
126126
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -130,7 +130,7 @@ jobs:
130130
- name: Collect Coverage for clang v11
131131
env:
132132
CLANG_VERSION: '11'
133-
run: just test
133+
run: just test ci
134134

135135
- name: Install clang 12
136136
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -140,7 +140,7 @@ jobs:
140140
- name: Collect Coverage for clang v12
141141
env:
142142
CLANG_VERSION: '12'
143-
run: just test
143+
run: just test ci
144144

145145
- name: Install clang 13
146146
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -150,7 +150,7 @@ jobs:
150150
- name: Collect Coverage for clang v13
151151
env:
152152
CLANG_VERSION: '13'
153-
run: just test
153+
run: just test ci
154154

155155
- name: Install clang 14
156156
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -160,7 +160,7 @@ jobs:
160160
- name: Collect Coverage for clang v14
161161
env:
162162
CLANG_VERSION: '14'
163-
run: just test
163+
run: just test ci
164164

165165
- name: Install clang 15
166166
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -170,7 +170,7 @@ jobs:
170170
- name: Collect Coverage for clang v15
171171
env:
172172
CLANG_VERSION: '15'
173-
run: just test
173+
run: just test ci
174174

175175
- name: Install clang 16
176176
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -180,7 +180,7 @@ jobs:
180180
- name: Collect Coverage for clang v16
181181
env:
182182
CLANG_VERSION: '16'
183-
run: just test
183+
run: just test ci
184184

185185
- name: Install clang 17
186186
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -190,7 +190,7 @@ jobs:
190190
- name: Collect Coverage for clang v17
191191
env:
192192
CLANG_VERSION: '17'
193-
run: just test
193+
run: just test ci
194194

195195
- name: Install clang 18
196196
uses: cpp-linter/cpp_linter_rs/install-clang-action@main
@@ -200,7 +200,7 @@ jobs:
200200
- name: Collect Coverage for clang v18
201201
env:
202202
CLANG_VERSION: '18'
203-
run: just test --run-ignored=all
203+
run: just test all
204204

205205
- name: Generate Coverage HTML report
206206
run: just pretty-cov
@@ -212,13 +212,11 @@ jobs:
212212
path: target/llvm-cov-pretty
213213

214214
- name: Generate Coverage lcov report
215-
if: runner.os == 'Linux'
216215
run: |
217216
rm coverage.json
218217
just lcov
219218
220219
- uses: codecov/codecov-action@v4
221-
if: runner.os == 'Linux'
222220
with:
223221
token: ${{secrets.CODECOV_TOKEN}}
224222
files: lcov.info

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cpp-linter/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ license.workspace = true
1414
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1515

1616
[dependencies]
17+
anyhow = "1.0.89"
1718
chrono = "0.4.38"
1819
clap = "4.5.17"
1920
fast-glob = "0.4.0"

cpp-linter/src/clang_tools/clang_format.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{
66
sync::{Arc, Mutex, MutexGuard},
77
};
88

9+
use anyhow::{Context, Result};
910
use log::Level;
1011
// non-std crates
1112
use serde::Deserialize;
@@ -56,13 +57,15 @@ pub struct Replacement {
5657
///
5758
/// This value is not provided by the XML output, but we calculate it after
5859
/// deserialization.
59-
pub line: Option<usize>,
60+
#[serde(default)]
61+
pub line: usize,
6062

6163
/// The column number on the line described by the [`Replacement::offset`].
6264
///
6365
/// This value is not provided by the XML output, but we calculate it after
6466
/// deserialization.
65-
pub cols: Option<usize>,
67+
#[serde(default)]
68+
pub cols: usize,
6669
}
6770

6871
impl Clone for Replacement {
@@ -109,15 +112,16 @@ pub fn tally_format_advice(files: &[Arc<Mutex<FileObj>>]) -> u64 {
109112
pub fn run_clang_format(
110113
file: &mut MutexGuard<FileObj>,
111114
clang_params: &ClangParams,
112-
) -> Vec<(log::Level, String)> {
115+
) -> Result<Vec<(log::Level, String)>> {
113116
let mut cmd = Command::new(clang_params.clang_format_command.as_ref().unwrap());
114117
let mut logs = vec![];
115118
cmd.args(["--style", &clang_params.style]);
116119
let ranges = file.get_ranges(&clang_params.lines_changed_only);
117120
for range in &ranges {
118121
cmd.arg(format!("--lines={}:{}", range.start(), range.end()));
119122
}
120-
cmd.arg(file.name.to_string_lossy().as_ref());
123+
let file_name = file.name.to_string_lossy().to_string();
124+
cmd.arg(file.name.to_path_buf().as_os_str());
121125
let mut patched = None;
122126
if clang_params.format_review {
123127
logs.push((
@@ -129,7 +133,7 @@ pub fn run_clang_format(
129133
.as_ref()
130134
.unwrap()
131135
.to_str()
132-
.unwrap(),
136+
.unwrap_or_default(),
133137
cmd.get_args()
134138
.map(|a| a.to_str().unwrap())
135139
.collect::<Vec<&str>>()
@@ -138,7 +142,7 @@ pub fn run_clang_format(
138142
));
139143
patched = Some(
140144
cmd.output()
141-
.expect("Failed to get fixes from clang-format")
145+
.with_context(|| format!("Failed to get fixes from clang-format: {file_name}"))?
142146
.stdout,
143147
);
144148
}
@@ -147,33 +151,30 @@ pub fn run_clang_format(
147151
log::Level::Info,
148152
format!(
149153
"Running \"{} {}\"",
150-
clang_params
151-
.clang_format_command
152-
.as_ref()
153-
.unwrap()
154-
.to_str()
155-
.unwrap(),
154+
cmd.get_program().to_string_lossy(),
156155
cmd.get_args()
157156
.map(|x| x.to_str().unwrap())
158157
.collect::<Vec<&str>>()
159158
.join(" ")
160159
),
161160
));
162-
let output = cmd.output().unwrap();
161+
let output = cmd
162+
.output()
163+
.with_context(|| format!("Failed to get replacements from clang-format: {file_name}"))?;
163164
if !output.stderr.is_empty() || !output.status.success() {
164165
logs.push((
165166
log::Level::Debug,
166167
format!(
167168
"clang-format raised the follow errors:\n{}",
168-
String::from_utf8(output.stderr).unwrap()
169+
String::from_utf8_lossy(&output.stderr)
169170
),
170171
));
171172
}
172173
if output.stdout.is_empty() {
173-
return logs;
174+
return Ok(logs);
174175
}
175176
let xml = String::from_utf8(output.stdout)
176-
.unwrap()
177+
.with_context(|| format!("stdout from clang-format was not UTF-8 encoded: {file_name}"))?
177178
.lines()
178179
.collect::<Vec<&str>>()
179180
.join("");
@@ -189,11 +190,12 @@ pub fn run_clang_format(
189190
});
190191
format_advice.patched = patched;
191192
if !format_advice.replacements.is_empty() {
193+
// get line and column numbers from format_advice.offset
192194
let mut filtered_replacements = Vec::new();
193195
for replacement in &mut format_advice.replacements {
194196
let (line_number, columns) = get_line_cols_from_offset(&file.name, replacement.offset);
195-
replacement.line = Some(line_number);
196-
replacement.cols = Some(columns);
197+
replacement.line = line_number;
198+
replacement.cols = columns;
197199
for range in &ranges {
198200
if range.contains(&line_number.try_into().unwrap_or(0)) {
199201
filtered_replacements.push(replacement.clone());
@@ -208,7 +210,7 @@ pub fn run_clang_format(
208210
format_advice.replacements = filtered_replacements;
209211
}
210212
file.format_advice = Some(format_advice);
211-
logs
213+
Ok(logs)
212214
}
213215

214216
#[cfg(test)]
@@ -234,29 +236,29 @@ mod tests {
234236
offset: 113,
235237
length: 5,
236238
value: Some(String::from("\n ")),
237-
line: None,
238-
cols: None,
239+
line: 0,
240+
cols: 0,
239241
},
240242
Replacement {
241243
offset: 147,
242244
length: 0,
243245
value: Some(String::from(" ")),
244-
line: None,
245-
cols: None,
246+
line: 0,
247+
cols: 0,
246248
},
247249
Replacement {
248250
offset: 161,
249251
length: 0,
250252
value: None,
251-
line: None,
252-
cols: None,
253+
line: 0,
254+
cols: 0,
253255
},
254256
Replacement {
255257
offset: 165,
256258
length: 19,
257259
value: Some(String::from("\n\n")),
258-
line: None,
259-
cols: None,
260+
line: 0,
261+
cols: 0,
260262
},
261263
],
262264
patched: None,

0 commit comments

Comments
 (0)