Skip to content

Commit 765b54c

Browse files
authored
Merge pull request #13 from alexey1312/feature/cc
Add automatic code coverage conversion and reporting
2 parents 25236b6 + f811109 commit 765b54c

File tree

5 files changed

+1319
-13
lines changed

5 files changed

+1319
-13
lines changed

CLAUDE.md

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,36 @@ xcodebuild build 2>&1 | xcsift --print-warnings
4545
# Quiet mode - suppress output when build succeeds with no warnings or errors
4646
swift build 2>&1 | xcsift --quiet
4747
xcodebuild build 2>&1 | xcsift -q
48+
49+
# Code coverage - automatically converts .profraw/.xcresult to JSON (no manual conversion needed!)
50+
51+
# SPM: auto-detects and converts .profraw files (summary-only by default)
52+
swift test --enable-code-coverage 2>&1 | xcsift --coverage
53+
swift test --enable-code-coverage 2>&1 | xcsift -c
54+
55+
# xcodebuild: auto-detects and converts .xcresult bundles (searches DerivedData automatically!)
56+
# Automatically filters coverage to tested target only
57+
xcodebuild test -enableCodeCoverage YES 2>&1 | xcsift --coverage
58+
59+
# Show detailed per-file coverage (default is summary-only for token efficiency)
60+
swift test --enable-code-coverage 2>&1 | xcsift --coverage --coverage-details
61+
xcodebuild test 2>&1 | xcsift -c --coverage-details
62+
63+
# Specify custom coverage path (optional - auto-detects by default)
64+
swift test --enable-code-coverage 2>&1 | xcsift --coverage --coverage-path .build/arm64-apple-macosx/debug/codecov
65+
xcodebuild test 2>&1 | xcsift --coverage --coverage-path path/to/file.xcresult
66+
67+
# Auto-detection and conversion:
68+
# SPM (.profraw → .profdata → JSON via llvm tools):
69+
# - .build/debug/codecov
70+
# - .build/arm64-apple-macosx/debug/codecov
71+
# - .build/x86_64-apple-macosx/debug/codecov
72+
# - .build/arm64-unknown-linux-gnu/debug/codecov
73+
# - .build/x86_64-unknown-linux-gnu/debug/codecov
74+
#
75+
# xcodebuild (.xcresult → JSON via xcrun xccov):
76+
# - ~/Library/Developer/Xcode/DerivedData/**/*.xcresult (searches automatically)
77+
# - Current directory/**/*.xcresult
4878
```
4979

5080
## Architecture
@@ -59,9 +89,10 @@ The codebase follows a simple two-component architecture:
5989

6090
2. **OutputParser.swift** - Core parsing logic
6191
- `OutputParser` class with regex-based line parsing
62-
- Defines data structures: `BuildResult`, `BuildSummary`, `BuildError`, `BuildWarning`, `FailedTest`
92+
- Defines data structures: `BuildResult`, `BuildSummary`, `BuildError`, `BuildWarning`, `FailedTest`, `CodeCoverage`, `FileCoverage`
6393
- Pattern matching for various Xcode/SPM output formats
6494
- Extracts file paths, line numbers, and messages from build output
95+
- Parses code coverage data from SPM coverage JSON files
6596

6697
### Data Flow
6798
1. Stdin input → `readStandardInput()`
@@ -74,6 +105,19 @@ The codebase follows a simple two-component architecture:
74105
- **Test Failure Detection**: XCUnit assertion failures and general test failures
75106
- **Build Time Extraction**: Captures build duration from output
76107
- **File/Line Mapping**: Extracts precise source locations for navigation
108+
- **Code Coverage with Auto-Conversion**: Automatically converts coverage files to JSON when `--coverage` flag is used
109+
- **Auto-detection**: Searches multiple default paths for both SPM and xcodebuild formats
110+
- **Target filtering**: Automatically extracts tested target name from xcodebuild output and filters coverage to that target only
111+
- **Summary-only mode** (default): Outputs only line coverage percentage to minimize token usage
112+
- **Details mode** (with `--coverage-details`): Includes full per-file coverage data
113+
- **SPM auto-conversion**: Finds `.profraw` files, locates test binary, runs `llvm-profdata merge` and `llvm-cov export`
114+
- `.profraw``.profdata` → JSON (fully automatic)
115+
- **xcodebuild auto-conversion**: Finds `.xcresult` bundles, runs `xcrun xccov view --report --json`
116+
- `.xcresult` → JSON (fully automatic)
117+
- **No manual steps**: Works out of the box with both build systems
118+
- SPM: `swift test --enable-code-coverage 2>&1 | xcsift --coverage`
119+
- xcodebuild: `xcodebuild test -enableCodeCoverage YES 2>&1 | xcsift --coverage`
120+
- Supports both formats seamlessly
77121

78122
## Testing
79123

@@ -84,6 +128,14 @@ Tests are in `Tests/OutputParserTests.swift` using XCTest framework. Test cases
84128
- Multi-error scenarios
85129
- Build time parsing
86130
- Edge cases (missing files, deprecated functions)
131+
- Code coverage data structures and parsing
132+
- JSON encoding with and without coverage data
133+
- SPM coverage format parsing
134+
- xcodebuild coverage format parsing (decimal and percentage formats)
135+
- Format auto-detection
136+
- Target extraction from xcodebuild output
137+
- Coverage target filtering
138+
- Summary-only vs details mode for coverage output
87139

88140
Run individual tests:
89141
```bash
@@ -100,8 +152,39 @@ swift test --filter OutputParserTests.testParseError
100152

101153
The tool outputs structured data optimized for coding agents:
102154

103-
- **JSON**: Structured format with `status`, `summary`, `errors`, `warnings` (optional), `failed_tests`
155+
- **JSON**: Structured format with `status`, `summary`, `errors`, `warnings` (optional), `failed_tests`, `coverage` (optional)
104156
- **Summary always includes warning count**: `{"summary": {"warnings": N, ...}}`
157+
- **Summary includes coverage percentage** (when `--coverage` flag is used): `{"summary": {"coverage_percent": X.X, ...}}`
105158
- **Detailed warnings list** (with `--print-warnings` flag): `{"warnings": [{"file": "...", "line": N, "message": "..."}]}`
106159
- **Default behavior** (without flag): Only shows warning count in summary, omits detailed warnings array to reduce token usage
107160
- **Quiet mode** (with `--quiet` or `-q` flag): Produces no output when build succeeds with zero warnings and zero errors
161+
- **Coverage data** (with `--coverage` flag):
162+
- **Summary-only mode** (default - token-efficient): Only includes coverage percentage in summary
163+
```json
164+
{
165+
"summary": {
166+
"coverage_percent": 85.5
167+
}
168+
}
169+
```
170+
- **Details mode** (with `--coverage-details` flag): Includes per-file coverage details
171+
```json
172+
{
173+
"coverage": {
174+
"line_coverage": 85.5,
175+
"files": [
176+
{
177+
"path": "/path/to/file.swift",
178+
"name": "file.swift",
179+
"line_coverage": 92.5,
180+
"covered_lines": 37,
181+
"executable_lines": 40
182+
}
183+
]
184+
}
185+
}
186+
```
187+
- **Target filtering** (xcodebuild only): Automatically extracts tested target from stdout and filters coverage to that target only
188+
- Supports both SPM (`swift test --enable-code-coverage`) and xcodebuild (`-enableCodeCoverage YES`) formats
189+
- Automatically detects format and parses accordingly
190+
- Warns to stderr if target was detected but no matching coverage data found

README.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ A Swift command-line tool to parse and format xcodebuild/SPM output for coding a
1212
- **Structured error reporting** - Clear categorization of errors, warnings, and test failures
1313
- **File/line number extraction** - Easy navigation to problematic code locations
1414
- **Build status summary** - Quick overview of build results
15+
- **Automatic code coverage conversion** - Converts .profraw (SPM) and .xcresult (xcodebuild) to JSON automatically
16+
- **Target filtering** - Automatically filters xcodebuild coverage to tested target only
17+
- **Summary-only mode** - Default coverage output includes only percentage (token-efficient)
18+
- **Quiet mode** - Suppress output when build succeeds with no warnings or errors
1519

