Skip to content

Releases: realm/SwiftLint

0.65.0: Fresh Folded Fixtures

Choose a tag to compare

@SimplyDanny SimplyDanny released this 27 Jun 07:43

Breaking

  • SwiftLint now requires Swift 6.1 or higher for development (to run tests). The
    executable can still be built with a Swift 6 compiler. The Swift Package Manager plugins
    continue to work with all versions down to Swift 5.9.
    SimplyDanny

Enhancements

  • SwiftLint now builds with Bazel versions 7 to 9.
    SimplyDanny

Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.65.0", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "d8c4add55c061a298a1913c654bda9e2c59b1af1bfb3bbba1195475e0676d9a0",
    url = "https://github.com/realm/SwiftLint/releases/download/0.65.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

0.64.1: All Windows Opened

Choose a tag to compare

@SimplyDanny SimplyDanny released this 23 Jun 06:31

Bug Fixes

  • Honor excluded paths when the linted project is located under a system directory
    on macOS that resolves through a symlink, such as /var and /tmp (which point
    to /private/var and /private/tmp).
    tumata
    #6782

0.64.0: All Windows Opened

Breaking

  • The ignored_literal_argument_functions option of the force_unwrapping rule now
    uses the configured value as-is instead of always merging in the five built-in defaults
    (URL(string:), NSURL(string:), UIImage(named:), NSImage(named:), Data(hexString:)).
    Those five functions remain the default when the option is not configured, but setting
    ignored_literal_argument_functions to any explicit list — including [] — now fully
    replaces the defaults. Configurations that add functions on top of the defaults must now
    explicitly include the five previously-default functions in their list.
    SimplyDanny
    #6675

Enhancements

  • SwiftLint can now be built and run on Windows. It is expected to work in the same way as
    on other platforms. The only restrictions are missing support for ?[] glob patterns in
    include/exclude patterns and the requirement for \n as line ending in all linted files.
    compnerd
    roman-bcny
    SimplyDanny
    #6351
    #6352

  • Rename allow_implicit_init to include_implicit_init for the
    optional_data_string_conversion rule to convey its purpose more clearly.
    SimplyDanny
    #6670

  • Improve linting performance by 10-15%, especially when running with many
    threads, by optimizing cache locking and reducing contention. Depending on
    the project and level of concurrency, the performance improvement can be even
    higher (3-4x).
    SimplyDanny

  • Rewrite the following rules with SwiftSyntax:

    • file_types_order

    SimplyDanny

  • Fix false positive in accessibility_label_for_image rule for images inside
    SwiftUI Label's icon: closure, which are inherently labeled by the
    Label's text content.
    sutheesh
    #6420

Bug Fixes

  • Fix literal_expression_end_indentation autocorrection deleting source code
    when the closing bracket of a multiline literal shares a line with the end of
    a multiline last element (e.g. ...))]). The corrector assumed everything
    before the bracket on that line was indentation and replaced it; it now moves
    only the bracket to its own line at the expected indentation.
    Luan Câmara
    #2823

  • Don't rewrite the type operand of an is / as? / as! cast (such as
    x is A) to Self in prefer_self_in_static_references when inside a
    class-like scope. Self is the dynamic type, so the rewrite silently changed
    runtime behavior for non-final classes (x is Self is not equivalent to
    x is A). Mirrors the rule's existing X.self skip; static member references
    such as A.f() are still corrected.
    Brett-Best
    #6764

  • Avoid false positives in vertical_parameter_alignment when a parameter is
    preceded by multi-byte characters, such as a function name containing
    non-ASCII letters. Alignment is now compared by visible column rather than by
    UTF-8 byte offset.
    systemBlue
    #5037

  • Treat macro declarations like function declarations for line_length when
    ignores_function_declarations is enabled.
    leno23
    #5648

  • Make Glob.expandGlobstar tolerant of unreadable directory entries on
    large trees. subpathsOfDirectory(atPath:) aborted the entire glob
    expansion on the first unreadable entry (permission denied, dangling
    symlink, file removed mid-scan), causing most files in large projects to
    be silently ignored. Replace the directory walk with a lazy URL
    enumerator that has a per-item error handler so unreadable items are
    skipped individually.
    Chupik

  • Avoid false positives in prefer_self_in_static_references for generic
    constraints and generic parameter bounds such as where A: P and <A: P>
    in classes and extensions.
    SimplyDanny
    #6674

  • Don't rewrite a type reference to Self in prefer_self_in_static_references
    when it appears in a protocol composition (such as any A & B), as the
    constraint of an existential or opaque type (such as any A or some A), or
    as the base of an existential metatype (such as A.Protocol), since the named
    type is not interchangeable with Self in those positions.
    Brett-Best
    #6748


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.64.1", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "d8d48a0d32a2359909d0e32065639b0c4a8e0e0e5fa6dbefbf5b63c24b55be63",
    url = "https://github.com/realm/SwiftLint/releases/download/0.64.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

