Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event-based TipKit rule triggers an empty_count violation #5883

Open
2 tasks done
achernenko-schibsted opened this issue Dec 5, 2024 · 1 comment · May be fixed by #5918
Open
2 tasks done

Event-based TipKit rule triggers an empty_count violation #5883

achernenko-schibsted opened this issue Dec 5, 2024 · 1 comment · May be fixed by #5918
Labels
bug Unexpected and reproducible misbehavior. good first issue Issue to be taken up by new contributors yet unfamiliar with the project.

Comments

@achernenko-schibsted
Copy link

achernenko-schibsted commented Dec 5, 2024

New Issue Checklist

Bug Description

TipKit uses the #Rule macro to define the conditions that must be fulfilled for a tip to be displayed:

import TipKit

struct SomeHelpfulTip: Tip {
    var rules: [Rule] {
        #Rule(Tips.someEventHappened) { $0.donations.count > 0 }
    }
}

$0.donations.count > 0 triggers the empty_count rule violation. However, changing this to $0.donations.isEmpty causes a build error, "Event Rules do not support keyPath operations.", so I have to resort to disabling the empty_count rule here. #Rule is a Swift macro that expects an event donation count to be compared with a number, failing to generate code otherwise, so there aren't any alternatives.

Environment

  • SwiftLint version: 0.57.1
  • Xcode version: 16.1
  • Installation method used: Homebrew
  • Configuration file:
swiftlint.yml
excluded: # paths to ignore during linting. Takes precedence over `included`.
  - Scripts
  - ReferenceImages
  - BuildSystem
  - Configurations
  - AppStoreConnect
  - node_modules
disabled_rules: # rule identifiers to exclude from running
  - line_length
  - identifier_name
  - todo
  - file_length
  - nesting
  - comma_inheritance
  - type_body_length
  - trailing_whitespace
  - static_over_final_class
opt_in_rules:
  - discouraged_assert
  - empty_count
  - first_where
  - empty_string
  - toggle_bool
  - convenience_type
  - overridden_super_call
  - shorthand_optional_binding
  - unneeded_parentheses_in_closure_argument
  - accessibility_label_for_image
  - accessibility_trait_for_button
  - array_init
  - attributes
  - closure_end_indentation
  - collection_alignment
  - yoda_condition
  - direct_return
analyzer_rules:
  - unused_import
custom_rules:
  invalid_hex_color:
    included: ".*\\.swift"
    name: "Invalid hex color"
    regex: 'hexString: "\#{0}[0-9a-fA-F]{3,8}"'
    message: "'hexString' should always be prefixed with a #"
    severity: error
  localizedDescription:
    included: ".*\\.swift"
    name: "Don't use localizedDescription"
    regex: '(\w+\.localizedDescription)'
    message: 'Don''t use .localizedDescription. Use "(error)" instead to get the full error string'
    severity: error
  no_ui_colors:
    name: "Don't use Standard UIColors"
    excluded: "(WidgetExtension)\\/.*|.*\\/WidgetExtension\\.swift|.*\\/UIColor\\+Extensions\\.swift|.*\\/Color\\+Extensions\\.swift"
    regex: '[.]\b(themeRed|themeBlue|themeWhite|themeBlack|systemBlue|systemGreen|systemIndigo|systemOrange|systemPink|systemPurple|systemRed|systemTeal|systemYellow|systemGray|systemGray2|systemGray3|systemGray4|systemGray5|systemGray6|black|blue|brown|cyan|darkGray|gray|green|lightGray|magenta|orange|purple|red|white|yellow)\b'
    message: "Only use the colors from UIColor+Extensions.swift"
    severity: warning
  no_color_initializers:
    name: "Don't use color initializers"
    excluded: "(WidgetExtension)\\/.*|.*\\/WidgetExtension\\.swift|.*\\/UIColor\\+Extensions\\.swift|.*\\/Color\\+Extensions\\.swift"
    regex: '\s(UIColor\(.*\)|.init\(hexString:.*\)|.init\(hue:.*saturation:.*brightness:.*\)|.init\(white:.*alpha:.*\)|.init\(red:.*green:.*blue:.*\)|.init\(red:.*green:.*blue:.*alpha:.*\))'
    message: "Only use the colors from UIColor+Extensions.swift"
    severity: warning
  no_color_generators:
    name: "Don't use color generators"
    excluded: "(WidgetExtension)\\/.*|.*\\/WidgetExtension\\.swift|.*\\/UIColor\\+Extensions\\.swift"
    regex: '\.(withAlphaComponent|darker|lighter)'
    message: "Only use the colors from UIColor+Extensions.swift"
    severity: warning
  no_optional_decode_initial_overridable:
    regex: 'decodeIfPresent\(InitialOverridable'
    name: "Don't decodeIfPresent InitialOverridable<T>"
    message: "InitialOverridable<T> should always be decoded as non-optional."
  no_raw_nsattributed_string_attributes:
    regex: 'NSAttributedString\(string: [\S]+,\s+attributes: [\S]+\)'
    name: "Do not use raw NSAttributedString attributes"
    message: "Use .init(string:safeAttributes:) instead"
  use_makefont:
    name: "Avoid UIFont(name:size)"
    regex: 'UIFont\(name: .*'
    message: "Use `UIFont.makeFont(name:size)` instead of `UIFont(name:size:)`"
    severity: warning
  disable_print:
    name: "print usage"
    regex: "((\\bprint)|(\\bdebugPrint)|(Swift\\.print))\\s*\\("
    message: "Don't use print statements in production code."
    severity: warning
    match_kinds:
      - identifier
overridden_super_call:
  included:
    - "*"
    - "viewSafeAreaInsetsDidChange()"
    - "viewLayoutMarginsDidChange()"
    - "viewDidLayoutSubviews()"
    - "viewWillTransition(to:with:)"
    - "collectionView(_:willDisplay:forItemAt:)"
    - "collectionView(_:didEndDisplaying:forItemAt:)"
attributes:
  attributes_with_arguments_always_on_line_above: false
  always_on_line_above:
    ["@MainActor", "@WidgetBundleBuilder", "@available", "@AppStorage"]
@SimplyDanny
Copy link
Collaborator

There should be enough characteristics here to identify this special case. They would be a

  • single x.donation.count > 0 expression in a
  • trailing closure attached to a
  • #Rule macro with a
  • single other argument.

Not very nice, but given these conditions we can just skip this case in the rule.

@SimplyDanny SimplyDanny added bug Unexpected and reproducible misbehavior. good first issue Issue to be taken up by new contributors yet unfamiliar with the project. labels Dec 5, 2024
@Ueeek Ueeek linked a pull request Dec 28, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected and reproducible misbehavior. good first issue Issue to be taken up by new contributors yet unfamiliar with the project.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants