Swiftlint: Custom Rules in nested configuration

Created on 3 Sep 2017  路  7Comments  路  Source: realm/SwiftLint

New Issue Checklist

Bug Report

I'm using a custom rule to validate the name of my Quick Specs (I want them to end with Tests, e.g. AppCordinatorTests). For that, I implemented a simple custom rule and placed it in the .swiftlint.yml that I have inside the Tests directory. It didn't work. So I moved the custom rule to the top level .swiftlint.yml and it worked.

Apparently custom rules don't work if placed in nested configurations.

Environment

  • SwiftLint version (run swiftlint version to be sure)? 0.22.0
  • Installation method used (Homebrew, CocoaPods, building from source, etc)? Homebrew
  • Paste your configuration file:
# ...

custom_rules:
  quickspec_class_name:
    name: "Invalid Test Class Name"
    regex: "class\\s+(.*)[^Tests]:\\s+QuickSpec"
    message: "A test class name must end with 'Tests'"
    severity: error
  • Are you using nested configurations? Yes, I am.

  • Which Xcode version are you using (check xcode-select -p)? Xcode 9b6 (App and Command Line)

// This triggers a violation:
class Foo: QuickSpec { }

// Doesn't trigger a violation:
class FooTests: QuickSpec { }
bug

All 7 comments

To reproduce it, create a file called issue1815.sh and paste the following:

#!/usr/bin/env sh

mkdir Issue1815
cd Issue1815

touch .swiftlint.yml
mkdir Tests
cd Tests

cat > .swiftlint.yml << EOF
custom_rules:
  quickspec_class_name:
    name: "Invalid Test Class Name"
    regex: "class\\\\s+(.*)[^Tests]:\\\\s+QuickSpec"
    message: "A test class name must end with 'Tests'"
    severity: error
EOF

cat > FooTests.swift << EOF
// This triggers a violation:
class Foo: QuickSpec { }

// Doesn't trigger a violation:
class FooTests: QuickSpec { }
EOF

Then run sh issue1815.sh. It will create a sample project that reproduces the problem. Run swiftlint from the top directory (inside Issue1815) and it will not trigger the violation. If you move the rule from Tests/.swiftlint.yml to .swiftlint.yml it triggers the violation.

Could reproduce it, but I needed to change cat > .swiftlint.yaml << EOF to cat > .swiftlint.yml << EOF in the script 馃槈

This issue appears for me when configuring a standard (non custom) rule in a nested configuration also.

To reproduce it, create a file called issue1815-StandardRule.sh and paste the following:

#!/usr/bin/env sh

mkdir Issue1815-StandardRule
cd Issue1815-StandardRule

touch .swiftlint.yml
mkdir Tests
cd Tests

cat > .swiftlint.yml << EOF
line_length:
  warning: 50
  error: 70

EOF

cat > FooTests.swift << EOF
// This triggers a violation:
class FooTests: VeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongQuickSpec { }

// Doesn't trigger a violation:
class Foo: QuickSpec { }
EOF

Then run sh issue1815-StandardRule.sh. It will create a sample project that reproduces the problem. Run swiftlint from the top directory (inside Issue1815-StandardRule) and it will not trigger the violation. If you move the rule from Tests/.swiftlint.yml to .swiftlint.yml it triggers the violation.

Hi there, I'm also experiencing the same issue. When can we expect a fix?

The reason that doesn't work is because of the way swiftlint currently handles merges. It is not a true 'merge' of the rules and it's values but a 'union' of rules by identifiers.

In @kenthumphries case:

  • The nested config in the Spec directory is attempted to be merged to the root config
  • The root config is blank and hence contains all default rules with their default severity levels
  • The root config rules are unioned (Set operation) with the nested config
  • Since the uniqueness of the rule is determined by it's identifier, the nested rule is completely ignored.
  • All the root config rules 'win' in this case and the error and warning threshold overrides in the nested config are completely ignored
  • This is contrary to what https://github.com/realm/SwiftLint/pull/1674 says

If you want to restore the original behaviour of a "nested config replacing the root config", please take a look at my open PR https://github.com/realm/SwiftLint/pull/2245
This is a backward compatible since the behaviour can be disabled using a commandline option.

@marcelofabri I feel this has regressed somewhere along the way. Let me know if you want me to raise a bug.

Reference
The merging strategy can be found here: https://github.com/realm/SwiftLint/blob/5a76b45550d9541e595e40412103dd44d029c440/Source/SwiftLintFramework/Extensions/Configuration%2BMerging.swift#L76

Fixed in #2556

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bourquep picture bourquep  路  3Comments

Den-Ree picture Den-Ree  路  3Comments

msanders picture msanders  路  4Comments

jszumski picture jszumski  路  3Comments

larslockefeer picture larslockefeer  路  3Comments