Repository navigation
A patch release. The JSON report now carries the real tool version, the CLI integration tests are deterministic again, and every document was checked against the code and corrected.
What's new
Bug fix
-
JSON report
versionreflects the tool version (#42, #43, #47): The top-levelversionfield was hardcoded as"1.0.0"in every release. It is now the same stringswift-cpd --versionprints."version": "swift-cpd 1.5.1 [arm64-macos15]"
Note: The value changes format, from a bare semver (
1.0.0) toswift-cpd <version> [<arch>-<os>]. Update any consumer that parsed this field as a plain version number.
Test suite hardening
- The
swift-cpdexecutable is found reliably (#37, #40): CLI tests resolve the binary from the package root via#filePath, using an architecture-independent.build/debugpath instead ofBundle.allBundles. A missing binary now fails with a clearMissingExecutableError. - No more hangs or flaky results (#38):
- Child process output goes to files, which avoids pipe buffer deadlocks.
runSwiftCPDfails after a deadline (ProcessTimeoutError) instead of hanging the suite.- The ignore-structural integration test checks clone types instead of JSON byte length.
Documentation
- Full documentation review (#45): every document was checked against the source and tests, and the sample outputs come from real runs. Corrections:
- README: the configuration example used an inline list (
enabledCloneTypes: [1, 2, 3, 4]), which the YAML parser rejects. It now uses a block list. - Inline suppression: a trailing
// swiftcpd:ignorecomment has no effect. The tag must start its own comment line, and it suppresses the next non-blank line, or the whole{…}block when that line opens one. - Defaults:
ignoreSameFileandignoreStructuraldefault tofalse. Only theswift-cpd inittemplate sets them totrue. - Baseline matching is exact: type, token count, line count, and each fragment's file and line range. Edits that shift line numbers count as new clones.
- Output examples for text, JSON and xcode match the current reporters.
- SonarQube: removed a
sonar.swift.cpd.reportPathsproperty and abaseline:YAML key that were documented but do not exist. - Xcode plugin guide:
- Output goes to stdout.
- The Xcode entry point analyzes the whole project directory.
- The cache lives in the plugin work directory.
.swift-cpd.ymlis read from the build's working directory.
- Requirements: Xcode 26, needed for Swift 6.2.
- Architecture and CodeBase references: corrected for the per-file pipeline order, the tokenizers, the Type 3 and Type 4 algorithms and weights, glob semantics, and git-ref IO.
- README: the configuration example used an inline list (
- New content:
- the
inittemplate, the supported YAML syntax, the exceptions to config precedence, and a cache section inDocs/USAGE.md - make targets in
Docs/BUILDING.md - development setup and commit rules in
CONTRIBUTING.md - reference entries for
ArgumentParsingError,ConfigurationError, the YAML loader and parser,CTokenizerScanner,CLanguageVocabulary,CompiledPatternandFileTokens
- the
Chore
Package.resolvedis now tracked, and.gitignoreentries were updated.
Requirements
- macOS 15+
- Swift 6.2+ (Xcode 26+)
gitonPATHwhen using--source-ref
Installation
See the Installation Guide for Homebrew, pre-built binary, SPM plugin, and pre-commit hook setup.
Quality bar
- 947 tests in 92 suites
- 100% line coverage
What's Changed
- fix(tests): resolve swift-cpd binary path independently of build architecture by @ericodx in #37
- fix(tests): make ignore-structural integration test deterministic and harden runSwiftCPD by @ericodx in #38
- fix(tests): resolve swift-cpd from the package root instead of Bundle.allBundles by @ericodx in #40
- fix: report the tool version in the JSON report by @ericodx in #43
- docs: review all documentation against the current code by @ericodx in #45
Full Changelog: v1.5.0...v1.5.1