Skip to content

A Swift compiler plugin to propagate CODEOWNERS attribution to Swift types

License

Notifications You must be signed in to change notification settings

gmazzo/swift-codeowners-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub SPM Build Status Coverage Users

Contributors

swift-codeowners-plugin

A Swift compiler plugin to propagate CODEOWNERS attribution to Swift types

Usage

Setup the compiler plugin and the runtime library in your project: In your Package.swift add the plugin dependency:

let package = Package(
    name: "MyProject",
    dependencies: [
        .package(url: "https://github.com/gmazzo/swift-codeowners-plugin", from: "x.y.z"),
    ],
    targets: [
        .target(
            name: "MyProjectTarget", 
            dependencies: [
                .product(name: "CodeOwnersAPI", package: "swift-codeowners-plugin")
            ],
            plugins: [
                .plugin(name: "CodeOwnersPlugin", package: "swift-codeowners-plugin")
            ]
        )
    ]
)

Then you can use the codeOwnersOf function on any struct, class or enum to query their owners at runtime:

struct MyType {
    func printOwner() {
        print("This type is owned by \(codeOwnersOf(self))") // or
        print("This type is owned by \(codeOwnersOf(MyType.self))") // or
        print("This type is owned by \(codeOwnersOf(MyType()))") // or
    }
}

The #codeowners macro

As an alternative or complementary approach, can you also define and use a #codeowners embed the owners of a file at compile time:

class MyClass {
    static let owners = #codeowners
    
    func printOwner() {
        print("This file is owned by \(#owners)") 
    }
}

Note

Due Swift macros limitations, the #codeowners macro can not be provided out-of-the-box, and it requires instead to define an ad-hoc .macro target in your project.

Setting up the #codeowners macro

First, declare a new macro target in your Package.swift (if you don't have one yet):

    targets: [
        .macro(
            name: "MyMacros",
            dependencies: [
                .product(name: "CodeOwnersMacro", package: "swift-codeowners-plugin"),
            ],
            plugins: [
                .plugin(name: "CodeOwnersMacroPlugin", package: "swift-codeowners-plugin")
            ]
        )
    ]

And make sure you define a CompilerPlugin exposing the CodeOwnersMacro:

import SwiftCompilerPlugin
import SwiftSyntaxMacros

@main
struct MacrosPlugin: CompilerPlugin {
    let providingMacros: [Macro.Type] = [ CodeOwnersMacro.self ]
}

Note

The CodeOwnersMacro type will be generated by the CodeOwnersMacroPlugin plugin

Then let your main target depend on the macro target:

    targets: [
        .target(
            name: "MyProject", 
            dependencies: [
                "MyMacros" // <-- add this line
            ]
        )
    ]

Finally, import the macro module and use the #codeowners macro in your code:

@freestanding(expression)
public macro codeOwners() -> Set<String>? = #externalMacro(module: "MyMacros", type: "CodeOwnersMacro")

The CODEOWNERS file

The expected format is the same as GitHub's and it can be located at any of the following paths:

  • $rootDir/CODEOWNERS
  • $rootDir/.github/CODEOWNERS
  • $rootDir/.gitlab/CODEOWNERS
  • $rootDir/docs/CODEOWNERS

Where rootDir is either project's or GIT's root directory

The .codeowners-tool.json configuration file

You can customize the plugin behavior by adding a .codeowners-tool.json file:

{
  "codeOwners": {
    "root": ".",                  // The root directory where the CODEOWNERS file patterns are based from.
    "file": ".github/CODEOWNERS"  // The CODEOWNERS file to use for determining ownership.
  },
  "renames": {
    "regEx": "replacement"        // Regex pattern to rename ownership names, in <regex>=<replacement> format)
  },
  "verbose": true,                // Enable verbose output for debugging purposes.
  "quiet": true                   // Suppress non-error output.
}

About

A Swift compiler plugin to propagate CODEOWNERS attribution to Swift types

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Languages