0.64.0: All Windows Opened

Choose a tag to compare

@SimplyDanny SimplyDanny released this 21 Jun 14:42

Breaking

  • The ignored_literal_argument_functions option of the force_unwrapping rule now
    uses the configured value as-is instead of always merging in the five built-in defaults
    (URL(string:), NSURL(string:), UIImage(named:), NSImage(named:), Data(hexString:)).
    Those five functions remain the default when the option is not configured, but setting
    ignored_literal_argument_functions to any explicit list — including [] — now fully
    replaces the defaults. Configurations that add functions on top of the defaults must now
    explicitly include the five previously-default functions in their list.
    SimplyDanny
    #6675

Experimental

  • None.

Enhancements

  • SwiftLint can now be built and run on Windows. It is expected to work in the same way as
    on other platforms. The only restrictions are missing support for ?[] glob patterns in
    include/exclude patterns and the requirement for \n as line ending in all linted files.
    compnerd
    roman-bcny
    SimplyDanny
    #6351
    #6352

  • Rename allow_implicit_init to include_implicit_init for the
    optional_data_string_conversion rule to convey its purpose more clearly.
    SimplyDanny
    #6670

  • Improve linting performance by 10-15%, especially when running with many
    threads, by optimizing cache locking and reducing contention. Depending on
    the project and level of concurrency, the performance improvement can be even
    higher (3-4x).
    SimplyDanny

  • Rewrite the following rules with SwiftSyntax:

    • file_types_order

    SimplyDanny

  • Fix false positive in accessibility_label_for_image rule for images inside
    SwiftUI Label's icon: closure, which are inherently labeled by the
    Label's text content.
    sutheesh
    #6420

Bug Fixes

  • Fix literal_expression_end_indentation autocorrection deleting source code
    when the closing bracket of a multiline literal shares a line with the end of
    a multiline last element (e.g. ...))]). The corrector assumed everything
    before the bracket on that line was indentation and replaced it; it now moves
    only the bracket to its own line at the expected indentation.
    Luan Câmara
    #2823

  • Don't rewrite the type operand of an is / as? / as! cast (such as
    x is A) to Self in prefer_self_in_static_references when inside a
    class-like scope. Self is the dynamic type, so the rewrite silently changed
    runtime behavior for non-final classes (x is Self is not equivalent to
    x is A). Mirrors the rule's existing X.self skip; static member references
    such as A.f() are still corrected.
    Brett-Best
    #6764

  • Avoid false positives in vertical_parameter_alignment when a parameter is
    preceded by multi-byte characters, such as a function name containing
    non-ASCII letters. Alignment is now compared by visible column rather than by
    UTF-8 byte offset.
    systemBlue
    #5037

  • Treat macro declarations like function declarations for line_length when
    ignores_function_declarations is enabled.
    leno23
    #5648

  • Make Glob.expandGlobstar tolerant of unreadable directory entries on
    large trees. subpathsOfDirectory(atPath:) aborted the entire glob
    expansion on the first unreadable entry (permission denied, dangling
    symlink, file removed mid-scan), causing most files in large projects to
    be silently ignored. Replace the directory walk with a lazy URL
    enumerator that has a per-item error handler so unreadable items are
    skipped individually.
    Chupik

  • Avoid false positives in prefer_self_in_static_references for generic
    constraints and generic parameter bounds such as where A: P and <A: P>
    in classes and extensions.
    SimplyDanny
    #6674

  • Don't rewrite a type reference to Self in prefer_self_in_static_references
    when it appears in a protocol composition (such as any A & B), as the
    constraint of an existential or opaque type (such as any A or some A), or
    as the base of an existential metatype (such as A.Protocol), since the named
    type is not interchangeable with Self in those positions.
    Brett-Best
    #6748


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.64.0", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "803d94e159f64c3a75a4ee5271496911139cd6b64e362b73ae859c965cafbf34",
    url = "https://github.com/realm/SwiftLint/releases/download/0.64.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

