Skip to content

Commit

Permalink
chore(lint): Add swiftlint (#4259)
Browse files Browse the repository at this point in the history
* chore(lint): Add swiftlint

* add swift lint and fix package scripts

* fix swift lint
  • Loading branch information
krystofwoldrich authored Nov 11, 2024
1 parent 8c88ac7 commit 94274ef
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 26 deletions.
104 changes: 104 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# We have to narrow down the included files to avoid minutes long lint runs due to node_modules
included:
- 'samples/react-native/ios/**'
- 'packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/**'
- 'packages/core/ios/**'
- 'performance-tests/TestAppPlain/ios/**'
- 'performance-tests/TestAppSentry/ios/**'

excluded:
- 'samples/react-native/ios/Pods'
- 'samples/react-native/ios/build'
- 'performance-tests/TestAppPlain/ios/Pods'
- 'performance-tests/TestAppPlain/ios/build'
- 'performance-tests/TestAppSentry/ios/Pods'
- 'performance-tests/TestAppSentry/ios/build'

only_rules:
- class_delegate_protocol
- closing_brace
- closure_end_indentation
- closure_parameter_position
- closure_spacing
- colon
- comma
- compiler_protocol_init
- control_statement
- custom_rules
- cyclomatic_complexity
- dynamic_inline
- empty_parameters
- empty_parentheses_with_trailing_closure
- explicit_init
- file_length
- first_where
- force_cast
- force_try
- force_unwrapping
- function_body_length
- generic_type_name
- implicit_getter
- large_tuple
- leading_whitespace
- legacy_cggeometry_functions
- legacy_constant
- legacy_constructor
- legacy_nsgeometry_functions
- line_length
- mark
- nimble_operator
- number_separator
- opening_brace
- operator_usage_whitespace
- operator_whitespace
- overridden_super_call
- private_outlet
- private_unit_test
- prohibited_super_call
- redundant_nil_coalescing
- redundant_optional_initialization
- redundant_string_enum_value
- redundant_void_return
- return_arrow_whitespace
- shorthand_operator
- sorted_imports
- statement_position
- syntactic_sugar
- todo
- trailing_comma
- trailing_newline
- trailing_semicolon
- type_body_length
- type_name
- unused_closure_parameter
- unused_enumerated
- unused_optional_binding
- valid_ibinspectable
- identifier_name
- vertical_parameter_alignment
- vertical_whitespace
- void_return
- weak_delegate
- yoda_condition

identifier_name:
allowed_symbols:
- i
- _
min_length:
- 1
max_length:
warning: 50
error: 50

line_length:
- 1000
type_name:
min_length:
- 2
- 1
max_length:
warning: 50
error: 50
large_tuple:
- 3
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,26 @@
"clean": "lerna run clean",
"circularDepCheck": "lerna run circularDepCheck",
"test": "lerna run test",
"fix": "run-s fix:lerna fix:android fix:clang",
"fix": "run-s fix:lerna fix:android fix:clang fix:swift",
"fix:lerna": "lerna run fix",
"fix:android": "run-s 'java:format fix' java:pmd",
"fix:clang": "run-s 'clang:format fix'",
"lint": "run-s lint:lerna lint:android lint:clang",
"fix:swift": "run-s 'swift:lint fix'",
"lint": "run-s lint:lerna lint:android lint:clang lint:swift",
"lint:lerna": "lerna run lint",
"lint:android": "run-s 'java:format lint' java:pmd",
"lint:clang": "run-s 'clang:format lint'",
"lint:swift": "run-s 'swift:lint lint'",
"java:format": "./scripts/google-java-format.sh",
"java:pmd": "./scripts/pmd.sh",
"clang:format": "./scripts/clang-format.sh",
"swift:lint": "./scripts/swiftlint.sh",
"run-ios": "cd samples/react-native && yarn react-native run-ios",
"run-android": "cd samples/react-native && yarn react-native run-android",
"set-version-samples": "lerna run set-version"
},
"devDependencies": {
"@expo/swiftlint": "^0.57.1",
"@sentry/cli": "2.38.2",
"clang-format": "^1.8.0",
"downlevel-dts": "^0.11.0",
Expand Down
11 changes: 11 additions & 0 deletions packages/core/RNSentryCocoaTester/.swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
parent_config: ../../../.swiftlint.yml

disabled_rules:
- force_cast
- force_try
- force_unwrapping
- function_body_length
- identifier_name
- large_tuple
- type_body_length
- weak_delegate
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import XCTest
import Sentry
import XCTest

class RNSentryBreadcrumbTests: XCTestCase {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import XCTest
import Sentry
import XCTest

final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {

Expand All @@ -12,7 +12,7 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
testBreadcrumb.category = "navigation"
testBreadcrumb.data = [
"from": "HomeScreen",
"to": "ProfileScreen",
"to": "ProfileScreen"
]
let actual = converter.convert(from: testBreadcrumb)

Expand All @@ -36,7 +36,7 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
testBreadcrumb.type = "navigation"
testBreadcrumb.category = "navigation"
testBreadcrumb.data = [
"to": "ProfileScreen",
"to": "ProfileScreen"
]
let actual = converter.convert(from: testBreadcrumb)

Expand All @@ -48,7 +48,7 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
assertRRWebBreadcrumbDefaults(actual: event)
XCTAssertEqual("info", payload["level"] as! String)
XCTAssertEqual("navigation", payload["category"] as! String)
XCTAssertNil(payloadData["from"] ?? nil)
XCTAssertNil(payloadData["from"])
XCTAssertEqual("ProfileScreen", payloadData["to"] as! String)
}

Expand All @@ -63,7 +63,7 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
XCTAssertNotNil(actual)
let event = actual!.serialize()
let data = event["data"] as! [String: Any?]
let payload = data["payload"] as! [String: Any?];
let payload = data["payload"] as! [String: Any?]
assertRRWebBreadcrumbDefaults(actual: event)
XCTAssertEqual(payload["category"] as! String, "app.foreground")
}
Expand All @@ -79,7 +79,7 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
XCTAssertNotNil(actual)
let event = actual!.serialize()
let data = event["data"] as! [String: Any?]
let payload = data["payload"] as! [String: Any?];
let payload = data["payload"] as! [String: Any?]
assertRRWebBreadcrumbDefaults(actual: event)
XCTAssertEqual(payload["category"] as! String, "app.background")
}
Expand Down Expand Up @@ -132,18 +132,18 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {

func testTouchMessageReturnsNilOnEmptyArray() throws {
let actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(from: [])
XCTAssertEqual(actual, nil);
XCTAssertEqual(actual, nil)
}

func testTouchMessageReturnsNilOnNilArray() throws {
let actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(from: nil as [Any]?)
XCTAssertEqual(actual, nil);
XCTAssertEqual(actual, nil)
}

func testTouchMessageReturnsNilOnMissingNameAndLevel() throws {
let testPath: [Any?] = [["element": "element4", "file": "file4"]]
let actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(from: testPath as [Any])
XCTAssertEqual(actual, nil);
XCTAssertEqual(actual, nil)
}

func testTouchMessageReturnsMessageOnValidPathExample1() throws {
Expand All @@ -153,10 +153,10 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
["name": "item2", "label": "label2"],
["name": "item3", "label": "label3", "element": "element3"],
["name": "item4", "label": "label4", "file": "file4"],
["name": "item5", "label": "label5", "element": "element5", "file": "file5"],
["name": "item5", "label": "label5", "element": "element5", "file": "file5"]
]
let actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(from: testPath as [Any])
XCTAssertEqual(actual, "label3(element3) > label2 > name1 > label0");
XCTAssertEqual(actual, "label3(element3) > label2 > name1 > label0")
}

