Harmonize is a Swift project with powerful linting capabilities, allowing developers to easily assert, validate, and harmonize code structure and architecture through declarative tests. It can enforce best practices to ensure a clean, maintainable, and consistent codebase aligned with your project guidelines.
Harmonize lint rules are written as unit tests using XCTest or Quick.
Warning
Harmonize is currently being developed in public and is used internally. It is considered an early alpha version, and its API is subject to change.
Add the following to your package dependencies:
// Product Dependencies block
.package(url: "https://github.com/perrystreetsoftware/harmonize.git", branch: "main")
// Target dependencies block
.product(name: "Harmonize", package: "Harmonize")
We recommend importing Harmonize
as part of your test target. While Harmonize can be used on any Swift package, you can also create a separate Swift package specifically for Harmonize rules to keep it decoupled from your main codebase.
To enable Harmonize to query your project files and provide the semantics API for your tests, you need to create a .harmonize.yaml
configuration file at the root level of your project. Currently, the only supported configuration is excludes
, which allows you to exclude specific files or folders from your project.
excludes:
- Package.swift
Note
We plan to build a CLI that will automate this process, but for the alpha version, this step is mandatory.
Using Harmonize is as simple as writing a unit test.
import XCTest
import Harmonize
final class ViewModelsTests: XCTestCase {
func testViewModelsBaseViewModelConformance() throws {
Harmonize.on("ViewModels").classes()
.assertTrue(message: "ViewModels must conform to AppLifecycleViewModel") {
$0.conforms(to: AppLifecycleViewModel.self)
}
}
}
Contributions are welcome through pull requests, issues, or feedback. We are still working on building a code of conduct.
This project is heavily inspired by SwiftLint and Konsist (a linter for Kotlin where this idea originated).
We see this project as a companion to your preferred compile-time linter, allowing you to create custom lint rules that align with your team and project architecture using unit tests.
Our Semantics module, built using Swift Syntax to parse the language Abstract Syntax Tree (AST), is inspired by the now-archived SwiftDocc Semantics.
Note
We are aware of potential performance issues when querying large codebases and parsing the AST. We are continuously working on improvements to make Harmonize faster.