1620
## Installation
1721

@@ -74,6 +78,26 @@ xcodebuild build 2>&1 | xcsift
7478

7579
# Print detailed warnings list (useful for fixing warnings)
7680
xcodebuild build 2>&1 | xcsift --print-warnings
81+
xcodebuild build 2>&1 | xcsift -w
82+
83+
# Quiet mode - suppress output when build succeeds with no warnings or errors
84+
xcodebuild build 2>&1 | xcsift --quiet
85+
swift build 2>&1 | xcsift -q
86+
87+
# Code coverage - automatic conversion from .profraw or .xcresult to JSON
88+
# Default: summary-only mode (line coverage percentage only - token-efficient)
89+
# xcodebuild automatically searches ~/Library/Developer/Xcode/DerivedData for latest .xcresult
90+
# and filters to tested target only
91+
swift test --enable-code-coverage 2>&1 | xcsift --coverage
92+
xcodebuild test -enableCodeCoverage YES 2>&1 | xcsift --coverage
93+
xcodebuild test 2>&1 | xcsift -c
94+
95+
# Show detailed per-file coverage (use when you need file-by-file breakdown)
96+
swift test --enable-code-coverage 2>&1 | xcsift --coverage --coverage-details
97+
xcodebuild test 2>&1 | xcsift -c --coverage-details
98+
99+
# Specify custom coverage path (optional - auto-detects by default)
100+
swift test --enable-code-coverage 2>&1 | xcsift --coverage --coverage-path .build/arm64-apple-macosx/debug/codecov
77101

78102
# Test output parsing
79103
xcodebuild test 2>&1 | xcsift
@@ -94,7 +118,9 @@ swift test 2>&1 | xcsift
94118
"errors": 2,
95119
"warnings": 1,
96120
"failed_tests": 2,
97-
"build_time": "3.2 seconds"
121+
"passed_tests": 28,
122+
"build_time": "3.2",
123+
"coverage_percent": 85.5
98124
},
99125
"errors": [
100126
{
@@ -115,12 +141,37 @@ swift test 2>&1 | xcsift
115141
"test": "Test assertion",
116142
"message": "XCTAssertEqual failed: (\"invalid\") is not equal to (\"valid\")"
117143
}
118-
]
144+
],
145+
"coverage": {
146+
"line_coverage": 85.5,
147+
"files": [
148+
{
149+
"path": "/path/to/ViewController.swift",
150+
"name": "ViewController.swift",
151+
"line_coverage": 92.5,
152+
"covered_lines": 37,
153+
"executable_lines": 40
154+
}
155+
]
156+
}
119157
}
120158
```
121159

122160
**Note on warnings:** By default, only the warning count appears in `summary.warnings`. The detailed `warnings` array (shown above) is only included when using the `--print-warnings` flag. This reduces token usage for coding agents that don't need to process every warning.
123161

162+
**Note on coverage:** The `coverage` section is only included when using the `--coverage-details` flag:
163+
- **Summary-only mode** (default): Only includes coverage percentage in summary for maximum token efficiency
164+
```json
165+
{
166+
"summary": {
167+
"coverage_percent": 85.5
168+
}
169+
}
170+
```
171+
- **Details mode** (with `--coverage-details`): Includes full `files` array as shown in the example above
172+
- **Target filtering** (xcodebuild only): Automatically extracts tested target from stdout and shows coverage for that target only
173+
- xcsift automatically converts `.profraw` files (SPM) or `.xcresult` bundles (xcodebuild) to JSON format without requiring manual llvm-cov or xccov commands
174+
124175

125176
## Comparison with xcbeautify/xcpretty
126177

@@ -131,6 +182,7 @@ swift test 2>&1 | xcsift
131182
| **Token efficiency** | High | Medium | Low |
132183
| **Machine readable** | Yes | No | Limited |
133184
| **Error extraction** | Structured | Visual | Visual |
185+
| **Code coverage** | Auto-converts | No | No |
134186
| **Build time** | Fast | Fast | Slower |
135187

136188
## Development

0 commit comments

Comments
 (0)