A Swift compiler plugin to propagate CODEOWNERS attribution to Swift types
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
    }
}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.
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 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.
}