0.63.3: High-Speed Extraction

Choose a tag to compare

@SimplyDanny SimplyDanny released this 27 May 15:12

Enhancements

  • Treat extensions like classes in the prefer_self_in_static_references
    rule.
    itsybitsybootsy
    #3993

  • Print fixed code read from stdin to stdout.
    SimplyDanny
    #6501

  • Add new redundant_final rule that detects final modifiers on declarations
    where they are redundant due to the containing context, such as final classes
    or actors. Final actors are themselves implicitly final, so the final modifier
    is redundant on them as well.
    william-laverty
    SimplyDanny
    #6407

  • Add discouraged_default_parameter opt-in rule that flags default parameter
    values in functions with configurable access levels.
    William-Laverty
    #6488

  • Add ignored_literal_argument_functions option to the force_unwrapping rule
    to skip violations for configurable function calls when all arguments are
    literal values (e.g. URL(string: "https://example.com")!). Defaults
    include URL(string:), NSURL(string:), UIImage(named:),
    NSImage(named:), and Data(hexString:).
    claudeaceae
    #6487

  • Add rules array to SARIF reporter output, providing metadata for all
    built-in rules in accordance with the SARIF specification.
    ahmadalfy
    #6499

  • Add allow_underscore_prefixed_names option to unused_parameter so
    underscore-prefixed parameter names can be treated as intentionally
    unused when configured.
    theamodhshetty
    #5741

  • Add detection of cases such as String.init(decoding: data, as: UTF8.self) and
    let text: String = .init(decoding: data, as: UTF8.self) to
    optional_data_string_conversion rule.
    nadeemnali
    #6359

  • Add new default invisible_character rule that detects invisible characters
    like zero-width space (U+200B), zero-width non-joiner (U+200C),
    and FEFF formatting character (U+FEFF) in string literals, which can cause
    hard-to-debug issues.
    kapitoshka438
    #6045

  • Add variable_shadowing rule that flags when a variable declaration shadows
    an identifier from an outer scope.
    nadeemnali
    #6228

  • Add legacy_uigraphics_function rule to encourage the use of modern
    UIGraphicsImageRenderer instead of the legacy UIGraphics{Begin|End}ImageContext.
    The modern replacement is safer, cleaner, Retina-aware and more performant.
    Dimitri Dupuis-Latour
    #6268

  • Support access level modifiers on imports in unused_imports rule.
    SimplyDanny
    #6620

  • Add name="SwiftLint" to JUnit testsuites and testsuite output for
    better CI parser compatibility.
    theamodhshetty
    #6161

  • Improve the opt-in pattern_matching_keywords rule by extending support
    beyond switch case and refining nested pattern handling.
    GandaLF2006

