mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-09 22:35:56 +05:45
lint: add SwiftLint rule against Int for epoch milliseconds (#8181)
This commit is contained in:
1 parent
cd9357a08a
commit
50444c22d9
2 files changed
+51
No files matched your search
@@ -109,6 +109,23 @@ custom_rules:
|
||||
message: "Use Bundle.revenueCatUI instead of Bundle.module for Compose Resources compatibility"
|
||||
severity: error
|
||||
|
||||
no_int_epoch_milliseconds:
|
||||
name: "No Int for epoch milliseconds"
|
||||
message: "Epoch milliseconds (~1.7e12) overflow `Int` on 32-bit platforms (e.g. arm64_32 Apple Watches), crashing at runtime. Use `Int64` instead."
|
||||
severity: error
|
||||
included:
|
||||
- "Sources/.*\\.swift"
|
||||
- "RevenueCatUI/.*\\.swift"
|
||||
- "AdapterSDKs/RevenueCatAdMob/Sources/.*\\.swift"
|
||||
excluded_match_kinds:
|
||||
- comment
|
||||
- doccomment
|
||||
- doccomment.field
|
||||
- string
|
||||
# Matches, within a single line: Int(<...since...> * 1000), Int(1000 * <...since...>),
|
||||
# Int(<...since...>) * 1000 and 1000 * Int(<...since...>). One level of nested parentheses is supported.
|
||||
regex: '\bInt\((?:[^()\n]|\([^()\n]*\)|\()*timeIntervalSince(?:1970|ReferenceDate|Now)\b(?:[^()\n]|\([^()\n]*\))*\*\s*1_?000\b|\bInt\((?:[^()\n]|\([^()\n]*\)|\()*\b1_?000\s*\*\s*(?:[^()\n]|\([^()\n]*\))*timeIntervalSince(?:1970|ReferenceDate|Now)\b|\bInt\((?:[^()\n]|\([^()\n]*\))*timeIntervalSince(?:1970|ReferenceDate|Now)\b(?:[^()\n]|\([^()\n]*\))*\)\s*\*\s*1_?000\b|\b1_?000\s*\*\s*Int\((?:[^()\n]|\([^()\n]*\))*timeIntervalSince(?:1970|ReferenceDate|Now)\b'
|
||||
|
||||
no_new_public_enums:
|
||||
name: "No new public enums in consumer-facing APIs"
|
||||
message: "Adding a new `public enum` to the SDK's consumer-facing surface (including `@_spi(Experimental)`) is not allowed. Adding a case to an existing `public enum` is a source-breaking change for any consumer with an exhaustive `switch`. Use a struct with static constants instead."
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import Foundation
|
||||
|
||||
let date = Date()
|
||||
|
||||
// Int(... * 1000)
|
||||
let purchaseDate = date.map { Int($0.timeIntervalSince1970 * 1000) } // violation
|
||||
let expirationDate = Int(date.timeIntervalSince1970 * 1000) // violation
|
||||
let underscored = Int(date.timeIntervalSince1970 * 1_000) // violation
|
||||
let nested = Int((date.timeIntervalSince1970 * 1000).rounded()) // violation
|
||||
let fromNow = Int(Date().timeIntervalSince1970 * 1000) // violation
|
||||
let wrapped = Int(max(0, date.timeIntervalSince1970 * 1000)) // violation
|
||||
let safePurchaseDate = date.map { Int64($0.timeIntervalSince1970 * 1000) }
|
||||
let safeRounded = Int64((date.timeIntervalSince1970 * 1000).rounded())
|
||||
|
||||
// Int(...) * 1000
|
||||
let convertedFirst = Int(date.timeIntervalSince1970) * 1000 // violation
|
||||
let leadingMultiplier = 1000 * Int(date.timeIntervalSince1970) // violation
|
||||
let safeConvertedFirst = Int64(date.timeIntervalSince1970) * 1000
|
||||
|
||||
// Reversed operands
|
||||
let reversed = Int(1000 * date.timeIntervalSince1970) // violation
|
||||
let reversedNested = Int((1_000 * date.timeIntervalSinceReferenceDate).rounded()) // violation
|
||||
let safeReversed = Int64(1000 * date.timeIntervalSince1970)
|
||||
|
||||
// Not epoch milliseconds
|
||||
let seconds = Int(date.timeIntervalSince1970)
|
||||
let smallDuration = Int(duration * 1000)
|
||||
let unrelatedReversed = Int(1000 * duration)
|
||||
let otherCall = Int(1) + foo(date.timeIntervalSince1970 * 1000)
|
||||
let separateInt = Int(5); let millis = Double(date.timeIntervalSince1970 * 1000)
|
||||
|
||||
// Comments are ignored
|
||||
// let commented = Int(date.timeIntervalSince1970 * 1000)
|
||||
let trailingComment = Int(1) // timeIntervalSince1970 * 1000
|
||||
Reference in new issue
Block a user