Home

Awesome

swift-mod

A tool for Swift code modification intermediating between code generation and formatting.

swift release test lincense


Overview

swift-mod is a tool for Swift code modification that intermediating between code generator and formatter built on top of apple/SwiftSyntax.
It can generates boilerplate code, such as access control or memberwise initializers in modularized source code, taking into account the state of the AST.
You can improve your productivity for writing more advanced Swift codes by introducing swift-mod.

Example

struct Avenger {
    var heroName: String
    internal var realName: String?
}

let avengers = [
    Avenger(heroName: "Iron Man", realName: "Tony Stark"),
    Avenger(heroName: "Captain America", realName: "Steve Rogers"),
    Avenger(heroName: "Thor"),
]

+ public struct Avenger {
+     public var heroName: String
    internal var realName: String?

+     public init(
+         heroName: String,
+         realName: String? = nil
+     ) {
+         self.heroName = heroName
+         self.realName = realName
+     }
}

+ public let avengers = [
    Avenger(heroName: "Iron Man", realName: "Tony Stark"),
    Avenger(heroName: "Captain America", realName: "Steve Rogers"),
    Avenger(heroName: "Thor"),
]

Getting Started

  1. Install swift-mod.

  2. Generates configuration file.

swift-mod init
  1. Check the all modification rules.
swift-mod rules
swift-mod rules --rule [RULE NAME] # Display more detailed rule description
  1. Edit your configuration file with an editor you like, refering to the documentation.

  2. Run

swift-mod <list of input files>

Command Usage

swift-mod [COMMAND] [OPTIONS]

All commands can be display a usage by option -h/--help.

OVERVIEW: Runs modification.

USAGE: swift-mod run [--mode <mode>] [--configuration <configuration>] [<paths> ...]

ARGUMENTS:
  <paths>                 Zero or more input filenames.

OPTIONS:
  -m, --mode <mode>                   Overrides running mode: modify|dry-run|check. (default: modify)
  -c, --configuration <configuration> The path to a configuration file.
  -h, --help                          Show help information.
OVERVIEW: Generates a modify configuration file.

USAGE: swift-mod init [--output <output>]

OPTIONS:
  -o, --output <output>   An output for the configuration file to be generated.
  -h, --help              Show help information.
OVERVIEW: Display the list of rules.

USAGE: swift-mod rules [--rule <rule>]

OPTIONS:
  -r, --rule <rule>       A rule name to see detail.
  -h, --help              Show help information.

Configuration

Modification rules and targets are defines with YAML-formatted file. By default, it's searched by name .swift-mod.yml.
Any file name is allowed with passing with option like follows:

swift-mod --configuration <configuration>

Example

format:
  indent: 4
  lineBreakBeforeEachArgument: true
rules:
  defaultAccessLevel:
    accessLevel: openOrPublic
    implicitInternal: true
  defaultMemberwiseInitializer:
    implicitInitializer: false
    implicitInternal: true
    ignoreClassesWithInheritance: false

Format

Determines the format setting in all rules.
Format according to this setting only when changes occur.

KEYVALUEREQUIREMENTDEFAULT
indentThe number of spaces, or tab by textOptional4
lineBreakBeforeEachArgumentIndicating whether to insert new lines before each function argumentOptionaltrue

Rules

Default Access Level

IDENTIFIEROVERVIEW
defaultAccessLevelAssigns the suitable access level to all declaration syntaxes if not present
KEYVALUEREQUIREMENTDEFAULT
accessLevel|openOrPublic|public|internal|fileprivate|private|Required
implicitInternalIndicating whether to omit the internal access levelOptionaltrue
struct Avenger {
    var heroName: String
    internal var realName: String?
}
+ public struct Avenger {
+    public var heroName: String
    internal var realName: String?
}

Default Memberwise Initializer

IDENTIFIEROVERVIEW
defaultMemberwiseInitializerDefines a memberwise initializer according to the access level in the type declaration if not present
KEYVALUEREQUIREMENTDEFAULT
implicitInitializerIndicating whether to omit the internal initializer in struct decalarationOptionalfalse
implicitInternalIndicating whether to omit the internal access levelOptionaltrue
ignoreClassesWithInheritanceIndicating whether to skip the classes having inheritance including protocolOptionalfalse
struct Avenger {
    var heroName: String
    internal var realName: String?
}
struct Avenger {
    var heroName: String
    internal var realName: String?

+    init(
+        heroName: String,
+        realName: String? = nil
+    ) {
+        self.heroName = heroName
+        self.realName = realName
+    }
}

Ignoring Rules

swift-mod allows users to suppress modification for node and its children by comment like below.

// swift-mod-ignore

// swift-mod-ignore
struct Avenger {
    var heroName: String
    internal var realName: String?
}

// swift-mod-ignore: [COMMA DELIMITED RULE IDENTIFIERS]

// swift-mod-ignore: defaultAccessLevel, defaultMemberwiseInitializer
struct Avenger {
    var heroName: String
    internal var realName: String?
}

Installation

Swift Package Manager

Add the following to the dependencies of your Package.swift:

dependencies: [
    .package(url: "https://github.com/ra1028/swift-mod.git", from: "swift-mod version"),
]

Run command:

swift run -c release swift-mod [COMMAND] [OPTIONS]

Mint

Install with Mint by following command:

mint install ra1028/swift-mod

Run command:

mint run ra1028/swift-mod [COMMAND] [OPTIONS]

Using a pre-built binary

You can also install swift-mod by downloading swift-mod.zip from the latest GitHub release.

Swift Version Support

swift-mod depends on SwiftSyntax version that matches the toolchain version in use.
So you should use swift-mod version that built with compatible version of Swift you are using.

Swift VersionLast Supported swift-mod
5.10.0.2
5.20.0.4
5.30.0.5
5.40.0.6
5.50.0.7
5.60.1.0
5.70.1.1
5.80.2.0
5.90.2.0
5.100.2.1

Development

Pull requests, bug reports and feature requests are welcome 🚀.
See CONTRIBUTING.md file to learn how to contribute to swift-mod.

Please validate and test your code before you submit your changes by following commands:

 make autocorrect # Modifying, formatting, linting codes and generating Linux XCTest manifests.  
 make test

In addition, swift-mod supports running on Linux, so you should test by installing Docker and following command:

make docker-test

License

swift-mod is released under the Apache 2.0 License.