Bug Fixes

  • Detect and autocorrect missing whitespace before else in guard
    statements for the statement_position rule.
    theamodhshetty
    #6153

  • Avoid false positives from unused_enumerated when higher-order calls on
    .enumerated() use result members like ?.offset after the closure.
    theamodhshetty
    #5881

  • Add an ignore_attributes option to implicit_optional_initialization so
    wrappers/attributes that require explicit = nil can be excluded from
    style checks for both style: always and style: never.
    theamodhshetty
    #3998

  • Skip @TestState properties in quick_discouraged_call rule, matching
    existing @TestInjected and @TestWeakly exclusions.
    William-Laverty
    #5803

  • Fix explicit_self false positives around string interpolation.
    jffmrk
    SimplyDanny
    #6611

  • Properly taint variables in tuples for unneeded_escaping rule.
    SimplyDanny
    #6621

  • Ensure that disable commands work for redundant_nil_coalescing rule.
    SimplyDanny
    #6465

  • Take try expressions in call parameters into account even if the call has
    trailing closures as well, so that an outer throws is not considered unneeded
    in the unneeded_throws_rethrows rule.
    SimplyDanny
    #6491

  • Ensure that disable commands work for prefer_key_path rule when the trailing
    closure starts on a different line than the function call as a whole.
    SimplyDanny
    #6466

  • Track identifiers declared in tuples to avoid false positives in the
    redundant_self rule.
    SimplyDanny
    #6553

  • Respect existing environment variables when setting BUILD_WORKSPACE_DIRECTORY
    in build tool plugins.
    SimplyDanny
    #6080

  • Fix false positives in indentation_width rule for continuation lines
    of multi-line guard/if/while conditions. A new option
    include_multiline_conditions (default: false) skips these lines by
    default. When enabled, it validates that continuation lines are aligned
    with the first condition after the keyword.
    tanaev
    #4961

  • multiline_call_arguments no longer reports violations for enum-case patterns in
    pattern matching (e.g. if case, switch case, for case, catch).
    GandaLF2006

  • Avoid false positives in prefer_self_in_static_references when a nested type
    shadows its enclosing type name.
    theamodhshetty
    #5917

0.63.2: High-Speed Extraction

Enhancements

  • Add ignore_regex configuration option to the large_tuple rule to silence
    violations for tuples inside Regex<...> types, which commonly have large
    tuple type parameters for capture groups.
    Deco354
    #6340

Bug Fixes

  • Use start position of closure (in addition to the containing function call) to check
    if violations are disabled for it in trailing_closure rule.
    SimplyDanny
    #6451

0.63.1: High-Speed Extraction

Enhancements

  • Add a --disable-sourcekit flag to the lint command to disable SourceKit when needed.
    The environment variable SWIFTLINT_DISABLE_SOURCEKIT can still be used as well.
    SimplyDanny
    #6282

Bug Fixes

  • Retain async initializers in actors in async_without_await rule.
    SimplyDanny
    #6423

  • Inform users about files being skipped due to impossible file system representation
    instead of crashing.
    SimplyDanny
    #6419

  • Ignore override functions in async_without_await rule.
    SimplyDanny
    #6416

  • Avoid infinite recursion for deeply nested symbolic links which is usually the case
    in node_modules directories managed by pnpm.
    SimplyDanny
    #6425

  • Fix false positive in unneeded_escaping rule when an escaping closure is used in
    a nested closure preceded by another closure.
    SimplyDanny
    #6410

  • Fix non-excluded bool literal in optional_enum_case_name when used inside a tuple.
    tristan-burnside-anz

0.63.0: High-Speed Extraction

Breaking

  • The redundant_self_in_closure rule has been renamed to redundant_self (with
    redundant_self_in_closure as a deprecated alias) to reflect its now broader scope,
    while it still ma...
Read more

0.63.2: High-Speed Extraction

Choose a tag to compare

@SimplyDanny SimplyDanny released this 26 Jan 21:06

Enhancements

  • Add ignore_regex configuration option to the large_tuple rule to silence
    violations for tuples inside Regex<...> types, which commonly have large
    tuple type parameters for capture groups.
    Deco354
    #6340

Bug Fixes

  • Use start position of closure (in addition to the containing function call) to check
    if violations are disabled for it in trailing_closure rule.
    SimplyDanny
    #6451

0.63.1: High-Speed Extraction

Enhancements

  • Add a --disable-sourcekit flag to the lint command to disable SourceKit when needed.
    The environment variable SWIFTLINT_DISABLE_SOURCEKIT can still be used as well.
    SimplyDanny
    #6282