func testTouchMessageReturnsMessageOnValidPathExample2() throws {
Expand All @@ -166,17 +166,17 @@ final class RNSentryReplayBreadcrumbConverterTests: XCTestCase {
["name": "item4", "label": "label4", "file": "file4"],
["name": "item5", "label": "label5", "element": "element5", "file": "file5"],
["label": "label6"],
["name": "name7"],
["name": "name7"]
]
let actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(from: testPath as [Any])
XCTAssertEqual(actual, "label5(element5, file5) > label4(file4) > label3(element3) > label2");
XCTAssertEqual(actual, "label5(element5, file5) > label4(file4) > label3(element3) > label2")
}

private func assertRRWebBreadcrumbDefaults(actual: [String: Any?]) {
let data = actual["data"] as! [String: Any?]
let payload = data["payload"] as! [String: Any?]
XCTAssertEqual("default", payload["type"] as! String)
XCTAssertEqual((payload["timestamp"] as! Double) * 1000.0, Double(actual["timestamp"] as! Int), accuracy: 1.0)
XCTAssertEqual((payload["timestamp"] as! Double) * 1_000.0, Double(actual["timestamp"] as! Int), accuracy: 1.0)
XCTAssertTrue(payload["timestamp"] as! Double > 0.0)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import XCTest
import Sentry
import XCTest

final class RNSentryReplayOptions: XCTestCase {

Expand All @@ -26,8 +26,8 @@ final class RNSentryReplayOptions: XCTestCase {
] as NSDictionary).mutableCopy() as! NSMutableDictionary
RNSentryReplay.updateOptions(optionsDict)

let experimental = optionsDict["experimental"] as! [String:Any]
let sessionReplay = experimental["sessionReplay"] as! [String:Any]
let experimental = optionsDict["experimental"] as! [String: Any]
let sessionReplay = experimental["sessionReplay"] as! [String: Any]

assertAllDefaultReplayOptionsAreNotNil(replayOptions: sessionReplay)
}
Expand All @@ -41,8 +41,8 @@ final class RNSentryReplayOptions: XCTestCase {
] as NSDictionary).mutableCopy() as! NSMutableDictionary
RNSentryReplay.updateOptions(optionsDict)

