Skip to content

Commit 861cf8b

Browse files
committed
fix: ci/cd and windows line endings
1 parent 1a3b71a commit 861cf8b

4 files changed

Lines changed: 140 additions & 25 deletions

File tree

.github/CODECOV_SETUP.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Codecov Setup Instructions
2+
3+
To enable code coverage reporting for this repository:
4+
5+
## 1. Sign up for Codecov
6+
1. Go to [codecov.io](https://about.codecov.io/)
7+
2. Sign in with your GitHub account
8+
3. Grant access to this repository
9+
10+
## 2. Get the Upload Token
11+
1. Navigate to your repository in Codecov
12+
2. Go to Settings → General
13+
3. Copy the Repository Upload Token
14+
15+
## 3. Add the Token to GitHub Secrets
16+
1. Go to your GitHub repository
17+
2. Navigate to Settings → Secrets and variables → Actions
18+
3. Click "New repository secret"
19+
4. Name: `CODECOV_TOKEN`
20+
5. Value: (paste the token from Codecov)
21+
22+
## 4. Update the CI Workflow (Optional)
23+
Once the token is configured, you can update `.github/workflows/ci.yml`:
24+
- Change `fail_ci_if_error: false` to `fail_ci_if_error: true`
25+
- Remove `continue-on-error: true`
26+
27+
## Current Configuration
28+
The codecov integration is currently configured to:
29+
- Not fail the CI build if coverage upload fails
30+
- Run in informational mode (won't block PRs)
31+
- Ignore test files and the binary entry point
32+
33+
This allows the CI to pass while Codecov is not fully configured.

.github/workflows/ci.yml

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ jobs:
8989
shell: bash
9090
run: |
9191
# Create test data
92-
echo -e "3\n1\n2" > test.txt
92+
printf "3\n1\n2\n" > test.txt
9393
9494
# Test basic sorting
9595
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
@@ -98,22 +98,20 @@ jobs:
9898
./target/release/sort test.txt > output.txt
9999
fi
100100
101-
# Check output
102-
expected="1\n2\n3"
103-
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
104-
# Windows line endings
105-
if ! echo -e "1\r\n2\r\n3" | cmp -s - output.txt; then
106-
echo "Basic sort test failed"
107-
cat output.txt
108-
exit 1
109-
fi
110-
else
111-
if ! echo -e "$expected" | cmp -s - output.txt; then
112-
echo "Basic sort test failed"
113-
cat output.txt
114-
exit 1
115-
fi
101+
# Check output - simplified cross-platform test
102+
# Extract just the numbers and check they're in order
103+
sorted_output=$(cat output.txt | tr -d '\r' | tr '\n' ' ')
104+
expected="1 2 3 "
105+
106+
if [[ "$sorted_output" != "$expected" ]]; then
107+
echo "Basic sort test failed"
108+
echo "Expected: $expected"
109+
echo "Got: $sorted_output"
110+
echo "Raw output:"
111+
cat output.txt | od -c
112+
exit 1
116113
fi
114+
117115
echo "✅ Basic functionality test passed"
118116
119117
benchmark:
@@ -199,7 +197,9 @@ jobs:
199197
uses: codecov/codecov-action@v3
200198
with:
201199
file: lcov.info
202-
fail_ci_if_error: true
200+
fail_ci_if_error: false
201+
verbose: true
202+
continue-on-error: true
203203

204204
docs:
205205
name: Documentation
@@ -217,12 +217,13 @@ jobs:
217217
- name: Build documentation
218218
run: cargo doc --no-deps --all-features
219219

220-
- name: Deploy documentation (main branch only)
221-
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
222-
uses: peaceiris/actions-gh-pages@v3
223-
with:
224-
github_token: ${{ secrets.GITHUB_TOKEN }}
225-
publish_dir: ./target/doc
220+
# Documentation deployment disabled until gh-pages branch is configured
221+
# - name: Deploy documentation (main branch only)
222+
# if: github.ref == 'refs/heads/main' && github.event_name == 'push'
223+
# uses: peaceiris/actions-gh-pages@v3
224+
# with:
225+
# github_token: ${{ secrets.GITHUB_TOKEN }}
226+
# publish_dir: ./target/doc
226227

227228
release:
228229
name: Create Release

codecov.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
codecov:
2+
require_ci_to_pass: false
3+
notify:
4+
wait_for_ci: false
5+
6+
coverage:
7+
status:
8+
project:
9+
default:
10+
# Basic settings for code coverage
11+
target: auto
12+
threshold: 1%
13+
informational: true # Won't fail the build
14+
patch:
15+
default:
16+
target: auto
17+
threshold: 1%
18+
informational: true # Won't fail the build
19+
20+
comment:
21+
layout: "reach,diff,flags,files,footer"
22+
behavior: default
23+
require_changes: false
24+
25+
ignore:
26+
- "tests/**"
27+
- "benches/**"
28+
- "examples/**"
29+
- "src/main.rs" # Ignore the binary entry point

src/zero_copy.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,15 +601,26 @@ fn parse_lines(data: &[u8]) -> Vec<Line> {
601601

602602
for (i, &byte) in data.iter().enumerate() {
603603
if byte == b'\n' {
604-
let line_data = &data[start..i];
604+
// Handle both Unix (\n) and Windows (\r\n) line endings
605+
let end = if i > 0 && data[i - 1] == b'\r' {
606+
i - 1
607+
} else {
608+
i
609+
};
610+
let line_data = &data[start..end];
605611
lines.push(Line::new(line_data));
606612
start = i + 1;
607613
}
608614
}
609615

610616
// Handle last line if it doesn't end with newline
611617
if start < data.len() {
612-
let line_data = &data[start..];
618+
let mut end = data.len();
619+
// Strip trailing \r if present
620+
if end > start && data[end - 1] == b'\r' {
621+
end -= 1;
622+
}
623+
let line_data = &data[start..end];
613624
lines.push(Line::new(line_data));
614625
}
615626

@@ -899,4 +910,45 @@ mod tests {
899910
assert_eq!(parse_int(b"12.34"), None); // Not simple
900911
assert_eq!(parse_int(b"abc"), None); // Not numeric
901912
}
913+
914+
#[test]
915+
fn test_parse_lines_with_different_endings() {
916+
// Test Unix line endings
917+
let unix_data = b"line1\nline2\nline3";
918+
let unix_lines = parse_lines(unix_data);
919+
assert_eq!(unix_lines.len(), 3);
920+
unsafe {
921+
assert_eq!(unix_lines[0].as_bytes(), b"line1");
922+
assert_eq!(unix_lines[1].as_bytes(), b"line2");
923+
assert_eq!(unix_lines[2].as_bytes(), b"line3");
924+
}
925+
926+
// Test Windows line endings
927+
let windows_data = b"line1\r\nline2\r\nline3\r\n";
928+
let windows_lines = parse_lines(windows_data);
929+
assert_eq!(windows_lines.len(), 3);
930+
unsafe {
931+
assert_eq!(windows_lines[0].as_bytes(), b"line1");
932+
assert_eq!(windows_lines[1].as_bytes(), b"line2");
933+
assert_eq!(windows_lines[2].as_bytes(), b"line3");
934+
}
935+
936+
// Test mixed line endings
937+
let mixed_data = b"line1\r\nline2\nline3\r";
938+
let mixed_lines = parse_lines(mixed_data);
939+
assert_eq!(mixed_lines.len(), 3);
940+
unsafe {
941+
assert_eq!(mixed_lines[0].as_bytes(), b"line1");
942+
assert_eq!(mixed_lines[1].as_bytes(), b"line2");
943+
assert_eq!(mixed_lines[2].as_bytes(), b"line3");
944+
}
945+
946+
// Test single line without ending
947+
let single_data = b"single_line";
948+
let single_lines = parse_lines(single_data);
949+
assert_eq!(single_lines.len(), 1);
950+
unsafe {
951+
assert_eq!(single_lines[0].as_bytes(), b"single_line");
952+
}
953+
}
902954
}

0 commit comments

Comments
 (0)