Bug Fixes

  • Retain async initializers in actors in async_without_await rule.
    SimplyDanny
    #6423

  • Inform users about files being skipped due to impossible file system representation
    instead of crashing.
    SimplyDanny
    #6419

  • Ignore override functions in async_without_await rule.
    SimplyDanny
    #6416

  • Avoid infinite recursion for deeply nested symbolic links which is usually the case
    in node_modules directories managed by pnpm.
    SimplyDanny
    #6425

  • Fix false positive in unneeded_escaping rule when an escaping closure is used in
    a nested closure preceded by another closure.
    SimplyDanny
    #6410

  • Fix non-excluded bool literal in optional_enum_case_name when used inside a tuple.
    tristan-burnside-anz

0.63.0: High-Speed Extraction

Breaking

  • The redundant_self_in_closure rule has been renamed to redundant_self (with
    redundant_self_in_closure as a deprecated alias) to reflect its now broader scope,
    while it still maintains the previous behavior of only checking closures by default.
    To enable checking for all redundant self usages, set the new only_in_closures
    option to false.
    SimplyDanny

Experimental

  • None.

Enhancements

  • Extend redundant_self_in_closure rule to detect all redundant uses of self,
    not just in closures. Initializers (which commonly prefer an explicit self prefix)
    can be ignored by setting keep_in_initializers to true.
    SimplyDanny

  • Add a separation configuration option to the vertical_whitespace_between_cases rule
    to allow customizing blank line separation between switch cases. The default value is
    always (require at least one blank line). Setting it to never enforces no blank
    lines between cases.
    SimplyDanny
    #6326

  • Rewrite the following rules with SwiftSyntax:

    • vertical_whitespace_between_cases

    SimplyDanny

  • Add new opt-in unneeded_throws_rethrows rule that triggers when declarations
    marked throws/rethrows never actually throw or call any throwing code.
    Tony Ngo

  • Add new unneeded_escaping rule that detects closure parameters marked with
    @escaping that are never stored or captured escapingly.
    SimplyDanny

  • Add multiline_call_arguments opt-in rule to enforce consistent multiline
    formatting for function and method call arguments.
    GandaLF2006

  • Improve performance when exclude patterns resolve to a large set of files.
    SimplyDanny
    #5018
    #5207
    #5953
    #6084
    #6259

Bug Fixes

  • Fix line_length rule incorrectly ignoring function bodies when
    ignores_function_declarations is enabled. The option should only ignore
    function declarations, not their implementation.
    SimplyDanny
    #6347

  • Fix false positives in vertical_whitespace_between_cases rule when cases are
    interleaved with compiler directives like #if/#else/#endif.
    SimplyDanny
    #6332

  • override_in_extension no longer triggers inside @objc @implementation extensions.
    JaredGrubb

  • Reinstate handling of access level imports in sorted_imports rule.
    Brett-Best
    #6374


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.63.2", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "e3da0cfecc1ae663338b0c54cc45869834cd436b539e0d30816dd44b0e369d28",
    url = "https://github.com/realm/SwiftLint/releases/download/0.63.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

0.64.0-rc.1: All Windows Opened

Pre-release

Choose a tag to compare

@SimplyDanny SimplyDanny released this 25 Jan 11:51

Experimental

  • SwiftLint can now be built and run on Windows. It is expected to work in the same way as
    on other platforms. The only restrictions are missing support for ?[] glob patterns in
    include/exclude patterns and the requirement for \n as line ending in all linted files.
    SimplyDanny
    compnerd
    roman-bcny
    #6351
    #6352

Enhancements

  • Add ignore_regex configuration option to the large_tuple rule to silence
    violations for tuples inside Regex<...> types, which commonly have large
    tuple type parameters for capture groups.
    Deco354
    #6340

Bug Fixes

  • Use start position of closure (in addition to the containing function call) to check
    if violations are disabled for it in trailing_closure rule.
    SimplyDanny
    #6451

Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.64.0-rc.1", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "18e10629d70461a7b287f01e61cb82181ddfe081e3ce9aea5655027287146ce6",
    url = "https://github.com/realm/SwiftLint/releases/download/0.64.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

0.63.1: High-Speed Extraction

Choose a tag to compare

@SimplyDanny SimplyDanny released this 15 Jan 20:25

Enhancements

  • Add a --disable-sourcekit flag to the lint command to disable SourceKit when needed.
    The environment variable SWIFTLINT_DISABLE_SOURCEKIT can still be used as well.
    SimplyDanny
    #6282

