A tool to enforce Swift style and conventions.

Overview

SwiftLint

A tool to enforce Swift style and conventions, loosely based on the now archived GitHub Swift Style Guide. SwiftLint enforces the style guide rules that are generally accepted by the Swift community. These rules are well described in popular style guides like Ray Wenderlich's Swift Style Guide.

SwiftLint hooks into Clang and SourceKit to use the AST representation of your source files for more accurate results.

Build Status codecov.io

This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Language Switch: 中文, 한국어.

Installation

Using Homebrew:

brew install swiftlint

Using CocoaPods:

Simply add the following line to your Podfile:

pod 'SwiftLint'

This will download the SwiftLint binaries and dependencies in Pods/ during your next pod install execution and will allow you to invoke it via ${PODS_ROOT}/SwiftLint/swiftlint in your Script Build Phases.

This is the recommended way to install a specific version of SwiftLint since it supports installing a pinned version rather than simply the latest (which is the case with Homebrew).

Note that this will add the SwiftLint binaries, its dependencies' binaries and the Swift binary library distribution to the Pods/ directory, so checking in this directory to SCM such as git is discouraged.

Using Mint:

$ mint install realm/SwiftLint

Using a pre-built package:

You can also install SwiftLint by downloading SwiftLint.pkg from the latest GitHub release and running it.

Installing from source:

You can also build and install from source by cloning this project and running make install (Xcode 12 or later).

Usage

Presentation

To get a high-level overview of recommended ways to integrate SwiftLint into your project, we encourage you to watch this presentation or read the transcript:

Presentation

Xcode

Integrate SwiftLint into your Xcode project to get warnings and errors displayed in the issue navigator.

To do this click the Project in the file navigator, then click the primary app target, and go to Build Phases. Click the + and select "New Run Script Phase". Insert the following as the script:

if which swiftlint >/dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

You might want to move your SwiftLint phase directly before 'Compile Sources' step, to detect errors quickly before compiling. However, SwiftLint is designed to run on valid Swift code that cleanly completes the compiler's parsing stage. So running SwiftLint before 'Compile Sources' might yield some incorrect results.

If you wish to autocorrect violations as well, your script could run swiftlint autocorrect && swiftlint instead of just swiftlint. This will mean that all correctable violations are fixed, while ensuring warnings show up in your project for remaining violations.

If you've installed SwiftLint via CocoaPods the script should look like this:

"${PODS_ROOT}/SwiftLint/swiftlint"

Format on Save Xcode Plugin

To run swiftlint autocorrect on save in Xcode, install the SwiftLintXcode plugin from Alcatraz.

⚠️ This plugin will not work with Xcode 8 or later without disabling SIP. This is not recommended.

AppCode

To integrate SwiftLint with AppCode, install this plugin and configure SwiftLint's installed path in the plugin's preferences. The autocorrect action is available via ⌥⏎.

Atom

To integrate SwiftLint with Atom, install the linter-swiftlint package from APM.

Visual Studio Code

To integrate SwiftLint with vscode, install the vscode-swiftlint extension from the marketplace.

fastlane

You can use the official swiftlint fastlane action to run SwiftLint as part of your fastlane process.

swiftlint(
    mode: :lint,                            # SwiftLint mode: :lint (default) or :autocorrect
    executable: "Pods/SwiftLint/swiftlint", # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
    path: "/path/to/lint",                  # Specify path to lint (optional)
    output_file: "swiftlint.result.json",   # The path of the output file (optional)
    reporter: "json",                       # The custom reporter to use (optional)
    config_file: ".swiftlint-ci.yml",       # The path of the configuration file (optional)
    files: [                                # List of files to process (optional)
        "AppDelegate.swift",
        "path/to/project/Model.swift"
    ],
    ignore_exit_status: true,               # Allow fastlane to continue even if SwiftLint returns a non-zero exit status (Default: false)
    quiet: true,                            # Don't print status logs like 'Linting ' & 'Done linting' (Default: false)
    strict: true                            # Fail on warnings? (Default: false)
)

Command Line

$ swiftlint help
Available commands:

   analyze         [Experimental] Run analysis rules
   autocorrect     Automatically correct warnings and errors
   generate-docs   Generates markdown documentation for all rules
   help            Display general or command-specific help
   lint            Print lint warnings and errors (default command)
   rules           Display the list of rules and their identifiers
   version         Display the current version of SwiftLint

Run swiftlint in the directory containing the Swift files to lint. Directories will be searched recursively.

To specify a list of files when using lint, autocorrect or analyze (like the list of files modified by Xcode specified by the ExtraBuildPhase Xcode plugin, or modified files in the working tree based on git ls-files -m), you can do so by passing the option --use-script-input-files and setting the following instance variables: SCRIPT_INPUT_FILE_COUNT and SCRIPT_INPUT_FILE_0, SCRIPT_INPUT_FILE_1...SCRIPT_INPUT_FILE_{SCRIPT_INPUT_FILE_COUNT}.

These are same environment variables set for input files to custom Xcode script phases.

Working With Multiple Swift Versions

SwiftLint hooks into SourceKit so it continues working even as Swift evolves!

This also keeps SwiftLint lean, as it doesn't need to ship with a full Swift compiler, it just communicates with the official one you already have installed on your machine.

You should always run SwiftLint with the same toolchain you use to compile your code.

You may want to override SwiftLint's default Swift toolchain if you have multiple toolchains or Xcodes installed.

Here's the order in which SwiftLint determines which Swift toolchain to use:

  • $XCODE_DEFAULT_TOOLCHAIN_OVERRIDE
  • $TOOLCHAIN_DIR or $TOOLCHAINS
  • xcrun -find swift
  • /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • ~/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
  • ~/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain

sourcekitd.framework is expected to be found in the usr/lib/ subdirectory of the value passed in the paths above.

You may also set the TOOLCHAINS environment variable to the reverse-DNS notation that identifies a Swift toolchain version:

$ TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 swiftlint autocorrect

On Linux, SourceKit is expected to be located in /usr/lib/libsourcekitdInProc.so or specified by the LINUX_SOURCEKIT_LIB_PATH environment variable.

Rules