let experimental = optionsDict["experimental"] as! [String:Any]
let sessionReplay = experimental["sessionReplay"] as! [String:Any]
let experimental = optionsDict["experimental"] as! [String: Any]
let sessionReplay = experimental["sessionReplay"] as! [String: Any]

assertAllDefaultReplayOptionsAreNotNil(replayOptions: sessionReplay)
}
Expand All @@ -57,8 +57,8 @@ final class RNSentryReplayOptions: XCTestCase {
] as NSDictionary).mutableCopy() as! NSMutableDictionary
RNSentryReplay.updateOptions(optionsDict)

let experimental = optionsDict["experimental"] as! [String:Any]
let sessionReplay = experimental["sessionReplay"] as! [String:Any]
let experimental = optionsDict["experimental"] as! [String: Any]
let sessionReplay = experimental["sessionReplay"] as! [String: Any]

assertAllDefaultReplayOptionsAreNotNil(replayOptions: sessionReplay)
}
Expand Down Expand Up @@ -105,8 +105,8 @@ final class RNSentryReplayOptions: XCTestCase {

XCTAssertEqual(optionsDict.count, 3)

let experimental = optionsDict["experimental"] as! [String:Any]
let sessionReplay = experimental["sessionReplay"] as! [String:Any]
let experimental = optionsDict["experimental"] as! [String: Any]
let sessionReplay = experimental["sessionReplay"] as! [String: Any]

let maskedViewClasses = sessionReplay["maskedViewClasses"] as! [String]
XCTAssertEqual(maskedViewClasses.count, 1)
Expand Down
30 changes: 30 additions & 0 deletions scripts/swiftlint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

set -eo pipefail

# Check if an argument is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <fix|lint>"
exit 1
fi

# Set the mode based on the first argument
mode=$1

DARWIN_PATH="$(dirname "$0")/../node_modules/@expo/swiftlint/bin/darwin-arm64/swiftlint"
LINUX_PATH="$(dirname "$0")/../node_modules/@expo/swiftlint/bin/linux-x64/swiftlint"

if [[ "$OSTYPE" == "darwin"* ]]; then
CMD="$DARWIN_PATH"
else
CMD="$LINUX_PATH"
fi

if [ "$mode" = "fix" ]; then
$CMD --fix
elif [ "$mode" = "lint" ]; then
$CMD --strict
else
echo "Invalid mode. Use 'fix' or 'lint'."
exit 1
fi
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3176,6 +3176,15 @@ __metadata:
languageName: node
linkType: hard

"@expo/swiftlint@npm:^0.57.1":
version: 0.57.1
resolution: "@expo/swiftlint@npm:0.57.1"
dependencies:
"@expo/spawn-async": ^1.5.0
checksum: 87f744bb45cc3a4aa2a40424d21995547c138eef4d4918a3990859c9f143acd3ce463ff3f0c421c0b3e95a694abf7d8fcb8c8545dbe00d81767fc461a68c8378
languageName: node
linkType: hard

"@expo/vector-icons@npm:^14.0.0":
version: 14.0.2
resolution: "@expo/vector-icons@npm:14.0.2"
Expand Down Expand Up @@ -22891,6 +22900,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "sentry-react-native@workspace:."
dependencies:
"@expo/swiftlint": ^0.57.1
"@sentry/cli": 2.38.2
clang-format: ^1.8.0
downlevel-dts: ^0.11.0
Expand Down

0 comments on commit 94274ef

Please sign in to comment.