Bug Fixes

  • Retain async initializers in actors in async_without_await rule.
    SimplyDanny
    #6423

  • Inform users about files being skipped due to impossible file system representation
    instead of crashing.
    SimplyDanny
    #6419

  • Ignore override functions in async_without_await rule.
    SimplyDanny
    #6416

  • Avoid infinite recursion for deeply nested symbolic links which is usually the case
    in node_modules directories managed by pnpm.
    SimplyDanny
    #6425

  • Fix false positive in unneeded_escaping rule when an escaping closure is used in
    a nested closure preceded by another closure.
    SimplyDanny
    #6410

  • Fix non-excluded bool literal in optional_enum_case_name when used inside a tuple.
    tristan-burnside-anz

0.63.0: High-Speed Extraction

Breaking

  • The redundant_self_in_closure rule has been renamed to redundant_self (with
    redundant_self_in_closure as a deprecated alias) to reflect its now broader scope,
    while it still maintains the previous behavior of only checking closures by default.
    To enable checking for all redundant self usages, set the new only_in_closures
    option to false.
    SimplyDanny

Enhancements

  • Extend redundant_self_in_closure rule to detect all redundant uses of self,
    not just in closures. Initializers (which commonly prefer an explicit self prefix)
    can be ignored by setting keep_in_initializers to true.
    SimplyDanny

  • Add a separation configuration option to the vertical_whitespace_between_cases rule
    to allow customizing blank line separation between switch cases. The default value is
    always (require at least one blank line). Setting it to never enforces no blank
    lines between cases.
    SimplyDanny
    #6326

  • Rewrite the following rules with SwiftSyntax:

    • vertical_whitespace_between_cases

    SimplyDanny

  • Add new opt-in unneeded_throws_rethrows rule that triggers when declarations
    marked throws/rethrows never actually throw or call any throwing code.
    Tony Ngo

  • Add new unneeded_escaping rule that detects closure parameters marked with
    @escaping that are never stored or captured escapingly.
    SimplyDanny

  • Add multiline_call_arguments opt-in rule to enforce consistent multiline
    formatting for function and method call arguments.
    GandaLF2006

  • Improve performance when exclude patterns resolve to a large set of files.
    SimplyDanny
    #5018
    #5207
    #5953
    #6084
    #6259

Bug Fixes

  • Fix line_length rule incorrectly ignoring function bodies when
    ignores_function_declarations is enabled. The option should only ignore
    function declarations, not their implementation.
    SimplyDanny
    #6347

  • Fix false positives in vertical_whitespace_between_cases rule when cases are
    interleaved with compiler directives like #if/#else/#endif.
    SimplyDanny
    #6332

  • override_in_extension no longer triggers inside @objc @implementation extensions.
    JaredGrubb

  • Reinstate handling of access level imports in sorted_imports rule.
    Brett-Best
    #6374


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.63.1", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "bbdde20024722af8813af317d2af051fd4b430b61332072bbccf7ab53825bb2a",
    url = "https://github.com/realm/SwiftLint/releases/download/0.63.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

0.63.0: High-Speed Extraction

Choose a tag to compare

@SimplyDanny SimplyDanny released this 03 Jan 14:25

Breaking

  • The redundant_self_in_closure rule has been renamed to redundant_self (with
    redundant_self_in_closure as a deprecated alias) to reflect its now broader scope,
    while it still maintains the previous behavior of only checking closures by default.
    To enable checking for all redundant self usages, set the new only_in_closures
    option to false.
    SimplyDanny

Enhancements

  • Extend redundant_self_in_closure rule to detect all redundant uses of self,
    not just in closures. Initializers (which commonly prefer an explicit self prefix)
    can be ignored by setting keep_in_initializers to true.
    SimplyDanny

  • Add a separation configuration option to the vertical_whitespace_between_cases rule
    to allow customizing blank line separation between switch cases. The default value is
    always (require at least one blank line). Setting it to never enforces no blank
    lines between cases.
    SimplyDanny
    #6326

  • Rewrite the following rules with SwiftSyntax:

    • vertical_whitespace_between_cases

    SimplyDanny

  • Add new opt-in unneeded_throws_rethrows rule that triggers when declarations
    marked throws/rethrows never actually throw or call any throwing code.
    Tony Ngo

  • Add new unneeded_escaping rule that detects closure parameters marked with
    @escaping that are never stored or captured escapingly.
    SimplyDanny

  • Add multiline_call_arguments opt-in rule to enforce consistent multiline
    formatting for function and method call arguments.
    GandaLF2006

  • Improve performance when exclude patterns resolve to a large set of files.
    SimplyDanny
    #5018
    #5207
    #5953
    #6084
    #6259

Bug Fixes

  • Fix line_length rule incorrectly ignoring function bodies when
    ignores_function_declarations is enabled. The option should only ignore
    function declarations, not their implementation.
    SimplyDanny
    #6347

  • Fix false positives in vertical_whitespace_between_cases rule when cases are
    interleaved with compiler directives like #if/#else/#endif.
    SimplyDanny
    #6332

  • override_in_extension no longer triggers inside @objc @implementation extensions.
    JaredGrubb

  • Reinstate handling of access level imports in sorted_imports rule.
    Brett-Best
    #6374


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.63.0", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "efd4d25d65857d56b2531ef88ac2d705457e3b861893bbd6bc46d55bbf6b5528",
    url = "https://github.com/realm/SwiftLint/releases/download/0.63.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

0.63.0-rc.2: High-Speed Extraction

Pre-release

Choose a tag to compare

@SimplyDanny SimplyDanny released this 20 Dec 11:45

Breaking

  • The redundant_self_in_closure rule has been renamed to redundant_self (with
    redundant_self_in_closure as a deprecated alias) to reflect its now broader scope.
    SimplyDanny

Enhancements

  • Extend redundant_self_in_closure rule to detect all redundant uses of self,
    not just in closures. Initializers (which commonly prefer an explicit self prefix)
    can be ignored by setting keep_in_initializers to true.
    SimplyDanny

  • Add a separation configuration option to the vertical_whitespace_between_cases rule
    to allow customizing blank line separation between switch cases. The default value is
    always (require at least one blank line). Setting it to never enforces no blank
    lines between cases.
    SimplyDanny
    #6326

  • Rewrite the following rules with SwiftSyntax:

    • vertical_whitespace_between_cases

    SimplyDanny

  • Add new opt-in unneeded_throws_rethrows rule that triggers when declarations
    marked throws/rethrows never actually throw or call any throwing code.
    Tony Ngo

  • Add new unneeded_escaping rule that detects closure parameters marked with
    @escaping that are never stored or captured escapingly.
    SimplyDanny

  • Add multiline_call_arguments opt-in rule to enforce consistent multiline
    formatting for function and method call arguments.
    GandaLF2006

  • Improve performance when exclude patterns resolve to a large set of files.
    SimplyDanny
    #5018
    #5207
    #5953
    #6084
    #6259

Bug Fixes

  • Fix line_length rule incorrectly ignoring function bodies when
    ignores_function_declarations is enabled. The option should only ignore
    function declarations, not their implementation.
    SimplyDanny
    #6347

  • Fix false positives in vertical_whitespace_between_cases rule when cases are
    interleaved with compiler directives like #if/#else/#endif.
    SimplyDanny
    #6332

  • override_in_extension no longer triggers inside @objc @implementation extensions.
    JaredGrubb

  • Reinstate handling of access level imports in sorted_imports rule.
    Brett-Best
    #6374


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.63.0-rc.2", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "b87c861c7ea2d838e3a6725978f39edf94b1fb3ca5f478fa32dd96f360b9d076",
    url = "https://github.com/realm/SwiftLint/releases/download/0.63.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

0.62.2: Generous Drum Volume

Choose a tag to compare

@SimplyDanny SimplyDanny released this 28 Oct 17:15

Enhancements

  • Add new incompatible_concurrency_annotation rule that triggers when a declaration
    isolated to a global actor, @Sendable closure arguments and/or generic sendable
    constraints is not annotated with @preconcurrency in order to maintain compatibility
    with Swift 5.
    mattmassicotte
    SimplyDanny
    #5987

  • Add isolation modifier group to modifier_order rule configuration.
    This allows configuring the position of nonisolated modifiers.
    nandhinisubbu
    #6164

  • Add test count to JUnit reporter.
    nandhinisubbu
    #6161

  • Adopt mimalloc for static Linux binary
    to improve performance.
    ainame
    #6298