Over 200 rules are included in SwiftLint and the Swift community (that's you!) continues to contribute more over time. Pull requests are encouraged.

You can find an updated list of rules and more information about them here.

You can also check Source/SwiftLintFramework/Rules directory to see their implementation.

Opt-In Rules

opt_in_rules are disabled by default (i.e., you have to explicitly enable them in your configuration file).

Guidelines on when to mark a rule as opt-in:

  • A rule that can have many false positives (e.g. empty_count)
  • A rule that is too slow
  • A rule that is not general consensus or is only useful in some cases (e.g. force_unwrapping)

Disable rules in code

Rules can be disabled with a comment inside a source file with the following format:

// swiftlint:disable <rule1> [<rule2> <rule3>...]

The rules will be disabled until the end of the file or until the linter sees a matching enable comment:

// swiftlint:enable <rule1> [<rule2> <rule3>...]

For example:

// swiftlint:disable colon
let noWarning :String = "" // No warning about colons immediately after variable names!
// swiftlint:enable colon
let hasWarning :String = "" // Warning generated about colons immediately after variable names

Including the all keyword will disable all rules until the linter sees a matching enable comment:

// swiftlint:disable all // swiftlint:enable all

For example:

// swiftlint:disable all
let noWarning :String = "" // No warning about colons immediately after variable names!
let i = "" // Also no warning about short identifier names
// swiftlint:enable all
let hasWarning :String = "" // Warning generated about colons immediately after variable names
let y = "" // Warning generated about short identifier names

It's also possible to modify a disable or enable command by appending :previous, :this or :next for only applying the command to the previous, this (current) or next line respectively.

For example:

// swiftlint:disable:next force_cast
let noWarning = NSNumber() as! Int
let hasWarning = NSNumber() as! Int
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast
let noWarning3 = NSNumber() as! Int
// swiftlint:disable:previous force_cast

Run swiftlint rules to print a list of all available rules and their identifiers.

Configuration

Configure SwiftLint by adding a .swiftlint.yml file from the directory you'll run SwiftLint from. The following parameters can be configured:

Rule inclusion:

  • disabled_rules: Disable rules from the default enabled set.
  • opt_in_rules: Enable rules not from the default set.
  • only_rules: Only the rules specified in this list will be enabled. Cannot be specified alongside disabled_rules or opt_in_rules.
  • analyzer_rules: This is an entirely separate list of rules that are only run by the analyze command. All analyzer rules are opt-in, so this is the only configurable rule list, there are no equivalents for disabled_rules only_rules.
# By default, SwiftLint uses a set of sensible default rules you can adjust:
disabled_rules: # rule identifiers turned on by default to exclude from running
  - colon
  - comma
  - control_statement
opt_in_rules: # some rules are turned off by default, so you need to opt-in
  - empty_count # Find all the available rules by running: `swiftlint rules`

# Alternatively, specify all rules explicitly by uncommenting this option:
# only_rules: # delete `disabled_rules` & `opt_in_rules` if using this
#   - empty_parameters
#   - vertical_whitespace

included: # paths to include during linting. `--path` is ignored if present.
  - Source
excluded: # paths to ignore during linting. Takes precedence over `included`.
  - Carthage
  - Pods
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift
  - Source/*/ExcludedFile.swift # Exclude files with a wildcard
analyzer_rules: # Rules run by `swiftlint analyze` (experimental)
  - explicit_self

# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
force_try:
  severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length: 110
# they can set both implicitly with an array
type_body_length:
  - 300 # warning
  - 400 # error
# or they can set both explicitly
file_length:
  warning: 500
  error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
  min_length: 4 # only warning
  max_length: # warning and error
    warning: 40
    error: 50
  excluded: iPhone # excluded via string
  allowed_symbols: ["_"] # these are allowed in type names
identifier_name:
  min_length: # only min_length
    error: 4 # only error
  excluded: # excluded via string array
    - id
    - URL
    - GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)

You can also use environment variables in your configuration file, by using ${SOME_VARIABLE} in a string.

Defining Custom Rules

You can define custom regex-based rules in your configuration file using the following syntax:

custom_rules:
  pirates_beat_ninjas: # rule identifier
    included: ".*\\.swift" # regex that defines paths to include during linting. optional.
    excluded: ".*Test\\.swift" # regex that defines paths to exclude during linting. optional
    name: "Pirates Beat Ninjas" # rule name. optional.
    regex: "([nN]inja)" # matching pattern
    capture_group: 0 # number of regex capture group to highlight the rule violation at. optional.
    match_kinds: # SyntaxKinds to match. optional.
      - comment
      - identifier
    message: "Pirates are better than ninjas." # violation message. optional.
    severity: error # violation severity. optional.
  no_hiding_in_strings:
    regex: "([nN]inja)"
    match_kinds: string

This is what the output would look like:

You can filter the matches by providing one or more match_kinds, which will reject matches that include syntax kinds that are not present in this list. Here are all the possible syntax kinds:

  • argument
  • attribute.builtin
  • attribute.id
  • buildconfig.id
  • buildconfig.keyword
  • comment
  • comment.mark
  • comment.url
  • doccomment
  • doccomment.field
  • identifier
  • keyword
  • number
  • objectliteral
  • parameter
  • placeholder
  • string
  • string_interpolation_anchor
  • typeidentifier

If using custom rules in combination with only_rules, make sure to add custom_rules as an item under only_rules.

Auto-correct

SwiftLint can automatically correct certain violations. Files on disk are overwritten with a corrected version.

Please make sure to have backups of these files before running swiftlint autocorrect, otherwise important data may be lost.

Standard linting is disabled while correcting because of the high likelihood of violations (or their offsets) being incorrect after modifying a file while applying corrections.

Analyze (experimental)

The experimental swiftlint analyze command can lint Swift files using the full type-checked AST. The compiler log path containing the clean swiftc build command invocation (incremental builds will fail) must be passed to analyze via the --compiler-log-path flag. e.g. --compiler-log-path /path/to/xcodebuild.log

This can be obtained by running xcodebuild -workspace {WORKSPACE}.xcworkspace -scheme {SCHEME} > xcodebuild.log with a clean DerivedData folder.

This command and related code in SwiftLint is subject to substantial changes at any time while this feature is marked as experimental. Analyzer rules also tend to be considerably slower than lint rules.

Using Multiple Configuration Files

SwiftLint offers a variety of ways to include multiple configuration files. Multiple configuration files get merged into one single configuration that is then applied just as a single configuration file would get applied.

There are quite a lot of use cases where using multiple configuration files could be helpful:

For instance, one could use a team-wide shared SwiftLint configuration while allowing overrrides in each project via a child configuration file.

Team-Wide Configuration:

disabled_rules:
- force_cast

Project-Specific Configuration:

opt_in_rules:
- force_cast

Child / Parent Configs (Locally)

You can specify a child_config and / or a parent_config reference within a configuration file. These references should be local paths relative to the folder of the configuration file they are specified in. This even works recursively, as long as there are no cycles and no ambiguities.

A child config is treated as a refinement and therefore has a higher priority, while a parent config is considered a base with lower priority in case of conflicts.

Here's an example, assuming you have the following file structure:

ProjectRoot
    |_ .swiftlint.yml
    |_ .swiftlint_refinement.yml
    |_ Base
        |_ .swiftlint_base.yml

To include both the refinement and the base file, your .swiftlint.yml should look like this:

child_config: .swiftlint_refinement.yml
parent_config: Base/.swiftlint_base.yml

When merging parent and child configs, included and excluded configurations are processed carefully to account for differences in the directory location of the containing configuration files.

Child / Parent Configs (Remote)

Just as you can provide local child_config / parent_config references, instead of referencing local paths, you can just put urls that lead to configuration files. In order for SwiftLint to detect these remote references, they must start with http:// or https://.

The referenced remote configuration files may even recursively reference other remote configuration files, but aren't allowed to include local references.

Using a remote reference, your .swiftlint.yml could look like this:

parent_config: https://myteamserver.com/our-base-swiftlint-config.yml

Every time you run SwiftLint and have an Internet connection, SwiftLint tries to get a new version of every remote configuration that is referenced. If this request times out, a cached version is used if available. If there is no cached version available, SwiftLint fails – but no worries, a cached version should be there once SwiftLint has run successfully at least once.

If needed, the timeouts for the remote configuration fetching can be specified manually via the configuration file(s) using the remote_timeout / remote_timeout_if_cached specifiers. These values default to 2 / 1 second(s).

Command Line

Instead of just providing one configuration file when running SwiftLint via the command line, you can also pass a hierarchy, where the first configuration is treated as a parent, while the last one is treated as the highest-priority child.

A simple example including just two configuration files looks like this:

swiftlint --config ".swiftlint.yml .swiftlint_child.yml"

Nested Configurations

In addition to a main configuration (the .swiftlint.yml file in the root folder), you can put other configuration files named .swiftlint.yml into the directory structure that then get merged as a child config, but only with an effect for those files that are within the same directory as the config or in a deeper directory where there isn't another configuration file. In other words: Nested configurations don't work recursively – there's a maximum number of one nested configuration per file that may be applied in addition to the main configuration.

.swiftlint.yml files are only considered as a nested configuration if they have not been used to build the main configuration already (e. g. by having been referenced via something like child_config: Folder/.swiftlint.yml). Also, parent_config / child_config specifications of nested configurations are getting ignored because there's no sense to that.

If one (or more) SwiftLint file(s) are explicitly specified via the --config parameter, that configuration will be treated as an override, no matter whether there exist other .swiftlint.yml files somewhere within the directory. So if you want to use use nested configurations, you can't use the -- config parameter.

License

MIT licensed.

About

SwiftLint is maintained and funded by Realm Inc. The names and logos for Realm are trademarks of Realm Inc.

We ❤️ open source software! See our other open source projects, read our blog, or say hi on twitter (@realm).

Our thanks to MacStadium for providing a Mac Mini to run our performance tests.

Comments
  • Adding --strict does not log or display linter violations as errors

    Adding --strict does not log or display linter violations as errors

    It seems that the purpose of the --strict flag in SwiftLint is to display or log linter violations as errors. I'd like to use that functionality but I am still seeing everything that has a .Warning level of severity displayed in Xcode or logged on the command line as a warning.

    I have attempted to add this flag to a script which runs linting on certain project files, and also to linting on the command line.

    In our build script I've tried:

    • swiftlint lint --config "${SRCROOT}/.swiftlint.yml" --path $file --strict
    • swiftlint lint --strict --config "${SRCROOT}/.swiftlint.yml" --path $file
    • swiftlint lint --config "${SRCROOT}/.swiftlint.yml" --path $file --strict 1
    • swiftlint lint --strict 1 --config "${SRCROOT}/.swiftlint.yml" --path $file

    file is a variable in our build script.

    On the command line I've tried the same thing, but without a reference to any particular file, and with different file path specification syntax, since I don't believe SRCROOT works correctly there.

    The build script displays these violations as warnings and the command on the command line prints "warning........" for each violation.

    Has anyone else seen this issue?

    Thanks!

    question 
    opened by tamarnachmany 46
  • Support for passing multiple paths to swiftlint lint and autocorrect

    Support for passing multiple paths to swiftlint lint and autocorrect

    This implements #810:

    TODO:

    • [x] What does rootPath mean now (especially in terms of caching) when multiple files are passed? (disabled with a warning)
    • [x] Okay to get drop the --path option? (decided to keep)
    • [x] Add tests. (filed CLI arg testing follow up ticket #1213)
    • [x] Add CHANGELOG entry.

    This + pre-commit/pre-commit#467 (personal motivation for this PR) + hooks.yaml (maybe in a follow up PR) makes this work with pre-commit using SwiftPM. I've tested this branch locally with pre-commit, and it works great!

    I'd appreciate thoughts and feedback on the above TODOs and existing changes :)

    opened by benasher44 40
  • Enforce explicit self

    Enforce explicit self

    Due to the Swift evolution proposal 009 being rejected, but still having a pretty big following, I think it'd be very valuable for certain teams to be able to enforce explicit self (like in Objective-C). Here's the reasoning for not changing the language from the core team and here's the proposal itself, where you can find reasons why the proposed change makes sense for some teams.

    The gist of the decision was that explicit self makes sense for a certain group of people and those should use a lint tool (suggested by the core Swift team) instead of the language being changed. Thus I think SwiftLint supporting this rule would help it to be used by all those devs.

    rule-request 
    opened by czechboy0 38
  • Investigate cases in which cache is stale

    Investigate cases in which cache is stale

    We have just updated to 0.16 in our codebase and I'm working through the new rules. First up it's sorted_imports. For this, we have a build phase which runs ${PODS_ROOT}/SwiftLint/swiftlint as per the guidelines in the README file. I've worked through part of our codebase (it takes a while as we have well over a hundred thousand lines of Swift code) and sorted the imports. I then re-ran the linter, to clear out the issues I'd already fixed and make it easier to keep track of my progress.

    At this point, the linter reported the remaining issues, but also reported several files I'd already fixed as having the issue. Manual inspection confirmed that the imports had already been sorted correctly.

    I ignored the issue for the time being and continued through the real issues, eventually reaching the end. Rerunning left only the false positives. No matter how many times I re-ran the linter, it would keep these false positives.

    However, changing our script in the build phase to ${PODS_ROOT}/SwiftLint/swiftlint line --no-cache resulted in the linter finding lots of files I hadn't got to, and removed all the false positives.

    I have no idea what's going on behind the scenes, but the new cache added in 0.16 seems to be broken.

    bug 
    opened by ghost 33
  • Add support for merging nested configuration with parent configurations

    Add support for merging nested configuration with parent configurations

    Continued from @stephanecopin's work in #1674. Depends on #1686.

    @stephanecopin I've given you commit access to SwiftLint so that you can continue iterating on this PR directly on this git remote.

    opened by jpsim 32
  • Swiftlint 0.39 library not loaded

    Swiftlint 0.39 library not loaded

    New Issue Checklist

    Describe the bug

    swiftlint always crashes after updating to version 0.39 via Homebrew. We've tried this on 3 systems and seen the same issue.

    We have tried installing "Swift 5 Runtime Support for Command Line Tools" as per the known issues but the systems are too new to allow this to be installed.

    We have downgraded to 0.38.2 which is working fine.

    Complete output when running SwiftLint, including the stack trace and command used
    $ swiftlint lint
    dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib
      Referenced from: /usr/local/bin/swiftlint
      Reason: image not found
    Abort trap: 6
    

    Environment

    • SwiftLint version: 0.39

    • macOS versions: 10.15.3 && 10.14.6

    • Installation method used: Homebrew

    • Are you using nested configurations? If so, paste their relative paths and respective contents.

    • Which Xcode version are you using: 11.3

    • Do you have a sample that shows the issue? Run `swiftlint"

    bug 
    opened by Oliver-Kirkland-Evoke 31
  • Dictionary Parameterization of rules

    Dictionary Parameterization of rules

    Dictionary Parameterization

    Closes #303

    Here is my idea on how to implement dictionary parameterization for rules. Sorry it is such a beast of a change (and hard to review), but it was necessary IMO to accomplish the task. There are some pretty big changes in here, so I understand if we need to refine this further or even reject this course.

    Merge Notes

    I merged my recursive configuration branch into this branch before it was integrated into master. In addition to that I have merged master several times to keep up with the other changes. Somehow this resulted in the recursive config commits being duplicated, though the diff's still look correct. This could be a result of the combination of how I merged and the cherry picking that was done to do the final integration.

    Overview

    This was my thought process as I developed this:

    • With the increased complexity in rule configuration, it didn't make sense to have Configuration store the knowledge on how to configure each rule anymore. This should be encapsulated in the Rule itself.

    • A new protocol, ConfigurableRule, was created to facilitate this.

    • When encapsulating the configuration in ConfigurableRule, I didn't want to create a dependency on Yaml, I chose instead for ConfigurableRule to have a failable initializer taking an AnyObject instead. AnyObject was chosen over the alternative, [String: AnyObject], to support the trivial config cases (e.g. line_length: 100).

    • I wrote Yaml extensions to flatten the Yaml.Dictionarys into [String: AnyObject]s

    • I then refactored Configuration to extract Yaml parsing to YamlParser

    • I also didn't think it made sense anymore to have Configuration store the master rule list, so I extracted this to the global masterRuleList using a rather trivial RuleList container I created.

    • I wrote protocol extensions for ParameterizedRule to make all legacy parameterized rules automatically conform to ConfigurableRule

    • Configuration now constructs it's rule array by iterating through a RuleList (defaulting to masterRuleList). If a rule is a ConfigurableRule and a configuration exists for this rule, the rule will be instantiated by passing it's configuration to init?(config:). If this fails, the rule is not a ConfigurableRule, or a configuration does not exist, the Rule is instantiated by calling it's default init.

    • I added the init() requirement to the Rule protocol to support the initialization of Rules with their default values.

    • I added the trivial case init() { } to all non-ConfigurableRules to support this.

    • I wrote unit tests for most of the above.

    • I adapted VariableNameMinLengthRule as an example of how to create a ConfigurableRule. The new implementation supports the same syntax as before, but now also supports configuration via warning and error parameters as well as a new excluded array parameter to exclude certain variable names from the check (e.g. id). Closes #231.

      variable_name_min_length:
        warning: 3
        error: 4
        excluded:
          - id
      

    Thoughts

    • I'm not crazy about the AnyObject parameter for configuration. I feel like it's fighting the strong type system a bit. But on the other hand, it seems like a necessary evil to support the use cases we would like. Also, this follows in the well-tread footsteps of serializing objects, and it makes it relatively easy to support any serialization technique for configurations (e.g. json, xml, or plist). The plist option is particularly nice because it would support a tighter integration of SwiftLint into Xcode.
    • Because we store Rules in a [Rule] for Configuration and I needed to implement equality testing (isEqualTo and Equatable) for Configuration to support unit tests, I needed a way of dealing with two ConfigurableRules being compared while being downcasted to Rules. This result in a somewhat ugly change to the implementation of Rule.isEqualTo that tests for upcasting to ConfigurableRules. This feels like fighting the type system, but I couldn't come up with a way around it. However, this is now a potential trap if more rule protocols are added.
    • There appears to be some sort of bug in how SwiftXPC overrides comparing two [String]s that results in two empty [String]s not being equal. I had to therefore test for equality in a different way in VariableNameMinLengthRule.
    • This is a beginning, but we can further this work by writing additional protocols and methods to support common configuration schemes to ease new ConfigurableRule creation. We can also further restrict configuration to remove the AnyObject requirement or create a new type to facilitate this.
    • Another project I have contributed to, ObjectMapper, can potentially be used to add some nice syntactical sugar to the syntax of ConfigurableRules.
    • I originally wrote the Yaml flattening as extensions, but it might make more sense to put those in YamlParser.
    opened by scottrhoyt 31
  • Baseline

    Baseline

    Adding a baseline mechanism similar to the one implemented for Android Lint described here: https://developer.android.com/studio/write/lint#snapshot

    To use the mechanism add --use-baseline flag when using the lint command. If there is no baseline file it will create .swiftlint_baseline file that's going to contain all violations reported by lint command. Calling lint with --use-baseline flag next time will only report new violations that are not present in the .swiftlint_baseline file.

    opened by polszacki-tooploox 29
  • ⚠️ WIP - Native plugins support

    ⚠️ WIP - Native plugins support

    Into

    This feature came to be as a possible solution to our need to run GraphQL queries validation against scheme allowing queries to be an organic part of the .swift source file and an external file. We wanted it to be part of the build process. All these factors made swiftlint an ideal candidate. However builtin rule system while powerful doesn't allow for code execution allow us to achieve it. As a potential use case, I can see external plugins for spell checking of strings and comments that would allow swiftlint autocorrect to automatically fix spelling mistakes as a part of the build process etc. Also it would open door to adhoc, domain specific and niche rules without need to contribute it back to swiftlint.

    Plugins infrastructure

    Plugin is a bundle with a principle class conforming to the Rule type. For now it has to be class and not a struct for the runtime to be able to address it. I used NSBundle infrastructure to load external code. Plugin should be linked against SwiftLintFramework to be able to address appropriate types which might be the problem if the framework is being updated and plugin is not. I'd like to hear your opinion on this one. This PR comes with a sample rule that compiles into .plugin bundle and can be referenced when running rules, autocorrect and lint commands by adding flag --plugins ~/swiftlint/plugins/PuppetPlugin.plugin. This plugin doesn't do match, it allows to specify whether it should fail and what is the severity of the failure. I used it as an example and for integration tests.

    Integration tests

    Since plugin infrastructure is a layer I added mostly on top of the command line app and not the framework I found that it is not that easy to test the app itself (or rather I couldn't find an easy way). I decided to go with a completely opaque approach of launching swiftlint binary that can be found in the tests bundle folder. But if you think it's better to test the swiftlint.app I'm open to suggestions.

    Open issues

    As you can see, PuppetPlugin is configured not to include swift libraries relying on the swiftlint use the same version of swift. Result of running plugin that uses different version of Swift against swiftlint is undefined, and, to be honest is not quite clear to me.

    While I understand this feature might not be something authors of the library planned for, I think that added value can enrich the capabilities of swiftlint with features that might be beyond traditional scope of linting. I'd appreciate your feedback on this.

    opened by zats 29
  • File Types Order & Type Contents Order

    File Types Order & Type Contents Order

    This fixes #2294 by introducing two new rules:

    • file_types_order: Specifies how the types within a file should be ordered.
    • type_contents_order: Specifies the order of subtypes, properties, methods & more within a type.
    opened by Jeehut 27
  • Segmentation fault on trailing_comma with Swift 2.3

    Segmentation fault on trailing_comma with Swift 2.3

    Currently exiting with code 139 on lint.

    2016-12-01 22:06:49.888 swiftlint[87645:2364960] *** -[__NSCFString substringWithRange:]: Range {2127, 18446744073709551614} out of bounds; string length 3640. This will become an exception for apps linked after 10.10 and iOS 8. Warning shown once per app execution.
    
    bug 
    opened by csjones 27
  • no_magic_numbers false positive for enum cases with a negative value

    no_magic_numbers false positive for enum cases with a negative value

    New Issue Checklist

    Describe the bug

    Negative numbers (except for -1) will trigger the no_magic_numbers - e.g. case negative = -2. Equivalent positive numbers (e.g. 2) are fine.

    Complete output when running SwiftLint, including the stack trace and command used
    swiftlint lint Example.swift --enable-all-rules
    Linting Swift files at paths Example.swift
    Linting 'Example.swift' (1/1)
    The `anyobject_protocol` rule is now deprecated and will be completely removed in a future release.
    ./Example.swift:3:22: warning: No Magic Numbers Violation: Magic numbers should be replaced by named constants. (no_magic_numbers)
    Done linting! Found 1 violation, 0 serious in 1 file.
    

    Environment

    • SwiftLint version (run swiftlint version to be sure)? 0.50.3

    • Installation method used (Homebrew, CocoaPods, building from source, etc)? Portable

    • Paste your configuration file: None

    • Are you using nested configurations? No

    • Which Xcode version are you using (check xcodebuild -version)? 14.2

    • Do you have a sample that shows the issue?echo "internal enum Example {\n case positive = 2\n case negative = -2\n}" | swiftlint lint --no-cache --use-stdin --enable-all-rules

    enum Example: Int {
        case positive = 2
        case negative = -2
    }
    
    opened by stephengurnett 0
  • Add Command Plugins

    Add Command Plugins

    Motivation

    SwiftLint already has a Build Tool Plugin in place. However, with the Build Tool Plugin, the files in the package cannot be modified, nor can they be executed at any given time. For this reason I have implemented the Command Plugin.

    References

    • https://github.com/apple/swift-evolution/blob/c42a47e9e631a5cc8cf89567f3bfa799d0dc5011/proposals/0332-swiftpm-command-plugins.md#example-2-formatting-source-code
    • https://github.com/apple/swift-format/pull/449
    • https://github.com/nicklockwood/SwiftFormat/pull/1297
    • https://github.com/apple/swift-docc-plugin
    • #4176
    opened by uhooi 1
  •  Object does not exist on the server in CircleCI

    Object does not exist on the server in CircleCI

    Using latest version from > 0.50.0 I got this error in CircleCI.

    Downloading Pods/SwiftLint/swiftlint (29 MB)MiB | 1.74 MiB/s
    Error downloading object: Pods/SwiftLint/swiftlint (a1eaf42): Smudge error: Error downloading Pods/SwiftLint/swiftlint (a1eaf42bc959a146ba1bb8c378b7eba3ed18b2d62b83acbff01c0c57bd48b8bb): [a1eaf42bc959a146ba1bb8c378b7eba3ed18b2d62b83acbff01c0c57bd48b8bb] Object does not exist on the server: [404] Object does not exist on the server

    Errors logged to '/Users/distiller/project/.git/lfs/logs/20230104T131701.16992.log'. Use git lfs logs last to view the log. error: external filter 'git-lfs filter-process' failed fatal: Pods/SwiftLint/swiftlint: smudge filter lfs failed

    exit status 128 CircleCI received exit code 128

    opened by rarias84 0
  • Rule Request: no_constant_condition

    Rule Request: no_constant_condition

    New Issue Checklist

    New rule request

    1. Why should this rule be added? Share links to existing discussion about what the community thinks about this.

    Conditional branches where the condition constantly evaluates to true or false are useless because only one branch is executed always or never.

    1. Provide several examples of what would and wouldn't trigger violations.

    Violating Examples

    if true {
        print("foo")
    }
    
    if false {
        print("foo")
    }
    
    if x && false {
        print("foo")
    }
    
    if x || true {
        print("foo")
    }
    
    switch "b" {
    case "a":
        print("foo")
    case "c":
        print("bar")
    default:
        break
    }
    

    Non-Violating Examples

    if x {
        print("foo")
    }
    
    switch x {
    case "a":
        print("foo")
    case "c":
        print("bar")
    default:
        break
    }
    
    1. Should the rule be configurable, if so what parameters should be configurable?

    This rule doesn’t need to be configurable.

    1. Should the rule be opt-in or enabled by default? Why? See README.md for guidelines on when to mark a rule as opt-in.

    I think this rule would be a good candidate for the default rules since it points out a possible programming error.

    rule-request 
    opened by lo1tuma 1
  • Rule Request: prefer_else_if

    Rule Request: prefer_else_if

    New Issue Checklist

    New rule request

    1. Why should this rule be added? Share links to existing discussion about what the community thinks about this.

    When an else branch has only one child statement which is either an if or if-else statement, this could be refactored to an else-if statement.

    1. Provide several examples of what would and wouldn't trigger violations.

    Violating Examples:

    if foo {
      bar()
    } else {
      if baz {
        qux()
      }
    }
    
    if foo {
      bar()
    } else {
      if baz {
        qux()
      } else {
        quux()
      }
    }
    

    Non-Violating Examples:

    if foo {
      bar()
    } else {
      if baz {
        qux()
      }
      somethingElse()
    }
    
    if foo {
      bar()
    } else if baz {
      qux()
    }
    
    if foo {
      bar()
    } else if {
      qux()
    } else {
      quux()
    }
    
    1. Should the rule be configurable, if so what parameters should be configurable?

    This rule doesn’t need to be configurable.

    1. Should the rule be opt-in or enabled by default? Why? See README.md for guidelines on when to mark a rule as opt-in.

    I think this should be an opt-in rule, because it is more like a stylistic rule to recommends to avoid unnecessary nesting.

    rule-request 
    opened by lo1tuma 0
  • Rule Request: no_duplicated_condition

    Rule Request: no_duplicated_condition

    New Issue Checklist

    New rule request

    1. Why should this rule be added?

    This rule should flag conditions that are used multiple times in the same branching statement like if-else-if or switch statement.

    1. Provide several examples of what would and wouldn't trigger violations.

    Violating Examples

    if x < 5 {
      foo()
    } else if x < 2 {
      bar()
    } else if x < 5 { // duplicated condition
      baz()
    }
    
    switch x {
    case "a":
      foo()
    case "a" // duplicated condition
      bar()
    }
    

    Non-Violating Examples

    if x < 5 {
      foo()
      baz()
    } else if x < 2 {
      bar()
    }
    
    switch x {
    case "a":
      foo()
      bar()
    }
    
    1. Should the rule be configurable, if so what parameters should be configurable?

    This rule doesn’t need to be configurable.

    1. Should the rule be opt-in or enabled by default? Why? See README.md for guidelines on when to mark a rule as opt-in.

    This would be a good candidate for a builtin rule as it points out bad structured code.

    good first issue rule-request 
    opened by lo1tuma 0
Releases(0.50.3)
  • 0.50.3(Dec 9, 2022)

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • The SwiftLintPlugin SwiftPM plugin now uses a prebuilt binary on macOS.
      Tony Arnold JP Simard #4558

    • Don't trigger shorthand_operator violations inside a shorthand operator function declaration.
      Marcelo Fabri #4611

    • The balanced_xctest_lifecycle, single_test_class, empty_xctest_method and test_case_accessibility rules will now be applied to subclasses of QuickSpec, as well as XCTestCase, by default.
      Martin Redington

    • Add test_parent_classes option to balanced_xctest_lifecycle, single_test_class and empty_xctest_method rules.
      Martin Redington #4200

    • Show warnings in the console for Analyzer rules that are listed in the opt_in_rules configuration section.
      SimplyDanny #4612

    Bug Fixes

    • Fix configuration parsing error in unused_declaration rule.
      SimplyDanny #4612

    • Skip defer statements being last in an #if block if the #if statement is not itself the last statement in a block.
      SimplyDanny #4615

    • Fix false positives in empty_enum_arguments when the called expression is an identifier or an init call.
      Steffen Matthischke #4597

    • Fix correction issue in comma when there was too much whitespace following the comma.
      JP Simard


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "b8c4d765bcd8b533fcc2e15f32482a1a17572f143b65af388f7d5ac99994a99a",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.3/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run -c opt @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(392.60 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(8.63 MB)
    SwiftLint.pkg(8.63 MB)
    SwiftLintBinary-macos.artifactbundle.zip(8.63 MB)
    swiftlint_linux.zip(33.70 MB)
  • 0.50.1(Nov 25, 2022)

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • Moved the validation of doc comments in local scopes out of orphaned_doc_comment and into a new opt-in local_doc_comment rule.
      JP Simard #4573

    • SwiftLint's Swift Package Build Tool Plugin will now only scan files in the target being built.
      Tony Arnold #4406

    Bug Fixes

    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(392.96 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(8.64 MB)
    SwiftLint.pkg(8.65 MB)
    SwiftLintBinary-macos.artifactbundle.zip(8.64 MB)
    swiftlint_linux.zip(33.69 MB)
  • 0.50.0(Nov 18, 2022)

    Breaking

    • SwiftLint now requires Swift 5.7 or higher to build.
      JP Simard

    • Exclude weak_delegate rule from autocorrection due to behavioral changes leading to potential undefined behavior or bugs.
      SimplyDanny #3577

    • The anyobject_protocol rule is now deprecated and will be completely removed in a future release because it is now handled by the Swift compiler.
      JP Simard

    • Built-in SwiftLint rules are no longer marked as public in SwiftLintFramework. This only impacts the programmatic API for the SwiftLintFramework module.
      JP Simard

    Experimental

    • None.

    Enhancements

    • SwiftSyntax libraries have been updated from the previous 5.6 release and now use the new parser written in Swift. Swift 5.7+ features should now be parsed more accurately. We've also measured an improvement in lint times of up to 15%. This should also fix some deployment issues where the exact version of the internal SwiftSyntax parser needed to be available. If you notice any unexpected changes to lint results, please file an issue on the SwiftLint issue tracker. We can look into it and if it's a SwiftSyntax parser regression we can re-file it upstream.
      JP Simard #4031

    • Rewrite some rules with SwiftSyntax, fixing some false positives and catching more violations:

      • anonymous_argument_in_multiline_closure
      • array_init
      • attributes
      • balanced_xctest_lifecycle
      • block_based_kvo
      • class_delegate_protocol
      • closing_brace
      • closure_body_length
      • closure_parameter_position
      • collection_alignment
      • comment_spacing
      • computed_accessors_order
      • conditional_returns_on_newline
      • contains_over_filter_count
      • contains_over_filter_is_empty
      • contains_over_first_not_nil
      • contains_over_range_nil_comparison
      • convenience_type
      • deployment_target
      • discarded_notification_center_observer
      • discouraged_assert
      • discouraged_direct_init
      • discouraged_none_name
      • discouraged_object_literal
      • discouraged_optional_boolean
      • duplicate_enum_cases
      • duplicated_key_in_dictionary_literal
      • dynamic_inline
      • empty_collection_literal
      • empty_count
      • empty_enum_arguments
      • empty_parameters
      • empty_parentheses_with_trailing_closure
      • empty_string
      • enum_case_associated_values_count
      • explicit_enum_raw_value
      • explicit_init
      • explicit_top_level_acl
      • fallthrough
      • file_name
      • first_where
      • flatmap_over_map_reduce
      • for_where
      • force_try
      • force_unwrapping
      • function_body_length
      • function_default_parameter_at_end
      • function_parameter_count
      • generic_type_name
      • ibinspectable_in_extension
      • identical_operands
      • implicit_getter
      • implicitly_unwrapped_optional
      • inclusive_language
      • inert_defer
      • is_disjoint
      • joined_default_parameter
      • large_tuple
      • last_where
      • legacy_cggeometry_functions
      • legacy_constant
      • legacy_constructor
      • legacy_hashing
      • legacy_multiple
      • legacy_nsgeometry_functions
      • legacy_objc_type
      • legacy_random
      • lower_acl_than_parent
      • multiline_arguments_brackets
      • multiline_parameters
      • multiple_closures_with_trailing_closure
      • no_extension_access_modifier
      • no_fallthrough_only
      • no_space_in_method_call
      • notification_center_detachment
      • nslocalizedstring_key
      • nslocalizedstring_require_bundle
      • nsobject_prefer_isequal
      • number_separator
      • object_literal
      • operator_whitespace
      • optional_enum_case_matching
      • orphaned_doc_comment
      • overridden_super_call
      • override_in_extension
      • pattern_matching_keywords
      • prefer_nimble
      • prefer_self_in_static_references
      • prefer_self_type_over_type_of_self
      • prefer_zero_over_explicit_init
      • prefixed_toplevel_constant
      • private_action
      • private_outlet
      • private_over_fileprivate
      • private_subject
      • private_unit_test
      • prohibited_interface_builder
      • prohibited_super_call
      • protocol_property_accessors_order
      • quick_discouraged_focused_test
      • quick_discouraged_pending_test
      • raw_value_for_camel_cased_codable_enum
      • reduce_boolean
      • reduce_into
      • redundant_discardable_let
      • redundant_nil_coalescing
      • redundant_objc_attribute
      • redundant_optional_initialization
      • redundant_set_access_control
      • redundant_string_enum_value
      • required_deinit
      • required_enum_case
      • return_arrow_whitespace
      • self_in_property_initialization
      • shorthand_operator
      • single_test_class
      • sorted_first_last
      • static_operator
      • strict_fileprivate
      • strong_iboutlet
      • switch_case_alignment
      • switch_case_on_newline
      • test_case_accessibility
      • toggle_bool
      • trailing_comma
      • trailing_semicolon
      • type_body_length
      • type_name
      • unneeded_break_in_switch
      • unneeded_parentheses_in_closure_argument
      • unowned_variable_capture
      • untyped_error_in_catch
      • unused_capture_list
      • unused_closure_parameter
      • unused_control_flow_label
      • unused_enumerated
      • unused_optional_binding
      • unused_setter_value
      • valid_ibinspectable
      • vertical_parameter_alignment
      • weak_delegate
      • xct_specific_matcher
      • xctfail_message
        Marcelo Fabri SimplyDanny JP Simard #2915
    • The "body length" family of rules have changed how they calculate body line count to be significantly more correct and intuitive. However, this is likely to require adjustments to your configuration or disable commands to account for the changes.
      JP Simard

    • Add ability to filter rules for generate-docs subcommand.
      kattouf

    • Add new excludes_trivial_init configuration for missing_docs rule to exclude initializers without any parameters.
      Marcelo Fabri #4107

    • Add new ns_number_init_as_function_reference rule to catch NSNumber.init and NSDecimalNumber.init being used as function references since it can cause the wrong initializer to be used, causing crashes. See https://github.com/apple/swift/issues/51036 for more info.
      Marcelo Fabri

    • Add accessibility_trait_for_button rule to warn if a SwiftUI View has a tap gesture added to it without having the button or link accessibility trait.
      Ryan Cole

    • Add methods from SE-0348 to UnusedDeclarationRule.
      JP Simard

    • Include the configured bind_identifier in self_binding violation messages.
      JP Simard

    • The self_binding rule now catches shorthand optional bindings (for example if let self {}) when using a bind_identifier different than self.
      Marcelo Fabri

    • Add library_content_provider file type to file_types_order rule to allow LibraryContentProvider to be ordered independent from main_type.
      dahlborn

    • Add test_parent_classes option to test_case_accessibility rule, which allows detection in subclasses of XCTestCase.
      Martin Redington #4200

    • Add a new shorthand_optional_binding opt-in rule that triggers in Swift 5.7 when a shadowing optional binding is created in an if or guard statement.
      SimplyDanny #4202

    • Use SwiftSyntax instead of SourceKit to determine if a file has parser errors before applying corrections. This speeds up corrections significantly when none of the rules use SourceKit.
      JP Simard

    • Add Swift Package Build Tool Plugin with support for Swift Packages and Xcode projects.
      Johannes Ebeling #3679 #3840

    • Make private_unit_test rule correctable.
      SimplyDanny

    • Disregard whitespace differences in identical_operands rule. That is, the rule now also triggers if the left-hand side and the right-hand side of an operation only differ in trivia.
      SimplyDanny

    • Print violations in realtime if --progress and --output are both set.
      JP Simard

    • Trigger prefer_self_in_static_references rule on more type references like:

      • Key paths (e.g. \MyType.myVar -> \Self.myVar)
      • Computed properties (e.g. var i: Int { MyType.myVar ) -> var i: Int { Self.myVar })
      • Constructor calls (e.g. MyType() -> Self())

      SimplyDanny

    • Update for_where rule, adding a new configuration allow_for_as_filter to allow using for in with a single if inside when there's a return statement inside the if's body.
      Marcelo Fabri #4040

    • quick_discouraged_call, quick_discouraged_focused_test and quick_discouraged_pending_test rules now trigger on subclasses of QuickSpec. Marcelo Fabri #4420

    • The type_name rule now validates protocol declarations by default. You can opt-out by using the validate_protocols key in your configuration:

      type_name:
        validate_protocols: false
      

      Marcelo Fabri #4430

    • Report how much memory was used when --benchmark is specified.
      JP Simard

    • Adds NSError to the list of types in discouraged_direct_init.
      jszumski #4508

    • Fix SwiftLint support on Xcode Cloud.
      JagCesar westerlund #4484

    • Add no_magic_numbers rule to avoid "Magic Numbers".
      Henrik Storch #4031

    • Add new option only_enforce_before_trivial_lines to vertical_whitespace_closing_braces rule. It restricts the rule to apply only before trivial lines (containing only closing braces, brackets and parentheses). This allows empty lines before non-trivial lines of code (e.g. if-else-statements).
      benjamin-kramer #3940

    Bug Fixes

    • Respect validates_start_with_lowercase option when linting function names.
      Chris Brakebill #2708

    • Do not report variables annotated with @NSApplicationDelegateAdaptor and @WKExtensionDelegateAdaptor in weak_delegate rule.
      Till Hainbach #3598 #3611

    • Fix false-positives related to the willMove lifecycle method in type_contents_order rule.
      SimplyDanny #3478

    • Do no longer autocorrect usage of NSIntersectionRect in legacy_nsgeometry_functions rule.
      SimplyDanny #3703

    • Fix Analyzer rules in Xcode 14.
      SimplyDanny #4208

    • Add column for SourceKit usage to rules command.
      JP Simard

    • Make nsobject_prefer_isequal rule work for nested @objc classes. Also consider the @objcMembers annotation.
      SimplyDanny

    • Print fixed content at most once to STDOUT.
      SimplyDanny #4211

    • Fix fatal error when content given via STDIN is corrected in the trailing_newline rule.
      SimplyDanny #4234

    • Fix false-positives from multiline_arguments_brackets when a function call has a single line trailing closure.
      CraigSiemens #4510


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "c99be76ea5efd6ff7e60b6df8a11b709d50c75dfdbd6fb429de9bbe9e45cdb1f",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.0/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(389.30 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(8.66 MB)
    SwiftLint.pkg(8.67 MB)
    SwiftLintBinary-macos.artifactbundle.zip(8.66 MB)
    swiftlint_linux.zip(33.65 MB)
  • 0.50.0-rc.4(Nov 4, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.50.0-rc.4 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.50.0-rc.4
    • Bazel: See instructions at the bottom

    Changes from 0.49.1: https://github.com/realm/SwiftLint/compare/0.49.1...0.50.0-rc.4 Changes from 0.50.0-rc.3: https://github.com/realm/SwiftLint/compare/0.50.0-rc.3...0.50.0-rc.4


    Breaking

    • SwiftLint now requires Swift 5.7 or higher to build.
      JP Simard

    • Exclude weak_delegate rule from autocorrection due to behavioral changes leading to potential undefined behavior or bugs.
      SimplyDanny #3577

    • The anyobject_protocol rule is now deprecated and will be completely removed in a future release because it is now handled by the Swift compiler.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Adds NSError to the list of types in discouraged_direct_init.
      jszumski #4508

    • Fix SwiftLint support on Xcode Cloud.
      JagCesar westerlund #4484

    • Add no_magic_numbers rule to avoid "Magic Numbers".
      Henrik Storch #4031

    • SwiftSyntax libraries have been updated from the previous 5.6 release and now use the new parser written in Swift. Swift 5.7+ features should now be parsed more accurately. We've also measured an improvement in lint times of up to 15%. This should also fix some deployment issues where the exact version of the internal SwiftSyntax parser needed to be available. If you notice any unexpected changes to lint results, please file an issue on the SwiftLint issue tracker. We can look into it and if it's a SwiftSyntax parser regression we can re-file it upstream.
      JP Simard #4031

    • Add ability to filter rules for generate-docs subcommand.
      kattouf

    • Add new excludes_trivial_init configuration for missing_docs rule to exclude initializers without any parameters.
      Marcelo Fabri #4107

    • Add new ns_number_init_as_function_reference rule to catch NSNumber.init and NSDecimalNumber.init being used as function references since it can cause the wrong initializer to be used, causing crashes. See https://github.com/apple/swift/issues/51036 for more info.
      Marcelo Fabri

    • Rewrite some rules with SwiftSyntax, fixing some false positives and catching more violations:

      • anonymous_argument_in_multiline_closure
      • array_init
      • attributes
      • block_based_kvo
      • class_delegate_protocol
      • closing_brace
      • closure_body_length
      • closure_parameter_position
      • collection_alignment
      • comment_spacing
      • computed_accessors_order
      • conditional_returns_on_newline
      • contains_over_filter_count
      • contains_over_filter_is_empty
      • contains_over_first_not_nil
      • contains_over_range_nil_comparison
      • convenience_type
      • deployment_target
      • discarded_notification_center_observer
      • discouraged_assert
      • discouraged_direct_init
      • discouraged_none_name
      • discouraged_object_literal
      • discouraged_optional_boolean
      • duplicate_enum_cases
      • duplicated_key_in_dictionary_literal
      • dynamic_inline
      • empty_collection_literal
      • empty_count
      • empty_enum_arguments
      • empty_parameters
      • empty_parentheses_with_trailing_closure
      • empty_string
      • enum_case_associated_values_count
      • explicit_enum_raw_value
      • explicit_init
      • explicit_top_level_acl
      • fallthrough
      • file_name
      • first_where
      • flatmap_over_map_reduce
      • for_where
      • force_try
      • force_unwrapping
      • function_body_length
      • function_default_parameter_at_end
      • function_parameter_count
      • generic_type_name
      • ibinspectable_in_extension
      • identical_operands
      • implicit_getter
      • implicitly_unwrapped_optional
      • inclusive_language
      • inert_defer
      • is_disjoint
      • joined_default_parameter
      • large_tuple
      • last_where
      • legacy_cggeometry_functions
      • legacy_constant
      • legacy_constructor
      • legacy_hashing
      • legacy_multiple
      • legacy_nsgeometry_functions
      • legacy_objc_type
      • legacy_random
      • lower_acl_than_parent
      • multiline_arguments_brackets
      • multiline_parameters
      • multiple_closures_with_trailing_closure
      • no_extension_access_modifier
      • no_fallthrough_only
      • no_space_in_method_call
      • notification_center_detachment
      • nslocalizedstring_require_bundle
      • nsobject_prefer_isequal
      • number_separator
      • operator_whitespace
      • optional_enum_case_matching
      • orphaned_doc_comment
      • overridden_super_call
      • override_in_extension
      • prefer_nimble
      • prefer_self_type_over_type_of_self
      • prefer_zero_over_explicit_init
      • prefixed_toplevel_constant
      • private_action
      • private_outlet
      • private_over_fileprivate
      • private_subject
      • private_unit_test
      • prohibited_interface_builder
      • prohibited_super_call
      • protocol_property_accessors_order
      • quick_discouraged_focused_test
      • quick_discouraged_pending_test
      • raw_value_for_camel_cased_codable_enum
      • reduce_boolean
      • reduce_into
      • redundant_discardable_let
      • redundant_nil_coalescing
      • redundant_objc_attribute
      • redundant_optional_initialization
      • redundant_set_access_control
      • redundant_string_enum_value
      • required_deinit
      • return_arrow_whitespace
      • self_in_property_initialization
      • shorthand_operator
      • single_test_class
      • sorted_first_last
      • static_operator
      • strict_fileprivate
      • strong_iboutlet
      • switch_case_alignment
      • switch_case_on_newline
      • test_case_accessibility
      • toggle_bool
      • trailing_comma
      • trailing_semicolon
      • type_body_length
      • type_name
      • unneeded_break_in_switch
      • unneeded_parentheses_in_closure_argument
      • unowned_variable_capture
      • untyped_error_in_catch
      • unused_capture_list
      • unused_closure_parameter
      • unused_control_flow_label
      • unused_enumerated
      • unused_optional_binding
      • unused_setter_value
      • valid_ibinspectable
      • vertical_parameter_alignment
      • weak_delegate
      • xct_specific_matcher
      • xctfail_message
        Marcelo Fabri SimplyDanny JP Simard #2915
    • The "body length" family of rules have changed how they calculate body line count to be significantly more correct and intuitive. However, this is likely to require adjustments to your configuration or disable commands to account for the changes.
      JP Simard

    • Add accessibility_trait_for_button rule to warn if a SwiftUI View has a tap gesture added to it without having the button or link accessibility trait.
      Ryan Cole

    • Add methods from SE-0348 to UnusedDeclarationRule.
      JP Simard

    • Include the configured bind_identifier in self_binding violation messages.
      JP Simard

    • Add library_content_provider file type to file_types_order rule to allow LibraryContentProvider to be ordered independent from main_type.
      dahlborn

    • Add test_parent_classes option to test_case_accessibility rule, which allows detection in subclasses of XCTestCase.
      Martin Redington #4200

    • Add a new shorthand_optional_binding opt-in rule that triggers in Swift 5.7 when a shadowing optional binding is created in an if or guard statement.
      SimplyDanny #4202

    • Use SwiftSyntax instead of SourceKit to determine if a file has parser errors before applying corrections. This speeds up corrections significantly when none of the rules use SourceKit.
      JP Simard

    • Add Swift Package Build Tool Plugin with support for Swift Packages and Xcode projects.
      Johannes Ebeling #3679 #3840

    • Make private_unit_test rule correctable.
      SimplyDanny

    • Disregard whitespace differences in identical_operands rule. That is, the rule now also triggers if the left-hand side and the right-hand side of an operation only differ in trivia.
      SimplyDanny

    • Print violations in realtime if --progress and --output are both set.
      JP Simard

    • Update for_where rule, adding a new configuration allow_for_as_filter to allow using for in with a single if inside when there's a return statement inside the if's body.
      Marcelo Fabri #4040

    • quick_discouraged_call, quick_discouraged_focused_test and quick_discouraged_pending_test rules now trigger on subclasses of QuickSpec. Marcelo Fabri #4420

    • The type_name rule now validates protocol declarations by default. You can opt-out by using the validate_protocols key in your configuration:

      type_name:
        validate_protocols: false
      

      Marcelo Fabri #4430

    • Report how much memory was used when --benchmark is specified.
      JP Simard

    Bug Fixes

    • Respect validates_start_with_lowercase option when linting function names.
      Chris Brakebill #2708

    • Do not report variables annotated with @NSApplicationDelegateAdaptor and @WKExtensionDelegateAdaptor in weak_delegate rule.
      Till Hainbach #3598 #3611

    • Fix false-positives related to the willMove lifecycle method in type_contents_order rule.
      SimplyDanny #3478

    • Do no longer autocorrect usage of NSIntersectionRect in legacy_nsgeometry_functions rule.
      SimplyDanny #3703

    • Fix Analyzer rules in Xcode 14.
      SimplyDanny #4208

    • Add column for SourceKit usage to rules command.
      JP Simard

    • Make nsobject_prefer_isequal rule work for nested @objc classes. Also consider the @objcMembers annotation.
      SimplyDanny

    • Print fixed content at most once to STDOUT.
      SimplyDanny #4211

    • Fix fatal error when content given via STDIN is corrected in the trailing_newline rule.
      SimplyDanny #4234

    • Fix false-positives from multiline_arguments_brackets when a function call has a single line trailing closure.
      CraigSiemens #4510


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "90e3b5e8ff942be134e64a83499974203ea64797fd620eddeb71b3a8e1bff681",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.2/rules_apple.1.1.2.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "ef49a8c0dcb70fb5befe549b016735deef72e1ac9f68562b288f23e496c164af",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.0-rc.4/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(399.27 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(8.85 MB)
    SwiftLint.pkg(8.87 MB)
    SwiftLintBinary-macos.artifactbundle.zip(8.86 MB)
    swiftlint_linux.zip(33.85 MB)
  • 0.50.0-rc.3(Oct 27, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.50.0-rc.3 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.50.0-rc.3
    • Bazel: See instructions at the bottom

    Changes from 0.49.1: https://github.com/realm/SwiftLint/compare/0.49.1...0.50.0-rc.3 Changes from 0.50.0-rc.2: https://github.com/realm/SwiftLint/compare/0.50.0-rc.2...0.50.0-rc.3


    Breaking

    • SwiftLint now requires Swift 5.7 or higher to build.
      JP Simard

    • Exclude weak_delegate rule from autocorrection due to behavioral changes leading to potential undefined behavior or bugs.
      SimplyDanny #3577

    • The anyobject_protocol rule is now deprecated and will be completely removed in a future release because it is now handled by the Swift compiler.
      JP Simard

    Experimental

    • None.

    Enhancements

    • SwiftSyntax libraries have been updated from the previous 5.6 release and now use the new parser written in Swift. Swift 5.7+ features should now be parsed more accurately. We've also measured an improvement in lint times of up to 15%. This should also fix some deployment issues where the exact version of the internal SwiftSyntax parser needed to be available. If you notice any unexpected changes to lint results, please file an issue on the SwiftLint issue tracker. We can look into it and if it's a SwiftSyntax parser regression we can re-file it upstream.
      JP Simard #4031

    • Add ability to filter rules for generate-docs subcommand.
      kattouf

    • Add new excludes_trivial_init configuration for missing_docs rule to exclude initializers without any parameters.
      Marcelo Fabri #4107

    • Add new ns_number_init_as_function_reference rule to catch NSNumber.init and NSDecimalNumber.init being used as function references since it can cause the wrong initializer to be used, causing crashes. See https://github.com/apple/swift/issues/51036 for more info.
      Marcelo Fabri

    • Rewrite some rules with SwiftSyntax, fixing some false positives and catching more violations:

      • anonymous_argument_in_multiline_closure
      • array_init
      • attributes
      • block_based_kvo
      • class_delegate_protocol
      • closing_brace
      • closure_body_length
      • closure_parameter_position
      • collection_alignment
      • comment_spacing
      • computed_accessors_order
      • conditional_returns_on_newline
      • contains_over_filter_count
      • contains_over_filter_is_empty
      • contains_over_first_not_nil
      • contains_over_range_nil_comparison
      • convenience_type
      • deployment_target
      • discarded_notification_center_observer
      • discouraged_assert
      • discouraged_direct_init
      • discouraged_none_name
      • discouraged_object_literal
      • discouraged_optional_boolean
      • duplicate_enum_cases
      • duplicated_key_in_dictionary_literal
      • dynamic_inline
      • empty_collection_literal
      • empty_count
      • empty_enum_arguments
      • empty_parameters
      • empty_parentheses_with_trailing_closure
      • empty_string
      • enum_case_associated_values_count
      • explicit_enum_raw_value
      • explicit_init
      • explicit_top_level_acl
      • fallthrough
      • file_name
      • first_where
      • flatmap_over_map_reduce
      • for_where
      • force_try
      • force_unwrapping
      • function_body_length
      • function_default_parameter_at_end
      • function_parameter_count
      • generic_type_name
      • ibinspectable_in_extension
      • identical_operands
      • implicit_getter
      • implicitly_unwrapped_optional
      • inclusive_language
      • inert_defer
      • is_disjoint
      • joined_default_parameter
      • large_tuple
      • last_where
      • legacy_cggeometry_functions
      • legacy_constant
      • legacy_constructor
      • legacy_hashing
      • legacy_multiple
      • legacy_nsgeometry_functions
      • legacy_objc_type
      • legacy_random
      • lower_acl_than_parent
      • multiple_closures_with_trailing_closure
      • multiline_parameters
      • no_extension_access_modifier
      • no_fallthrough_only
      • no_space_in_method_call
      • notification_center_detachment
      • nslocalizedstring_require_bundle
      • nsobject_prefer_isequal
      • number_separator
      • operator_whitespace
      • override_in_extension
      • nsobject_prefer_isequal
      • prefer_nimble
      • prefer_self_type_over_type_of_self
      • prefer_zero_over_explicit_init
      • prefixed_toplevel_constant
      • private_action
      • private_over_fileprivate
      • private_outlet
      • private_unit_test
      • prohibited_interface_builder
      • protocol_property_accessors_order
      • quick_discouraged_focused_test
      • quick_discouraged_pending_test
      • raw_value_for_camel_cased_codable_enum
      • reduce_boolean
      • reduce_into
      • redundant_discardable_let
      • redundant_nil_coalescing
      • redundant_objc_attribute
      • redundant_set_access_control
      • redundant_optional_initialization
      • redundant_string_enum_value
      • required_deinit
      • return_arrow_whitespace
      • self_in_property_initialization
      • shorthand_operator
      • single_test_class
      • sorted_first_last
      • static_operator
      • strict_fileprivate
      • strong_iboutlet
      • switch_case_alignment
      • switch_case_on_newline
      • test_case_accessibility
      • toggle_bool
      • trailing_comma
      • trailing_semicolon
      • type_body_length
      • type_name
      • unneeded_break_in_switch
      • unneeded_parentheses_in_closure_argument
      • unowned_variable_capture
      • untyped_error_in_catch
      • unused_capture_list
      • unused_closure_parameter
      • unused_control_flow_label
      • unused_enumerated
      • unused_optional_binding
      • unused_setter_value
      • valid_ibinspectable
      • vertical_parameter_alignment
      • weak_delegate
      • xct_specific_matcher
      • xctfail_message
        Marcelo Fabri SimplyDanny JP Simard #2915
    • The "body length" family of rules have changed how they calculate body line count to be significantly more correct and intuitive. However, this is likely to require adjustments to your configuration or disable commands to account for the changes.
      JP Simard

    • Add accessibility_trait_for_button rule to warn if a SwiftUI View has a tap gesture added to it without having the button or link accessibility trait.
      Ryan Cole

    • Add methods from SE-0348 to UnusedDeclarationRule.
      JP Simard

    • Include the configured bind_identifier in self_binding violation messages.
      JP Simard

    • Add library_content_provider file type to file_types_order rule to allow LibraryContentProvider to be ordered independent from main_type.
      dahlborn

    • Add test_parent_classes option to test_case_accessibility rule, which allows detection in subclasses of XCTestCase.
      Martin Redington #4200

    • Add a new shorthand_optional_binding opt-in rule that triggers in Swift 5.7 when a shadowing optional binding is created in an if or guard statement.
      SimplyDanny #4202

    • Use SwiftSyntax instead of SourceKit to determine if a file has parser errors before applying corrections. This speeds up corrections significantly when none of the rules use SourceKit.
      JP Simard

    • Add Swift Package Build Tool Plugin with support for Swift Packages and Xcode projects.
      Johannes Ebeling #3679 #3840

    • Make private_unit_test rule correctable.
      SimplyDanny

    • Disregard whitespace differences in identical_operands rule. That is, the rule now also triggers if the left-hand side and the right-hand side of an operation only differ in trivia.
      SimplyDanny

    • Print violations in realtime if --progress and --output are both set.
      JP Simard

    • Update for_where rule, adding a new configuration allow_for_as_filter to allow using for in with a single if inside when there's a return statement inside the if's body.
      Marcelo Fabri #4040

    • quick_discouraged_call, quick_discouraged_focused_test and quick_discouraged_pending_test rules now trigger on subclasses of QuickSpec. Marcelo Fabri #4420

    • The type_name rule now validates protocol declarations by default. You can opt-out by using the validate_protocols key in your configuration:

      type_name:
        validate_protocols: false
      

      Marcelo Fabri #4430

    • Report how much memory was used when --benchmark is specified.
      JP Simard

    Bug Fixes

    • Respect validates_start_with_lowercase option when linting function names.
      Chris Brakebill #2708

    • Do not report variables annotated with @NSApplicationDelegateAdaptor and @WKExtensionDelegateAdaptor in weak_delegate rule.
      Till Hainbach #3598 #3611

    • Fix false-positives related to the willMove lifecycle method in type_contents_order rule.
      SimplyDanny #3478

    • Do no longer autocorrect usage of NSIntersectionRect in legacy_nsgeometry_functions rule.
      SimplyDanny #3703

    • Fix Analyzer rules in Xcode 14.
      SimplyDanny #4208

    • Add column for SourceKit usage to rules command.
      JP Simard

    • Make nsobject_prefer_isequal rule work for nested @objc classes. Also consider the @objcMembers annotation.
      SimplyDanny

    • Print fixed content at most once to STDOUT.
      SimplyDanny #4211

    • Fix fatal error when content given via STDIN is corrected in the trailing_newline rule.
      SimplyDanny #4234


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "90e3b5e8ff942be134e64a83499974203ea64797fd620eddeb71b3a8e1bff681",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.2/rules_apple.1.1.2.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "0cc64b76c801242ba440f83a85d4d54aa11303f1f48094555ddc3a818fbc9858",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.0-rc.3/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(399.46 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(8.82 MB)
    SwiftLint.pkg(8.84 MB)
    SwiftLintBinary-macos.artifactbundle.zip(8.82 MB)
    swiftlint_linux.zip(33.67 MB)
  • 0.50.0-rc.2(Oct 17, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.50.0-rc.2 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.50.0-rc.2
    • Bazel: See instructions at the bottom

    Changes from 0.49.1: https://github.com/realm/SwiftLint/compare/0.49.1...0.50.0-rc.2 Changes from 0.50.0-rc.1: https://github.com/realm/SwiftLint/compare/0.50.0-rc.1...0.50.0-rc.2


    Breaking

    • SwiftLint now requires Swift 5.7 or higher to build.
      JP Simard

    • Exclude weak_delegate rule from autocorrection due to behavioral changes leading to potential undefined behavior or bugs.
      SimplyDanny #3577

    • The anyobject_protocol rule is now deprecated and will be completely removed in a future release because it is now handled by the Swift compiler.
      JP Simard

    Experimental

    • None.

    Enhancements

    • SwiftSyntax libraries have been updated from the previous 5.6 release and now use the new parser written in Swift. Swift 5.7+ features should now be parsed more accurately. We've also measured an improvement in lint times of up to 15%. This should also fix some deployment issues where the exact version of the internal SwiftSyntax parser needed to be available. If you notice any unexpected changes to lint results, please file an issue on the SwiftLint issue tracker. We can look into it and if it's a SwiftSyntax parser regression we can re-file it upstream.
      JP Simard #4031

    • Add ability to filter rules for generate-docs subcommand.
      kattouf

    • Add new excludes_trivial_init configuration for missing_docs rule to exclude initializers without any parameters.
      Marcelo Fabri #4107

    • Rewrite some rules with SwiftSyntax, fixing some false positives and catching more violations:

      • anonymous_argument_in_multiline_closure
      • array_init
      • attributes
      • block_based_kvo
      • class_delegate_protocol
      • closing_brace
      • closure_body_length
      • closure_parameter_position
      • computed_accessors_order
      • conditional_returns_on_newline
      • contains_over_filter_count
      • contains_over_filter_is_empty
      • contains_over_first_not_nil
      • contains_over_range_nil_comparison
      • deployment_target
      • discouraged_assert
      • discouraged_direct_init
      • discouraged_none_name
      • discouraged_object_literal
      • discouraged_optional_boolean
      • duplicate_enum_cases
      • dynamic_inline
      • empty_collection_literal
      • empty_enum_arguments
      • empty_parameters
      • empty_parentheses_with_trailing_closure
      • empty_string
      • enum_case_associated_values_count
      • explicit_enum_raw_value
      • explicit_init
      • fallthrough
      • first_where
      • flatmap_over_map_reduce
      • force_try
      • force_unwrapping
      • function_body_length
      • function_default_parameter_at_end
      • function_parameter_count
      • generic_type_name
      • ibinspectable_in_extension
      • identical_operands
      • implicit_getter
      • implicitly_unwrapped_optional
      • inert_defer
      • is_disjoint
      • large_tuple
      • last_where
      • legacy_cggeometry_functions
      • legacy_constant
      • legacy_constructor
      • legacy_hashing
      • legacy_multiple
      • legacy_nsgeometry_functions
      • legacy_random
      • multiple_closures_with_trailing_closure
      • no_extension_access_modifier
      • no_fallthrough_only
      • no_space_in_method_call
      • nslocalizedstring_require_bundle
      • nsobject_prefer_isequal
      • number_separator
      • operator_whitespace
      • nsobject_prefer_isequal
      • private_action
      • private_over_fileprivate
      • private_outlet
      • private_unit_test
      • prohibited_interface_builder
      • protocol_property_accessors_order
      • quick_discouraged_focused_test
      • quick_discouraged_pending_test
      • reduce_boolean
      • redundant_discardable_let
      • redundant_nil_coalescing
      • redundant_string_enum_value
      • self_in_property_initialization
      • shorthand_operator
      • sorted_first_last
      • static_operator
      • strict_fileprivate
      • strong_iboutlet
      • switch_case_alignment
      • switch_case_on_newline
      • toggle_bool
      • trailing_comma
      • trailing_semicolon
      • type_body_length
      • unneeded_break_in_switch
      • unneeded_parentheses_in_closure_argument
      • unowned_variable_capture
      • untyped_error_in_catch
      • unused_closure_parameter
      • unused_control_flow_label
      • unused_enumerated
      • unused_setter_value
      • valid_ibinspectable
      • weak_delegate
      • xctfail_message
        Marcelo Fabri SimplyDanny JP Simard #2915
    • The "body length" family of rules have changed how they calculate body line count to be significantly more correct and intuitive. However, this is likely to require adjustments to your configuration or disable commands to account for the changes.
      JP Simard

    • Add accessibility_trait_for_button rule to warn if a SwiftUI View has a tap gesture added to it without having the button or link accessibility trait.
      Ryan Cole

    • Add methods from SE-0348 to UnusedDeclarationRule.
      JP Simard

    • Include the configured bind_identifier in self_binding violation messages.
      JP Simard

    • Add library_content_provider file type to file_types_order rule to allow LibraryContentProvider to be ordered independent from main_type.
      dahlborn

    • Add test_parent_classes option to test_case_accessibility rule, which allows detection in subclasses of XCTestCase.
      Martin Redington #4200

    • Add a new shorthand_optional_binding opt-in rule that triggers in Swift 5.7 when a shadowing optional binding is created in an if or guard statement.
      SimplyDanny #4202

    • Use SwiftSyntax instead of SourceKit to determine if a file has parser errors before applying corrections. This speeds up corrections significantly when none of the rules use SourceKit.
      JP Simard

    • Add Swift Package Build Tool Plugin with support for Swift Packages and Xcode projects.
      Johannes Ebeling #3679 #3840

    • Make private_unit_test rule correctable.
      SimplyDanny

    • Disregard whitespace differences in identical_operands rule. That is, the rule now also triggers if the left-hand side and the right-hand side of an operation only differ in trivia.
      SimplyDanny

    • Print violations in realtime if --progress and --output are both set.
      JP Simard

    Bug Fixes

    • Respect validates_start_with_lowercase option when linting function names.
      Chris Brakebill #2708

    • Do not report variables annotated with @NSApplicationDelegateAdaptor and @WKExtensionDelegateAdaptor in weak_delegate rule.
      Till Hainbach #3598 #3611

    • Fix false-positives related to the willMove lifecycle method in type_contents_order rule.
      SimplyDanny #3478

    • Do no longer autocorrect usage of NSIntersectionRect in legacy_nsgeometry_functions rule.
      SimplyDanny #3703

    • Fix Analyzer rules in Xcode 14.
      SimplyDanny #4208

    • Add column for SourceKit usage to rules command.
      JP Simard

    • Make nsobject_prefer_isequal rule work for nested @objc classes. Also consider the @objcMembers annotation.
      SimplyDanny

    • Print fixed content at most once to STDOUT.
      SimplyDanny #4211

    • Fix fatal error when content given via STDIN is corrected in the trailing_newline rule.
      SimplyDanny #4234


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "90e3b5e8ff942be134e64a83499974203ea64797fd620eddeb71b3a8e1bff681",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.2/rules_apple.1.1.2.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "973587995aab45ac56b963c1768a830a6a66580ccea4d5bf81617106b22bfa3f",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.0-rc.2/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(394.58 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(11.33 MB)
    SwiftLint.pkg(11.34 MB)
    SwiftLintBinary-macos.artifactbundle.zip(11.33 MB)
    swiftlint_linux.zip(36.56 MB)
  • 0.50.0-rc.1(Oct 7, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.50.0-rc.1 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.50.0-rc.1
    • Bazel: See instructions at the bottom

    Changes from 0.49.1: https://github.com/realm/SwiftLint/compare/0.49.1...0.50.0-rc.1


    Breaking

    • SwiftLint now requires Swift 5.7 or higher to build.
      JP Simard

    • Exclude weak_delegate rule from autocorrection due to behavioral changes leading to potential undefined behavior or bugs.
      SimplyDanny #3577

    • The anyobject_protocol rule is now deprecated and will be completely removed in a future release because it is now handled by the Swift compiler.
      JP Simard

    Experimental

    • None.

    Enhancements

    • SwiftSyntax libraries have been updated from the previous 5.6 release and now use the new parser written in Swift. Swift 5.7+ features should now be parsed more accurately. We've also measured an improvement in lint times of up to 15%. This should also fix some deployment issues where the exact version of the internal SwiftSyntax parser needed to be available. If you notice any unexpected changes to lint results, please file an issue on the SwiftLint issue tracker. We can look into it and if it's a SwiftSyntax parser regression we can re-file it upstream.
      JP Simard #4031

    • Add ability to filter rules for generate-docs subcommand.
      kattouf

    • Add new excludes_trivial_init configuration for missing_docs rule to exclude initializers without any parameters.
      Marcelo Fabri #4107

    • Rewrite some rules with SwiftSyntax, fixing some false positives and catching more violations:

      • anonymous_argument_in_multiline_closure
      • array_init
      • block_based_kvo
      • class_delegate_protocol
      • closing_brace
      • closure_parameter_position
      • computed_accessors_order
      • contains_over_filter_count
      • contains_over_range_nil_comparison
      • deployment_target
      • discouraged_object_literal
      • discouraged_optional_boolean
      • duplicate_enum_cases
      • dynamic_inline
      • empty_collection_literal
      • empty_enum_arguments
      • empty_parameters
      • empty_parentheses_with_trailing_closure
      • empty_string
      • explicit_init
      • fallthrough
      • flatmap_over_map_reduce
      • force_try
      • force_unwrapping
      • generic_type_name
      • ibinspectable_in_extension
      • implicit_getter
      • inert_defer
      • large_tuple
      • legacy_cggeometry_functions
      • legacy_constant
      • legacy_nsgeometry_functions
      • multiple_closures_with_trailing_closure
      • no_extension_access_modifier
      • no_fallthrough_only
      • no_space_in_method_call
      • nsobject_prefer_isequal
      • private_action
      • private_outlet
      • private_unit_test
      • protocol_property_accessors_order
      • redundant_nil_coalescing
      • redundant_string_enum_value
      • strong_iboutlet
      • switch_case_on_newline
      • toggle_bool
      • trailing_semicolon
      • unneeded_break_in_switch
      • unneeded_parentheses_in_closure_argument
      • unowned_variable_capture
      • untyped_error_in_catch
      • xctfail_message
        Marcelo Fabri SimplyDanny JP Simard #2915
    • Add accessibility_trait_for_button rule to warn if a SwiftUI View has a tap gesture added to it without having the button or link accessibility trait.
      Ryan Cole

    • Add methods from SE-0348 to UnusedDeclarationRule.
      JP Simard

    • Include the configured bind_identifier in self_binding violation messages.
      JP Simard

    • Add library_content_provider file type to file_types_order rule to allow LibraryContentProvider to be ordered independent from main_type.
      dahlborn

    • Add test_parent_classes option to test_case_accessibility rule, which allows detection in subclasses of XCTestCase.
      Martin Redington #4200

    • Add a new if_let_shadowing opt-in rule that triggers in Swift 5.7 when a shadowing optional binding is created in an if- or guard-statement.
      SimplyDanny #4202

    • Use SwiftSyntax instead of SourceKit to determine if a file has parser errors before applying corrections. This speeds up corrections significantly when none of the rules use SourceKit.
      JP Simard

    • Add Swift Package Build Tool Plugin with support for Swift Packages and Xcode projects.
      Johannes Ebeling #3679 #3840

    • Make private_unit_test rule correctable.
      SimplyDanny

    Bug Fixes

    • Respect validates_start_with_lowercase option when linting function names.
      Chris Brakebill #2708

    • Do not report variables annotated with @NSApplicationDelegateAdaptor and @WKExtensionDelegateAdaptor in weak_delegate rule.
      Till Hainbach #3598 #3611

    • Fix false-positives related to the willMove lifecycle method in type_contents_order rule.
      SimplyDanny #3478

    • Do no longer autocorrect usage of NSIntersectionRect in legacy_nsgeometry_functions rule.
      SimplyDanny #3703

    • Fix Analyzer rules in Xcode 14.
      SimplyDanny #4208

    • Add column for SourceKit usage to rules command.
      JP Simard


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "90e3b5e8ff942be134e64a83499974203ea64797fd620eddeb71b3a8e1bff681",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.2/rules_apple.1.1.2.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "ee13554c48ca7845513ae307863525afbb5b8f22d4c3b34b5b2e87311c3d5e26",
        url = "https://github.com/realm/SwiftLint/releases/download/0.50.0-rc.1/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(391.83 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(11.15 MB)
    SwiftLint.pkg(11.16 MB)
    SwiftLintBinary-macos.artifactbundle.zip(11.15 MB)
    swiftlint_linux.zip(36.10 MB)
  • 0.49.1(Sep 1, 2022)

    Note: The default branch for the SwiftLint git repository was renamed from master to main on September 1st. Please update any code or automation accordingly.

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • Add new self_binding opt-in rule to enforce that self identifiers are consistently re-bound to a common identifier name. Configure bind_identifier to the name you want to use. Defaults to self.
      JP Simard #2495

    • Add --output option to lint and analyze commands to write to a file instead of to stdout.
      JP Simard #4048

    • Add --progress flag to lint and analyze commands to show a live-updating progress bar instead of each file being processed.
      JP Simard

    • --fix now works with --use-stdin, printing the output to to STDOUT instead of crashing.
      SimplyDanny #4127

    Bug Fixes

    • Migrate empty_xctest_method rule to SwiftSyntax fixing some false positives.
      SimplyDanny #3647 #3691

    • Fix false positives in redundant_discardable_let when using async let.
      Martin Hosna #4142

    • Consistently print error/info messages to stderr instead of stdout, which wasn't being done for errors regarding remote configurations.
      JP Simard


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "f003875c248544009c8e8ae03906bbdacb970bc3e5931b40cd76cadeded99632",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.0/rules_apple.1.1.0.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "7c454ff4abeeecdd9513f6293238a6d9f803b587eb93de147f9aa1be0d8337c4",
        url = "https://github.com/realm/SwiftLint/releases/download/0.49.1/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(383.18 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(20.87 MB)
    SwiftLint.pkg(20.87 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.87 MB)
    swiftlint_linux.zip(30.54 MB)
  • 0.49.0(Aug 26, 2022)

    Note: The default branch for the SwiftLint git repository will be renamed from master to main on September 1st. Please update any code or automation accordingly.

    Breaking

    • SwiftLint now requires Swift 5.6 or higher to build, and macOS 12 or higher to run.
      JP Simard

    • Code Climate reports now use SHA256 strings as the issue fingerprint values.
      JP Simard

    • Make comma_inheritance an opt-in rule.
      Steve Madsen #4027

    • The autocorrect command that was deprecated in 0.43.0 has now been completely removed. Use --fix instead.
      JP Simard

    • Remove the AutomaticTestableRule protocol. All examples listed in rules are now tested automatically to make sure they are correct.
      SimplyDanny

    • Deprecate the --in-process-sourcekit command line flag. SwiftLint now always uses an in-process SourceKit.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Make duplicate_imports rule correctable. Fix duplicate_imports rule reporting redundant violations when more than one duplicate is present.
      Timofey Solonin

    • Support for building SwiftLint with bazel.
      JP Simard

    • Support for writing custom private native rules when building with bazel.
      JP Simard Keith Smiley #3516

    • Make comma rule about 10x faster, finding some previously missed cases and fixing some previously wrong corrections.
      JP Simard

    • Make colon rule about 7x faster, finding some previously missed cases.
      JP Simard

    • Make closure_spacing rule about 9x faster, finding some previously missed cases and fixing some previously wrong corrections.
      JP Simard SimplyDanny #4090

    • Introduce new configuration option include_compiler_directives (true by default) for the indentation_width rule that allows to ignore compiler directives in the indentation analysis. This is especially useful if one (or a formatter) prefers to have compiler directives always at the very beginning of a line.
      SimplyDanny #4030

    • Enable (recursive) globs in included file paths.
      sarastro-nl

    • Custom rules are now broken down per rule instead of in aggregate in --benchmark.
      JP Simard

    • The version command now has an optional --verbose flag that prints out the full version info, notably the build ID, which can be used to determine if two swiftlint executables are identical.
      JP Simard

    • Update documentation for multiline_arguments_brackets and multiline_literal_brackets to make it immediately obvious that common examples will trigger.
      chrisjf #4060

    • The --compile-commands argument can now parse SwiftPM yaml files produced when running swift build at .build/{debug,release}.yaml.
      JP Simard

    • Add new configuration option allowed_no_space_operators to operator_usage_whitespace rule. It allows to specify custom operators which shall not be considered by the rule.
      imben123

    • Add new protocols to remove some boilerplate involved in writing SwiftSyntax-based rules.
      JP Simard

    Bug Fixes

    • Fix false positive in self_in_property_initialization rule when using closures inside didSet and other accessors.
      Marcelo Fabri #4041

    • Fix false positive in Duplicated Key in Dictionary Literal Violation rule when using keys that are generated at runtime with the same source code.
      OrEliyahu #4012

    • Fix false positive in yoda_condition rule by basing it on SwiftSyntax.
      SimplyDanny #4081

    • Fix false negatives in first_where rule when filtering array of dictionaries with String keys.
      KS1019

    • Fix broken correction for explicit_init rule.
      KS1019


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "f003875c248544009c8e8ae03906bbdacb970bc3e5931b40cd76cadeded99632",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.0/rules_apple.1.1.0.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "ec566314e9220ff681ddb639d3a0532834f66f7e733f5a59c7390469dcb5bd3e",
        url = "https://github.com/realm/SwiftLint/releases/download/0.49.0/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(376.91 KB)
    bazel.tar.gz.sha256(116 bytes)
    portable_swiftlint.zip(20.83 MB)
    SwiftLint.pkg(20.83 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.83 MB)
    swiftlint_linux.zip(30.48 MB)
  • 0.49.0-rc.2(Aug 18, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.49.0-rc.2 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.49.0-rc.2
    • Bazel: See instructions at the bottom

    Changes from 0.48.0: https://github.com/realm/SwiftLint/compare/0.48.0...0.49.0-rc.2 Changes from 0.49.0-rc.1: https://github.com/realm/SwiftLint/compare/0.49.0-rc.1...0.49.0-rc.2


    Note: The default branch for the SwiftLint git repository will be renamed from master to main on September 1st. Please update any code or automation accordingly.

    Breaking

    • SwiftLint now requires Swift 5.6 or higher to build, and macOS 12 or higher to run.
      JP Simard

    • Code Climate reports now use SHA256 strings as the issue fingerprint values.
      JP Simard

    • Make comma_inheritance an opt-in rule.
      Steve Madsen #4027

    • The autocorrect command that was deprecated in 0.43.0 has now been completely removed. Use --fix instead.
      JP Simard

    • Remove the AutomaticTestableRule protocol. All examples listed in rules are now tested automatically to make sure they are correct.
      SimplyDanny

    • Deprecate the --in-process-sourcekit command line flag. SwiftLint now always uses an in-process SourceKit.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Make duplicate_imports rule correctable. Fix duplicate_imports rule reporting redundant violations when more than one duplicate is present.
      Timofey Solonin

    • Support for building SwiftLint with bazel.
      JP Simard

    • Support for writing custom private native rules when building with bazel.
      JP Simard Keith Smiley #3516

    • Make comma rule about 10x faster, finding some previously missed cases and fixing some previously wrong corrections.
      JP Simard

    • Make colon rule about 7x faster, finding some previously missed cases.
      JP Simard

    • Make closure_spacing rule about 9x faster, finding some previously missed cases and fixing some previously wrong corrections.
      JP Simard SimplyDanny #4090

    • Introduce new configuration option include_compiler_directives (true by default) for the indentation_width rule that allows to ignore compiler directives in the indentation analysis. This is especially useful if one (or a formatter) prefers to have compiler directives always at the very beginning of a line.
      SimplyDanny #4030

    • Enable (recursive) globs in included file paths.
      sarastro-nl

    • Custom rules are now broken down per rule instead of in aggregate in --benchmark.
      JP Simard

    • The version command now has an optional --verbose flag that prints out the full version info, notably the build ID, which can be used to determine if two swiftlint executables are identical.
      JP Simard

    • Update documentation for multiline_arguments_brackets and multiline_literal_brackets to make it immediately obvious that common examples will trigger.
      chrisjf #4060

    Bug Fixes

    • Fix false positive in self_in_property_initialization rule when using closures inside didSet and other accessors.
      Marcelo Fabri #4041

    • Fix false positive in Duplicated Key in Dictionary Literal Violation rule when using keys that are generated at runtime with the same source code.
      OrEliyahu #4012

    • Fix false positive in yoda_condition rule by basing it on SwiftSyntax.
      SimplyDanny #4081

    • Fix false negatives in first_where rule when filtering array of dictionaries with String keys.
      KS1019

    • Fix broken correction for explicit_init rule.
      KS1019


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "36072d4f3614d309d6a703da0dfe48684ec4c65a89611aeb9590b45af7a3e592",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.0.1/rules_apple.1.0.1.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "d34bf123e6380a7527ee78c5f6ec7ede5e00e8c39a9c3b394f590374f566c57d",
        url = "https://github.com/realm/SwiftLint/releases/download/0.49.0-rc.2/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(368.25 KB)
    bazel.tar.gz.sha256(79 bytes)
    portable_swiftlint.zip(20.80 MB)
    SwiftLint.pkg(20.80 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.80 MB)
    swiftlint_linux.zip(30.43 MB)
  • 0.49.0-rc.1(Aug 12, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.49.0-rc.1 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.49.0-rc.1
    • Bazel: See instructions at the bottom

    Changes from 0.48.0: https://github.com/realm/SwiftLint/compare/0.48.0...0.49.0-rc.1


    Note: The default branch for the SwiftLint git repository will be renamed from master to main on September 1st. Please update any code or automation accordingly.

    Breaking

    • SwiftLint now requires Swift 5.6 or higher to build, and macOS 12 or higher to run.
      JP Simard

    • Code Climate reports now use SHA256 strings as the issue fingerprint values.
      JP Simard

    • Make comma_inheritance an opt-in rule.
      Steve Madsen #4027

    • The autocorrect command that was deprecated in 0.43.0 has now been completely removed. Use --fix instead.
      JP Simard

    • Remove the AutomaticTestableRule protocol. All examples listed in rules are now tested automatically to make sure they are correct.
      SimplyDanny

    • Deprecate the --in-process-sourcekit command line flag. SwiftLint now always uses an in-process SourceKit.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Make duplicate_imports rule correctable. Fix duplicate_imports rule reporting redundant violations when more than one duplicate is present.
      Timofey Solonin

    • Support for building SwiftLint with bazel.
      JP Simard

    • Support for writing custom private native rules when building with bazel.
      JP Simard Keith Smiley #3516

    • Make comma rule about 10x faster, finding some previously missed cases and fixing some previously wrong corrections.
      JP Simard

    • Make colon rule about 7x faster, finding some previously missed cases.
      JP Simard

    • Introduce new configuration option include_compiler_directives (true by default) for the indentation_width rule that allows to ignore compiler directives in the indentation analysis. This is especially useful if one (or a formatter) prefers to have compiler directives always at the very beginning of a line.
      SimplyDanny #4030

    Bug Fixes

    • Fix false positive in self_in_property_initialization rule when using closures inside didSet and other accessors.
      Marcelo Fabri #4041

    • Fix false positive in Duplicated Key in Dictionary Literal Violation rule when using keys that are generated at runtime with the same source code.
      OrEliyahu #4012


    Using Bazel

    Put this in your WORKSPACE:

    WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "build_bazel_rules_apple",
        sha256 = "36072d4f3614d309d6a703da0dfe48684ec4c65a89611aeb9590b45af7a3e592",
        url = "https://github.com/bazelbuild/rules_apple/releases/download/1.0.1/rules_apple.1.0.1.tar.gz",
    )
    
    load(
        "@build_bazel_rules_apple//apple:repositories.bzl",
        "apple_rules_dependencies",
    )
    
    apple_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:repositories.bzl",
        "swift_rules_dependencies",
    )
    
    swift_rules_dependencies()
    
    load(
        "@build_bazel_rules_swift//swift:extras.bzl",
        "swift_rules_extra_dependencies",
    )
    
    swift_rules_extra_dependencies()
    
    http_archive(
        name = "SwiftLint",
        sha256 = "e954f4483f7f4cf523896693ee3505585f6beb0f791e362b42d9bdbb615f051a",
        url = "https://github.com/realm/SwiftLint/releases/download/0.49.0-rc.1/bazel.tar.gz",
    )
    
    load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
    
    swiftlint_repos()
    
    load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
    
    swiftlint_deps()
    

    Then you can run SwiftLint in the current directory with this command:

    bazel run @SwiftLint//:swiftlint -- --help
    
    Source code(tar.gz)
    Source code(zip)
    bazel.tar.gz(366.63 KB)
    bazel.tar.gz.sha256(79 bytes)
    portable_swiftlint.zip(20.77 MB)
    SwiftLint.pkg(20.78 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.77 MB)
    swiftlint_linux.zip(30.40 MB)
  • 0.48.0(Jul 26, 2022)

    This is the last release to support building with Swift 5.5.x and running on macOS < 12.

    Breaking

    • Deprecate the --path options for lint/analyze commands. Prefer the positional paths that can be added last to both commands.
      SimplyDanny

    Experimental

    • None.

    Enhancements

    • Support iOSApplicationExtension, macOSApplicationExtension, watchOSApplicationExtension, and tvOSApplicationExtension identifiers in the deployment_target rule. To configure the rule for these identifiers, you need to use the keys iOSApplicationExtension_deployment_target, macOSApplicationExtension_deployment_target, watchOSApplicationExtension_deployment_target, and tvOSApplicationExtension_deployment_target. Extentions default to their counterparts unless they are explicitly defined.
      tahabebek #4004

    • Rewrite operator_usage_whitespace rule using SwiftSyntax, fixing false positives and false negatives.
      Note that this rule doesn't catch violations around return arrows (->) anymore - they are already handled by return_arrow_whitespace.
      Marcelo Fabri #3965 #3668 #2728

    • Support arrays for the included and excluded options when defining a custom rule.
      Marcelo Fabri

    • Add back void_function_in_ternary opt-in rule to warn against using a ternary operator to call Void functions.
      Marcelo Fabri

    • Support UIEdgeInsets type in prefer_zero_over_explicit_init rule.
      KokiHirokawa #3986

    Bug Fixes

    • Ignore array types in syntactic_sugar rule if their associated Index is accessed.
      SimplyDanny #3502

    • Prevent crash for private types named _ in type_name rules. sinoru #3971

    • Make for_where rule implementation independent of order in structure dictionary. This fixes the rule in Xcode 13.3 where some violation were no longer reported.
      SimplyDanny #3975

    • Update result builder methods in unused_declaration rule fixing some false-positives.
      SimplyDanny

    • Look for call expressions which are not wrapped into an argument when checking for nested (possibly multiline) arguments fixing some false-negatives in (at least) Xcode 13.2.
      SimplyDanny #3975

    • Make sure that include paths prefixed with the name of the original path are included in the analysis.
      SimplyDanny #3705

    • Do not trigger unavailable_condition rule if other #(un)available checks are involved.
      SimplyDanny #3985

    • Update nimble_operator to support the operators for beNil().
      CraigSiemens

    • Avoid false-positive in let_var_whitespace rule by allowing custom attributes on lines directly before let/var declarations.
      SimplyDanny #2980

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(20.68 MB)
    SwiftLint.pkg(20.69 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.68 MB)
    swiftlint_linux.zip(29.76 MB)
    swiftlint_linux_swift_5_5.zip(29.03 MB)
  • 0.47.1(Apr 25, 2022)

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • Add type-checked analyzer rule version of ArrayInitRule named TypesafeArrayInitRule with identifier typesafe_array_init that avoids the false positives present in the lint rule.
      SimplyDanny #3749

    • Add the --in-process-sourcekit command line flag to lint and analyze commands, which has the same effect as setting the IN_PROCESS_SOURCEKIT environment variable.
      Juozas Valancius

    • Add a new artifactbundle release asset containing swiftlint binaries for x86 & arm64 macOS.
      Juozas Valancius #3840

    • Add back return_value_from_void_function opt-in rule to warn against using return <expression> in a function that returns Void.
      Marcelo Fabri

    • Don't skip autocorrect on files that have parser warnings. Only files with errors reported by the Swift parser will be skipped.
      Marcelo Fabri #3343

    • Add accessibility_label_for_image rule to warn if a SwiftUI Image does not have an accessibility label and is not hidden from accessibility.
      Ryan Cole

    • Add unavailable_condition rule to prefer using if #unavailable instead of if #available with an empty body and an else condition when using Swift 5.6 or later.
      Marcelo Fabri #3897

    • Add comma_inheritance rule to validate that inheritance clauses use commas instead of &.
      Marcelo Fabri #3950

    Bug Fixes

    • Fix false positives in unused_closure_parameter when using parameters with backticks.
      JP Simard #3628

    • Improved the syntactic_sugar rule's detection accuracy and fixed some corrections leading to invalid code.
      Paul Taykalo #3866

    • Fix analyzer rules with Xcode 13.3 / Swift 5.6. Note that we've measured performance regressions compared to Swift 5.5 on the order of about 2x.
      JP Simard #3920

    • Error by default on bad expiring todo date formatting.
      Christopher Hale #3636

    • Lint/analyze all files listed in the command even if the --path option is used.
      coffmark

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(20.62 MB)
    SwiftLint.pkg(20.63 MB)
    SwiftLintBinary-macos.artifactbundle.zip(20.62 MB)
    swiftlint_linux.zip(29.68 MB)
    swiftlint_linux_swift_5_5.zip(28.94 MB)
  • 0.47.0(Mar 23, 2022)

    Breaking

    • SwiftLint now requires Swift 5.5 or higher to build.
      JP Simard

    • The SwiftLintFramework podspec has been removed. To our knowledge, this was completely unused by other projects and was not worth the complexity needed to justify its continued maintenance, especially in light of the integration of SwiftSyntax. The SwiftLint podspec is still supported.
      JP Simard

    • SwiftLint now requires at least Swift 5.0 installed in order to lint files.
      Marcelo Fabri

    Experimental

    • The force_cast rule and the comment command parsing mechanism have been updated to use SwiftSyntax instead of SourceKit. Please report any problems you encounter by opening a GitHub issue. If this is successful, more rules may use Swift Syntax in the future.
      JP Simard

    Enhancements

    • Empty files no longer trigger any violations.
      JP Simard #3854

    • Support recursive globs.
      funzin JP Simard #3789 #3891

    • The legacy_random rule is now enabled by default.
      Marcelo Fabri

    • The deployment_target rule now supports the #unavailable syntax added in Swift 5.6.
      Marcelo Fabri #3896

    • Set the IN_PROCESS_SOURCEKIT environment variable, which will use the in-process version of sourcekitd on macOS when Xcode 13 or later is selected. This avoids the use of XPC, which is prohibited in some sandboxed environments, such as in Swift Package Manager plugins.
      Juozas Valancius

    • Add ability to run only one (focused) example.
      PaulTaykalo #3911

    Bug Fixes

    • Extend class_delegate_protocol to correctly identify cases with the protocol body opening brace on a new line.
      Tobisaninfo

    • Fix SwiftLint.pkg installer installing multiple copies of SwiftLint.
      JP Simard #3815 #3887

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(20.54 MB)
    SwiftLint.pkg(20.55 MB)
    swiftlint_linux.zip(29.55 MB)
    swiftlint_linux_swift_5_5.zip(28.81 MB)
  • 0.47.0-rc.4(Mar 18, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.47.0-rc.4 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.47.0-rc.4

    Changes from 0.46.5: https://github.com/realm/SwiftLint/compare/0.46.5...0.47.0-rc.4 Changes from 0.47.0-rc.3: https://github.com/realm/SwiftLint/compare/0.47.0-rc.3...0.47.0-rc.4

    Breaking

    • SwiftLint now requires Swift 5.5 or higher to build.
      JP Simard

    • The SwiftLintFramework podspec has been removed. To our knowledge, this was completely unused by other projects and was not worth the complexity needed to justify its continued maintenance, especially in light of the integration of SwiftSyntax. The SwiftLint podspec is still supported.
      JP Simard

    • SwiftLint now requires at least Swift 5.0 installed in order to lint files.
      Marcelo Fabri

    Experimental

    • The force_cast rule and the comment command parsing mechanism have been updated to use SwiftSyntax instead of SourceKit. Please report any problems you encounter by opening a GitHub issue. If this is successful, more rules may use Swift Syntax in the future.
      JP Simard

    Enhancements

    • Empty files no longer trigger any violations.
      JP Simard #3854

    • Support recursive globs.
      funzin JP Simard #3789 #3891

    • The legacy_random rule is now enabled by default.
      Marcelo Fabri

    • The deployment_target rule now supports the #unavailable syntax added in Swift 5.6.
      Marcelo Fabri #3896

    • Set the IN_PROCESS_SOURCEKIT environment variable, which will use the in-process version of sourcekitd on macOS when Xcode 13 or later is selected. This avoids the use of XPC, which is prohibited in some sandboxed environments, such as in Swift Package Manager plugins.
      Juozas Valancius

    Bug Fixes

    • Extend class_delegate_protocol to correctly identify cases with the protocol body opening brace on a new line.
      Tobisaninfo

    • Fix SwiftLint.pkg installer installing multiple copies of SwiftLint.
      JP Simard #3815 #3887

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(24.14 MB)
    SwiftLint.pkg(24.14 MB)
    swiftlint_linux.zip(29.55 MB)
    swiftlint_linux_swift_5_5.zip(28.81 MB)
  • 0.47.0-rc.3(Mar 17, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.47.0-rc.3 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.47.0-rc.3

    Changes from 0.46.5: https://github.com/realm/SwiftLint/compare/0.46.5...0.47.0-rc.3 Changes from 0.47.0-rc.2: https://github.com/realm/SwiftLint/compare/0.47.0-rc.2...0.47.0-rc.3

    Breaking

    • SwiftLint now requires Swift 5.5 or higher to build.
      JP Simard

    • The SwiftLintFramework podspec has been removed. To our knowledge, this was completely unused by other projects and was not worth the complexity needed to justify its continued maintenance, especially in light of the integration of SwiftSyntax. The SwiftLint podspec is still supported.
      JP Simard

    • SwiftLint now requires at least Swift 5.0 installed in order to lint files.
      Marcelo Fabri

    Experimental

    • The force_cast rule and the comment command parsing mechanism have been updated to use SwiftSyntax instead of SourceKit. Please report any problems you encounter by opening a GitHub issue. If this is successful, more rules may use Swift Syntax in the future.
      JP Simard

    Enhancements

    • Empty files no longer trigger any violations.
      JP Simard #3854

    • Support recursive globs.
      funzin JP Simard #3789 #3891

    • The legacy_random rule is now enabled by default.
      Marcelo Fabri

    • The deployment_target rule now supports the #unavailable syntax added in Swift 5.6.
      Marcelo Fabri #3896

    • SwiftSyntax has been updated to its Swift 5.6 release and may improve parsing of Swift 5.6 code.
      JP Simard

    • Add IN_PROCESS_SOURCEKIT environment variable, which uses the in-process version of sourcekitd on macOS when Xcode 13 or later is selected. This avoids the use of XPC, which is prohibited in some sandboxed environments, such as in Swift Package Manager plugins.
      Juozas Valancius

    Bug Fixes

    • Extend class_delegate_protocol to correctly identify cases with the protocol body opening brace on a new line.
      Tobisaninfo

    • Fix SwiftLint.pkg installer installing multiple copies of SwiftLint.
      JP Simard #3815 #3887

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(24.14 MB)
    SwiftLint.pkg(24.14 MB)
    swiftlint_linux.zip(29.55 MB)
  • 0.47.0-rc.2(Mar 16, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.47.0-rc.2 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.47.0-rc.2

    Changes from 0.46.5: https://github.com/realm/SwiftLint/compare/0.46.5...0.47.0-rc.2 Changes from 0.47.0-rc.1: https://github.com/realm/SwiftLint/compare/0.47.0-rc.1...0.47.0-rc.2

    Breaking

    • SwiftLint now requires Swift 5.5 or higher to build.
      JP Simard

    • The SwiftLintFramework podspec has been removed. To our knowledge, this was completely unused by other projects and was not worth the complexity needed to justify its continued maintenance, especially in light of the integration of SwiftSyntax. The SwiftLint podspec is still supported.
      JP Simard

    • SwiftLint now requires at least Swift 5.0 installed in order to lint files.
      Marcelo Fabri

    Experimental

    • The force_cast rule and the comment command parsing mechanism have been updated to use SwiftSyntax instead of SourceKit. Please report any problems you encounter by opening a GitHub issue. If this is successful, more rules may use Swift Syntax in the future.
      JP Simard

    Enhancements

    • Empty files no longer trigger any violations.
      JP Simard #3854

    • Support recursive globs.
      funzin JP Simard #3789 #3891

    • The legacy_random rule is now enabled by default.
      Marcelo Fabri

    • The deployment_target rule now supports the #unavailable syntax added in Swift 5.6.
      Marcelo Fabri #3896

    • Add IN_PROCESS_SOURCEKIT environment variable, which uses the in-process version of sourcekitd on macOS when Xcode 13 or later is selected. This avoids the use of XPC, which is prohibited in some sandboxed environments, such as in Swift Package Manager plugins.
      Juozas Valancius

    Bug Fixes

    • Extend class_delegate_protocol to correctly identify cases with the protocol body opening brace on a new line.
      Tobisaninfo

    • Fix SwiftLint.pkg installer installing multiple copies of SwiftLint.
      JP Simard #3815 #3887

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(25.31 MB)
    SwiftLint.pkg(25.31 MB)
    swiftlint_linux.zip(28.81 MB)
  • 0.47.0-rc.1(Mar 9, 2022)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.47.0-rc.1 && make install
    • Docker: docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:0.47.0-rc.1

    Changes from 0.46.5: https://github.com/realm/SwiftLint/compare/0.46.5...0.47.0-rc.1

    Breaking

    • SwiftLint now requires Swift 5.5 or higher to build.
      JP Simard

    • The SwiftLintFramework podspec has been removed. To our knowledge, this was completely unused by other projects and was not worth the complexity needed to justify its continued maintenance, especially in light of the integration of SwiftSyntax. The SwiftLint podspec is still supported.
      JP Simard

    Experimental

    • The force_cast rule and the comment command parsing mechanism have been updated to use SwiftSyntax instead of SourceKit. Please report any problems you encounter by opening a GitHub issue. If this is successful, more rules may use Swift Syntax in the future.
      JP Simard
    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(25.32 MB)
    SwiftLint.pkg(25.32 MB)
    swiftlint_linux.zip(28.84 MB)
  • 0.46.5(Mar 8, 2022)

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • None.

    Bug Fixes

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.85 MB)
    SwiftLint.pkg(13.70 MB)
    swiftlint_linux.zip(25.06 MB)
  • 0.46.4(Mar 7, 2022)

  • 0.46.3(Feb 22, 2022)

  • 0.46.2(Jan 27, 2022)

  • 0.46.1(Jan 21, 2022)

    Breaking

    • The weak_delegate rule has been opt-in due to its high false positive rate.
      JP Simard #2786

    Experimental

    • None.

    Enhancements

    Bug Fixes

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.85 MB)
    SwiftLint.pkg(13.69 MB)
    swiftlint_linux.zip(24.99 MB)
  • 0.46.0(Jan 21, 2022)

    Breaking

    • The weak_delegate rule has been deprecated due to its high false positive rate. The identifier will become invalid in a future release.
      JP Simard #2786

    Experimental

    • None.

    Enhancements

    Bug Fixes

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.84 MB)
    SwiftLint.pkg(6.84 MB)
    swiftlint_linux.zip(24.98 MB)
  • 0.45.1(Nov 29, 2021)

    Breaking

    • None.

    Experimental

    • None.

    Enhancements

    • Update Rule list documentation to distinguish between opt-in and on-by-default rules.
      Benny Wong

    • Add opt-in prefer_self_in_static_references rule to warn if the type name is used to reference static members the same type. Prefer using Self instead which is not affected by renamings.
      SimplyDanny

    • Add support for running SwiftLint as a pre-commit hook.
      Jesse Crocker Hannes Ljungberg

    Bug Fixes

    • Fix unused_import rule incorrectly considering SwiftShims as a used import.
      JP Simard

    • Fix false positives on large_tuple rule when using async closures.
      Kaitlin Mahar #3753

    • Fix false positive on legacy_objc_type rule when using types with names that start with a legacy type name.
      Isaac Ressler #3555

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.84 MB)
    SwiftLint.pkg(6.84 MB)
    swiftlint_linux.zip(25.45 MB)
  • 0.45.0(Oct 18, 2021)

    Breaking

    • SwiftLint now requires Swift 5.4 or higher to build.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Add self_in_property_initialization rule to catch uses of self inside an inline closure used for initializing a variable. In this case, self refers to the NSObject.self method and likely won't be what you expect. You can make the variable lazy to be able to refer to the current instance with self or use MyClass.self if you really want to reference the method.
      Marcelo Fabri

    • Exclude id from identifier_name by default.
      Artem Garmash #3651

    • Handle get async and get throws (introduced in Swift 5.5) in the implicit_getter rule.
      Marcelo Fabri #3684

    • Speed up explicit type interface rule.
      PaulTaykalo #3745

    • Speed up analyzer rules.
      PaulTaykalo #3747

    Bug Fixes

    • Fix a bug with the missing_docs rule where excludes_inherited_types would not be set.
      Ben Fox

    • Fix redundant_optional_initialization autocorrect broken in case observer's brace exists. Naruki Chigira #3718

    • Fix a false positive in the unneeded_break_in_switch rule when using do/catch.
      Marcelo Fabri #3724

    • Speed up Computed Accessors Order rule. PaulTaykalo #3727

    • [Colon Rule] Fix case when comment is used in function call. PaulTaykalo #3740

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.82 MB)
    SwiftLint.pkg(6.81 MB)
    swiftlint_linux.zip(25.43 MB)
  • 0.44.0(Sep 9, 2021)

    Breaking

    • SwiftLint now requires Swift 5.3 or higher to build.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Add configuration options to missing_docs rule:

      • excludes_extensions defaults to true to skip reporting violations for extensions with missing documentation comments.
      • excludes_inherited_types defaults to true to skip reporting violations for inherited declarations, like subclass overrides.
        Ben Fox
    • Fix false negative on redundant_optional_initialization rule when variable has observers.
      Isaac Ressler #3621

    • Make test_case_accessibility rule identify invalid test functions with parameters.
      Keith Smiley #3612

    • Add duplicated_key_in_dictionary_literal rule to warn against duplicated keys in dictionary literals.
      Marcelo Fabri

    • Fix the rule name from "Colon" to "Colon Spacing" to improve phrasing.
      Radu #3587

    • Add discouraged_none_name opt-in rule to discourage naming cases and static/class members "none", which can conflict with Swift's Optional<T>.none when checking equality.
      Kane Cheshire #3624

    • Improve language and positioning of file_length warnings when ignore_comment_only_lines: true.
      Steven Grosmark #3654

    • Add anonymous_argument_in_multiline_closure opt-in rule to validate that named arguments are used in closures that span multiple lines.
      Marcelo Fabri

    Bug Fixes

    • Fix false positives in empty_enum_arguments rule when comparing values with a static member (e.g. if number == .zero).
      Marcelo Fabri #3562

    • Fix the regex for expiring-todos.
      namolnad #3597

    • Fix type_contents_order initializer detection.
      StevenMagdy

    • Fix autocorrect when there's no space between the tuple the in keyword on unneeded_parentheses_in_closure_argument rule.
      p-x9 #3633

    • Fix unused_capture_list, empty_enum_arguments, implicit_return and explicit_type_interface rules when using Swift 5.4.
      Marcelo Fabri #3615 #3685

    • Fix Xcode build logs with spaces in paths preventing analyze from running.
      adamawolf

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.65 MB)
    SwiftLint.pkg(6.64 MB)
    swiftlint_linux.zip(25.25 MB)
  • 0.43.1(Mar 15, 2021)

  • 0.43.0(Mar 3, 2021)

    Breaking

    • The command line syntax has slightly changed due to migrating from the Commandant command line parsing library to swift-argument-parser. For the most part the breaking changes are all to make the syntax more unix compliant and intuitive to use. For example, commands such as swiftlint --help or swiftlint -h now work as expected. The help output from various commands has greatly improved as well. Notably: swiftlint autocorrect was removed in favor of swiftlint --fix. Previous commands should continue to work temporarily to help with the transition. Please let us know if there's a command that no longer works and we'll attempt to add a bridge to help with its transition.
      JP Simard

    • Configuration files now consistently have their included/excluded relative file paths applied relative to their location in the file system. Previously the root configuration file applied these relative to the current working directory, but nested configurations applied these to their location in the file system.
      Frederick Pietschmann JP Simard

    • The discarded_notification_center_observer is now opt-in due to some difficult to resolve false positives, such as #3498.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Added allows_single_line option in multiline_parameters rule configuration. Defaults to true. This enforces parameters in a method with multiple parameters to always be in different lines.
      Otavio Cordeiro

    • Support relative paths in compilation databases for SwiftLint analyzer rules.
      JP Simard

    • Add opt-in rule discouraged_assert to encourage the use of assertionFailure() and/or preconditionFailure() over assert(false).
      Otavio Cordeiro

    • Adds balanced_xctest_lifecycle opt-in rule to enforce balanced setUp and tearDown methods in a test class.
      Otavio Cordeiro #3452

    • Tweak the auto-correction result console output for clarity.
      mokagio #3522

    • Allow configuring related USRs to skip in UnusedDeclarationRule by specifying a list of USRs in the related_usrs_to_skip key. For example you might have custom source tooling that does something with types conforming to a procotol even if that type is never explicitly referenced by other code.
      JP Simard

    • Make strong_iboutlet rule correctable.
      MaxHaertwig

    • Add legacy_objc_type opt-in rule to warn against using bridged Objective-C reference types instead of Swift value types.
      Blake #2758

    • Support Swift Playground control comments in the comment_spacing rule.
      Thomas Goyne

    • [Internal] Integrate OS Signposts to help profile SwiftLint performance.
      jpsim

    • Update CodeClimateReporter to produce relative paths.
      bmwalters

    • Add Bool violation reporting in redundant_type_annotation.
      Artem Garmash #3423

    • Add a new capture_variable analyzer rule to warn about listing a non-constant (var) variable in a closure's capture list. This captures the variable's value at closure creation time instead of closure call time, which may be unexpected.
      Laszlo Kustra

    • Log references to a specified module when running the unused_import by setting the SWIFTLINT_LOG_MODULE_USAGE=<module-name> environment variable when running analyze.
      jpsim

    • Add opt-in rule private_subject rule which warns against public Combine subjects.
      Otavio Cordeiro

    Bug Fixes

    • Fix custom_rules merging when the parent configuration is based on only_rules.
      Frederick Pietschmann #3468

    • Fix misleading warnings about rules defined in the custom_rules not being available (when using multiple configurations).
      Frederick Pietschmann #3472

    • Fix bug that prevented the reconfiguration of a custom rule in a child config.
      Frederick Pietschmann #3477

    • Fix typos in configuration options for file_name rule.
      advantis

    • Fix issue that prevented the inclusion of a configuration file from a parent folder.
      Frederick Pietschmann #3485

    • Fix violation location and misplaced corrections for some function references in explicit_self rule.
      JP Simard

    • Fix false positives with result builders in unused_declaration.
      JP Simard

    • Find more unused declarations in unused_declaration.
      JP Simard

    • Fix parsing xcode logs for analyzer rules for target names with spaces.
      JP Simard #3021

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.60 MB)
    SwiftLint.pkg(6.60 MB)
    swiftlint_linux.zip(25.17 MB)
  • 0.43.0-rc.4(Feb 26, 2021)

    This is a prerelease version. It won't be published to Homebrew or CocoaPods. But there are many other ways to install:

    • Downloading the attached SwiftLint.pkg installer and launching it
    • Downloading the attached portable_swiftlint.zip archive, extracting it and moving the binary from portable_swiftlint/swiftlint to /usr/local/bin or elsewhere in your PATH
    • Using Mint: mint install realm/[email protected]
    • Cloning and building from source: git clone https://github.com/realm/SwiftLint.git && cd SwiftLint && git checkout 0.43.0-rc.4 && make install

    Changes from 0.43.0-rc.3: https://github.com/realm/SwiftLint/compare/0.43.0-rc.3...0.43.0-rc.4

    Breaking

    • The command line syntax has slightly changed due to migrating from the Commandant command line parsing library to swift-argument-parser. For the most part the breaking changes are all to make the syntax more unix compliant and intuitive to use. For example, commands such as swiftlint --help or swiftlint -h now work as expected. The help output from various commands has greatly improved as well. Notably: swiftlint autocorrect was removed in favor of swiftlint --fix. Previous commands should continue to work temporarily to help with the transition. Please let us know if there's a command that no longer works and we'll attempt to add a bridge to help with its transition.
      JP Simard

    • Configuration files now consistently have their included/excluded relative file paths applied relative to their location in the file system. Previously the root configuration file applied these relative to the current working directory, but nested configurations applied these to their location in the file system.
      Frederick Pietschmann JP Simard

    • The discarded_notification_center_observer is now opt-in due to some difficult to resolve false positives, such as #3498.
      JP Simard

    Experimental

    • None.

    Enhancements

    • Added allows_single_line option in multiline_parameters rule configuration. Defaults to true. This enforces parameters in a method with multiple parameters to always be in different lines.
      Otavio Cordeiro

    • Support relative paths in compilation databases for SwiftLint analyzer rules.
      JP Simard

    • Add opt-in rule discouraged_assert to encourage the use of assertionFailure() and/or preconditionFailure() over assert(false).
      Otavio Cordeiro

    • Add opt-in rule private_subject rule which warns against public Combine subjects.
      Otavio Cordeiro

    • Tweak the auto-correction result console output for clarity.
      mokagio #3522

    • Allow configuring related USRs to skip in UnusedDeclarationRule by specifying a list of USRs in the related_usrs_to_skip key. For example you might have custom source tooling that does something with types conforming to a procotol even if that type is never explicitly referenced by other code.
      JP Simard

    • Make strong_iboutlet rule correctable.
      MaxHaertwig

    • Add legacy_objc_type opt-in rule to warn against using bridged Objective-C reference types instead of Swift value types.
      Blake #2758

    • Support Swift Playground control comments in the comment_spacing rule.
      Thomas Goyne

    • [Internal] Integrate OS Signposts to help profile SwiftLint performance.
      jpsim

    • Update CodeClimateReporter to produce relative paths.
      bmwalters

    • Add Bool violation reporting in redundant_type_annotation.
      Artem Garmash #3423

    • Log references to a specified module when running the unused_import by setting the SWIFTLINT_LOG_MODULE_USAGE=<module-name> environment variable when running analyze.
      jpsim

    Bug Fixes

    • Fix custom_rules merging when the parent configuration is based on only_rules.
      Frederick Pietschmann #3468

    • Fix misleading warnings about rules defined in the custom_rules not being available (when using multiple configurations).
      Frederick Pietschmann #3472

    • Fix bug that prevented the reconfiguration of a custom rule in a child config.
      Frederick Pietschmann #3477

    • Fix typos in configuration options for file_name rule.
      advantis

    • Fix issue that prevented the inclusion of a configuration file from a parent folder.
      Frederick Pietschmann #3485

    • Fix violation location and misplaced corrections for some function references in explicit_self rule.
      JP Simard

    • Fix false positives with result builders in unused_declaration.
      JP Simard

    Source code(tar.gz)
    Source code(zip)
    portable_swiftlint.zip(6.56 MB)
    SwiftLint.pkg(13.12 MB)
    swiftlint_linux.zip(25.12 MB)
Owner
Realm
Realm is a mobile database: a replacement for SQLite & ORMs. SDKs for Swift, Objective-C, Java, Kotlin, C#, and JavaScript.
Realm
A static source code analysis tool to improve quality and reduce defects for C, C++ and Objective-C

OCLint - https://oclint.org OCLint is a static code analysis tool for improving quality and reducing defects by inspecting C, C++ and Objective-C code

The OCLint Static Code Analysis Tool 3.6k Dec 29, 2022
A tool for Swift code modification intermediating between code generation and formatting.

swift-mod A tool for Swift code modification intermediating between code generation and formatting. Overview swift-mod is a tool for Swift code modifi

Ryo Aoyama 95 Nov 3, 2022
A command-line tool and Xcode Extension for formatting Swift code

Table of Contents What? Why? How? Command-line tool Xcode source editor extension Xcode build phase Via Applescript VSCode plugin Sublime Text plugin

Nick Lockwood 6.3k Jan 8, 2023
Simple iOS app blackbox assessment tool. Powered by frida.re and vuejs.

Discontinued Project This project has been discontinued. Please use the new Grapefruit #74 frida@14 compatibility issues frida@14 introduces lots of b

Chaitin Tech 1.6k Dec 16, 2022
A linter tool for Interface Builder

IBLinter A linter tool to normalize .xib and .storyboard files. Inspired by realm/SwiftLint Installation Using Homebrew $ brew install iblinter Using

IBDecodable 945 Nov 11, 2022
iOS tool that helps with profiling iOS Memory usage.

FBMemoryProfiler An iOS library providing developer tools for browsing objects in memory over time, using FBAllocationTracker and FBRetainCycleDetecto

Facebook Archive 3.4k Dec 7, 2022
Measure Swift code metrics and get reports in Xcode, Jenkins and other CI platforms.

Taylor ⚠️ Taylor is DEPRECATED. Use SwiftLint instead. A tool aimed to increase Swift code quality, by checking for conformance to code metrics. Taylo

YOPESO 301 Dec 24, 2022
SwiftCop is a validation library fully written in Swift and inspired by the clarity of Ruby On Rails Active Record validations.

SwiftCop is a validation library fully written in Swift and inspired by the clarity of Ruby On Rails Active Record validations. Objective Build a stan

Andres Canal 542 Sep 17, 2022
Cross-platform static analyzer and linter for Swift.

Wiki • Installation • Usage • Features • Developers • License Tailor is a cross-platform static analysis and lint tool for source code written in Appl

Sleekbyte 1.4k Dec 19, 2022
Type-safe observable values and collections in Swift

GlueKit ⚠️ WARNING ⚠️ This project is in a prerelease state. There is active work going on that will result in API changes that can/will break code wh

null 361 Oct 12, 2022
Trackable is a simple analytics integration helper library. It’s especially designed for easy and comfortable integration with existing projects.

Trackable Trackable is a simple analytics integration helper library. It’s especially designed for easy and comfortable integration with existing proj

Vojta Stavik 145 Apr 14, 2022
Makes it easier to support older versions of iOS by fixing things and adding missing methods

PSTModernizer PSTModernizer carefully applies patches to UIKit and related Apple frameworks to fix known radars with the least impact. The current set

PSPDFKit Labs 217 Aug 9, 2022
Find common xib and storyboard-related problems without running your app or writing unit tests.

IBAnalyzer Find common xib and storyboard-related problems without running your app or writing unit tests. Usage Pass a path to your project to ibanal

Arek Holko 955 Oct 15, 2022
Skredvarsel app - an iOS, iPadOS, and macOS application that provides daily avalanche warnings from the Norwegian Avalanche Warning Service API

Skredvarsel (Avalanche warning) app is an iOS, iPadOS, and macOS application that provides daily avalanche warnings from the Norwegian Avalanche Warning Service API

Jonas Follesø 8 Dec 15, 2022
Exclude files and folders from Alfred’s search results

Ignore in Alfred Alfred Workflow Exclude files and folders from Alfred’s search results ⤓ Download Workflow About The macOS metadata search API only a

Alfred 10 Dec 13, 2022
Lint anything by combining the power of Swift & regular expressions.

Installation • Getting Started • Configuration • Xcode Build Script • Donation • Issues • Regex Cheat Sheet • License AnyLint Lint any project in any

Flinesoft 116 Sep 24, 2022
An Xcode formatter plug-in to format your swift code.

Swimat Swimat is an Xcode plug-in to format your Swift code. Preview Installation There are three way to install. Install via homebrew-cask # Homebrew

Jintin 1.6k Jan 7, 2023
💊 Syntactic sugar for Swift do-try-catch

Fallback Syntactic sugar for Swift do-try-catch. At a Glance value = try fallback( try get("A"), try get("B"), try get("C"), try get("D") ) is

Suyeol Jeon 43 May 25, 2020
A Swift micro-framework to easily deal with weak references to self inside closures

WeakableSelf Context Closures are one of Swift must-have features, and Swift developers are aware of how tricky they can be when they capture the refe

Vincent Pradeilles 72 Sep 1, 2022