8000 GitHub - perrystreetsoftware/Harmonize: Harmonize is a modern linter for Swift that allows you to write architectural lint rules as unit tests, helping your team to keep your codebase clean, maintainable, and consistent as it grows, without relying on manual code reviews.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Harmonize is a modern linter for Swift that allows you to write architectural lint rules as unit tests, helping your team to keep your codebase clean, maintainable, and consistent as it grows, without relying on manual code reviews.

License

Notifications You must be signed in to change notification settings

perrystreetsoftware/Harmonize

Repository files navigation

Harmonize

Tests

Harmonize is a modern linter for Swift that allows you to assert, validate, and harmonize your code’s structure and architecture by writing lint rules as unit tests—using Quick, XCTest, or Swift Testing.

This allows your team to keep your codebase clean, maintainable, and consistent as it grows, without relying on manual code reviews.

Harmonize aims to solve the limitations of regex-based linters such as SwiftLint, which focus primarily on Swift style and simple conventions. Inspired by Konsist for Kotlin and ArchUnit for Java, Harmonize provides a richer, semantic way to enforce your project's architecture and structural guidelines.

Usage

With Harmonize, you can write a lint rule similarly as you would write a unit test:

Example using Quick:

import Harmonize
import Quick

final class ViewModelsInheritBaseViewModelSpec: QuickSpec {
    override func spec() {
        describe("ViewModels") {
            let viewModels = Harmonize.productionCode().classes()
                .withNameEndingWith("ViewModel")

            it("should inherit from BaseViewModel") {
                viewModels.assertTrue(message: "All ViewModels must inherit from BaseViewModel") {
                    $0.inherits(from: "BaseViewModel")
                }
            }
        }
    }
}

Example using XCTest:

import Harmonize
import XCTest

final class ViewModelsInheritBaseViewModelSpec: XCTestCase {
    func testViewModels() throws {
        let viewModels = Harmonize.productionCode().classes()
            .withNameEndingWith("ViewModel")
        
        viewModels.assertTrue(message: "All ViewModels must inherit from BaseViewModel") {
            $0.inherits(from: "BaseViewModel")
        }
    }
}

Example using Swift Testing:

import Harmonize
import Testing

@Test
func viewModelsInheritBaseViewModel() {
    let viewModels = Harmonize.productionCode().classes()
        .withNameEndingWith("ViewModel")
        
    viewModels.assertTrue(message: "All ViewModels must inherit from BaseViewModel") {
        $0.inherits(from: "BaseViewModel")
    }
}

This lint rule enforces all ViewModels to inherit from BaseViewModel. Since it runs as a unit test, it will fail once it detects a violation. You can add exceptions or a baseline to this rule using the withoutName function:

let viewModels = Harmonize.productionCode().classes()
    .withNameEndingWith("ViewModel")
    .withoutName(["LegacyViewModel"])

You can create similar rules for any architectural or structural pattern that you want to enforce.

Unlike regex-based linters such as SwiftLint, Harmonize provides you with a rich and simple API to directly access any component in your codebase—including files, packages, classes, functions, and properties—and make assertions about them.

Installation

Swift Package Manager (SPM)

To add Harmonize using Swift Package Manager, follow these steps:

In Xcode:

  • Go to File > Add Package Dependencies....
  • Enter the repository URL: https://github.com/perrystreetsoftware/Harmonize.git.
  • Add it as a dependency to your test target

Or, manually add it to your Package.swift file:

.package(url: "https://github.com/perrystreetsoftware/Harmonize.git", from: "0.2.0"),

You can optionally create a dedicated Swift package for your Harmonize lint rules to separate them from the rest of the unit tests.

Configuration

Add an empty .harmonize.yaml file to the root of your project. This file is required for Harmonize to correctly detect the project root and apply your lint rules.

You can also optionally specify which files or folders you want to exclude from all lint rules, using the excludes key:

excludes:
  - Package.swift

Integrating with CI/CD

Since Harmonize lint rules run as unit tests, you can integrate them easily into your existing CI/CD pipeline and automate them, similarly as you would automate your unit tests. Here’s an example of a GitHub Action that runs all your Harmonize lint rules when a pull request is opened:

name: Run Harmonize Lint Rules
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  harmonize:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run Harmonize Rules (macOS)
        run: |
          xcodebuild -scheme YourHarmonizeTestScheme -sdk macosx test

Articles

Example project

You can see an example project that uses Harmonize here.

Contributing

All contributions are welcome through pull requests, issues, or discussions.

About

Harmonize is a modern linte 6AA4 r for Swift that allows you to write architectural lint rules as unit tests, helping your team to keep your codebase clean, maintainable, and consistent as it grows, without relying on manual code reviews.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 7

Languages

0