Bug Fixes

  • Fix false positive with #Preview macro in closure_end_indentation rule.
    gibachan

  • Fix correction of sorted_imports rule when comments (with a distance) are present before
    the first import.
    SimplyDanny
    #6317

0.62.1: Generous Drum Volume

Bug Fixes

  • Remove trailing comma making the code base again compilable with at least Swift 6.0.
    SimplyDanny

0.62.0: Generous Drum Volume

Breaking

  • The structure of SwiftLintBinary.artifactbundle.zip is now simpler. Internal paths no
    longer contain version numbers, especially. So in an Xcode Run Script build phase,
    you can refer to the swiftlint binary like this:

    SWIFT_PACKAGE_DIR="${BUILD_DIR%Build/*}SourcePackages/artifacts"
    SWIFTLINT_CMD="$SWIFT_PACKAGE_DIR/swiftlintplugins/SwiftLintBinary/SwiftLintBinary.artifactbundle/macos/swiftlint"

    All other consumers of the artifact bundle do not need to change anything. Swift Package
    Manager resolves the new paths automatically.
    SimplyDanny

  • SwiftLint now requires a Swift 6 or higher compiler to build. The
    Swift Package Manager plugins continue
    to work with all versions down to Swift 5.9.
    SimplyDanny

  • sorted_imports rule's behavior changed in that it now treats imports directly adjacent
    to each other as a group that is sorted together. Imports separated by at least one
    non-import statement or empty line(s) are treated as separate groups. Comments are
    considered part of the import group they are attached to and do not break it.
    SimplyDanny

Enhancements

  • Rewrite the following rules with SwiftSyntax:

    • modifier_order
    • sorted_imports

    SimplyDanny

  • Add new prefer_asset_symbols rule that suggests using asset symbols over
    string-based image initialization to avoid typos and enable compile-time
    checking. This rule detects UIImage(named:) and SwiftUI.Image(_:) calls
    with string literals and suggests using asset symbols instead.
    danglingP0inter
    #5939

  • Exclude integer generic parameters from generic_type_name rule.
    Include integer generic parameters in the identifier_name rule for validation.
    nandhinisubbu
    #6213

Bug Fixes

  • Ignore function, initializer and subscript declarations alike when the
    ignores_function_declarations option is enabled in the line_length rule.
    SimplyDanny
    #6241

  • Individual custom_rules can now be specified in the only_rule configuration
    setting and the --only-rule command line option without having to specify
    custom_rules as well. Additionally, violations of custom rules are now reported
    in a deterministic order, sorted by the rule's identifier.
    Martin Redington
    #6029
    #6058

  • Ignore redundant_discardable_let rule violations in nested SwiftUI scopes as well
    when ignore_swiftui_view_bodies is enabled.
    SimplyDanny
    #3855
    #6255

  • Exclude function types from async_without_await rule analysis. Higher-order function
    objects can be async without containing an await when assigning to them.
    SimplyDanny
    #6253

  • Exclude @concurrent functions from async_without_await rule analysis.
    @concurrent functions requires aysnc in any case.
    nandhinisubbu
    #6283

  • swiftlint-static, the experimental fully-static Linux binary, now uses 512 KiB
    as thread stack size matching Darwin’s size to prevent stack exhaustion.
    ainame
    #6287


Using Bazel

With bzlmod:

// Pending BCR update
bazel_dep(name = "swiftlint", version = "0.62.2", repo_name = "SwiftLint")

Without bzlmod, 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 = "9e26307516c4d5f2ad4aee90ac01eb8cd31f9b8d6ea93619fc64b3cbc81b0944",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/2.2.0/rules_apple.2.2.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 = "9e729406b1ba9a94bb3a3367ff81dc53465d6231dd83e728ebac3d1391ad19e2",
    url = "https://github.com/realm/SwiftLint/releases/download/0.62.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