mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-09-19 05:00:48 +00:00
Make SwiftLint blocking in CI now that the violation backlog is zero (#1646)
* Make SwiftLint blocking in CI now that the violation backlog is zero The lint job has been advisory since #1361, with the backlog tracked in #1088. That backlog is now down to 28 violations, so this clears it and flips the job to enforcing instead of adding baseline machinery: - Fix all remaining violations: closure parameters/capture lists joined onto their opening-brace line (BLEService, NoiseSessionManager, ChatMediaTransferCoordinator, BLENoisePacketHandlerTests), one trailing comma, one opening-brace spacing (both via swiftlint --fix). - Move the two periphery:ignore comments above the doc blocks they were orphaning; verified with a periphery --strict scan that the commands still register (no new findings vs baseline). - Disable the todo rule: the single TODO cites tracked issue #1434 and is a deliberate marker, not lint debt. - Exclude .device-lab from local runs (untracked; CI never sees it). - CI: drop continue-on-error and the "(advisory)" label; run with --strict so any new warning fails the job. Full SwiftPM suite green (2,004 tests / 216 suites) after the formatting changes; swiftlint lint --strict exits 0 with the same 0.65.0 the CI container pins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix is_disjoint violation introduced by #1542 The strict lint gate caught this on its first run: the mention-suggestion key handler used modifierFlags.intersection([...]).isEmpty, which is exactly the pattern isDisjoint(with:) expresses directly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9c84d4ce4f
commit
2a9fb4d53f
13
.github/workflows/swift-tests.yml
vendored
13
.github/workflows/swift-tests.yml
vendored
@ -264,11 +264,13 @@ jobs:
|
|||||||
CODE_SIGNING_ALLOWED=NO \
|
CODE_SIGNING_ALLOWED=NO \
|
||||||
test
|
test
|
||||||
|
|
||||||
# Advisory only: SwiftLint reports style violations without ever failing the
|
# Blocking since the backlog reached zero (all violations fixed; rules the
|
||||||
# build. Runs in a pinned container (no Xcode plugin, no pbxproj changes) so
|
# codebase deliberately breaks are disabled in .swiftlint.yml). --strict
|
||||||
# it can never break the documented xcodebuild path or block a merge.
|
# promotes warnings to errors so new violations fail the job. Runs in a
|
||||||
|
# pinned container (no Xcode plugin, no pbxproj changes) so it can never
|
||||||
|
# break the documented xcodebuild path.
|
||||||
lint:
|
lint:
|
||||||
name: SwiftLint (advisory)
|
name: SwiftLint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
# This job runs a third-party container image, so give it the least
|
# This job runs a third-party container image, so give it the least
|
||||||
@ -280,10 +282,9 @@ jobs:
|
|||||||
# Tag for readability, digest for immutability (tags can be repointed).
|
# Tag for readability, digest for immutability (tags can be repointed).
|
||||||
# Bump both together, deliberately — never a floating tag.
|
# Bump both together, deliberately — never a floating tag.
|
||||||
image: ghcr.io/realm/swiftlint:0.65.0@sha256:a482729f4b58741875af1566f23397f3f6db300372756fc31606d0a4527fab9e
|
image: ghcr.io/realm/swiftlint:0.65.0@sha256:a482729f4b58741875af1566f23397f3f6db300372756fc31606d0a4527fab9e
|
||||||
continue-on-error: true
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Run SwiftLint
|
- name: Run SwiftLint
|
||||||
run: swiftlint lint --reporter github-actions-logging
|
run: swiftlint lint --strict --reporter github-actions-logging
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
excluded:
|
excluded:
|
||||||
- .build
|
- .build
|
||||||
- .claude
|
- .claude
|
||||||
|
- .device-lab
|
||||||
- .swiftpm
|
- .swiftpm
|
||||||
- .DerivedData
|
- .DerivedData
|
||||||
- DerivedData
|
- DerivedData
|
||||||
@ -21,6 +22,7 @@ disabled_rules:
|
|||||||
- control_statement
|
- control_statement
|
||||||
- void_function_in_ternary
|
- void_function_in_ternary
|
||||||
- redundant_discardable_let # SwiftUI breaks without it
|
- redundant_discardable_let # SwiftUI breaks without it
|
||||||
|
- todo # TODOs that cite a tracked issue are deliberate markers, not lint debt
|
||||||
# To be enabled as we fix the issues
|
# To be enabled as we fix the issues
|
||||||
- trailing_whitespace
|
- trailing_whitespace
|
||||||
- cyclomatic_complexity
|
- cyclomatic_complexity
|
||||||
|
|||||||
@ -1001,8 +1001,7 @@ final class NoiseSessionManager {
|
|||||||
0,
|
0,
|
||||||
recentInitiatorCompletionGracePeriod - elapsed
|
recentInitiatorCompletionGracePeriod - elapsed
|
||||||
)
|
)
|
||||||
let timeout = DispatchWorkItem(flags: .barrier) {
|
let timeout = DispatchWorkItem(flags: .barrier) { [weak self, weak establishedSession] in
|
||||||
[weak self, weak establishedSession] in
|
|
||||||
guard let self,
|
guard let self,
|
||||||
let establishedSession,
|
let establishedSession,
|
||||||
let current = self.sessions[peerID],
|
let current = self.sessions[peerID],
|
||||||
|
|||||||
@ -4027,10 +4027,8 @@ extension BLEService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.onRekeyHandshakeReady = {
|
service.onRekeyHandshakeReady = { [weak self, weak service] peerID, initiation in
|
||||||
[weak self, weak service] peerID, initiation in
|
self?.messageQueue.async { [weak self, weak service] in
|
||||||
self?.messageQueue.async {
|
|
||||||
[weak self, weak service] in
|
|
||||||
guard let self,
|
guard let self,
|
||||||
let service,
|
let service,
|
||||||
self.noiseService === service else {
|
self.noiseService === service else {
|
||||||
@ -4046,14 +4044,12 @@ extension BLEService {
|
|||||||
self.broadcastNoiseHandshake(message, to: peerID)
|
self.broadcastNoiseHandshake(message, to: peerID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.onHandshakeRecoveryRequired = {
|
service.onHandshakeRecoveryRequired = { [weak self, weak service] request in
|
||||||
[weak self, weak service] request in
|
|
||||||
guard let self, let service else { return }
|
guard let self, let service else { return }
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
self._test_beforeHandshakeRecoveryEnqueued?(request.peerID)
|
self._test_beforeHandshakeRecoveryEnqueued?(request.peerID)
|
||||||
#endif
|
#endif
|
||||||
self.messageQueue.async {
|
self.messageQueue.async { [weak self, weak service] in
|
||||||
[weak self, weak service] in
|
|
||||||
guard let self,
|
guard let self,
|
||||||
let service,
|
let service,
|
||||||
self.noiseService === service else {
|
self.noiseService === service else {
|
||||||
@ -5294,8 +5290,7 @@ extension BLEService {
|
|||||||
) else {
|
) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageQueue.async {
|
messageQueue.async { [weak self, weak service] in
|
||||||
[weak self, weak service] in
|
|
||||||
guard let self,
|
guard let self,
|
||||||
let service,
|
let service,
|
||||||
self.noiseService === service,
|
self.noiseService === service,
|
||||||
|
|||||||
@ -108,6 +108,6 @@ struct QuickJoinSuggestion {
|
|||||||
"UY": "6c", "UZ": "tx", "VA": "sr", "VC": "dd",
|
"UY": "6c", "UZ": "tx", "VA": "sr", "VC": "dd",
|
||||||
"VE": "d9", "VI": "de", "VN": "w7", "VU": "rs",
|
"VE": "d9", "VI": "de", "VN": "w7", "VU": "rs",
|
||||||
"WS": "2j", "XK": "sr", "YE": "sf", "YT": "mj",
|
"WS": "2j", "XK": "sr", "YE": "sf", "YT": "mj",
|
||||||
"ZA": "ke", "ZM": "kt", "ZW": "ks",
|
"ZA": "ke", "ZM": "kt", "ZW": "ks"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1859,8 +1859,7 @@ private extension ChatMediaTransferCoordinator {
|
|||||||
TimeInterval(UInt64.max) / 1_000_000_000
|
TimeInterval(UInt64.max) / 1_000_000_000
|
||||||
) * 1_000_000_000
|
) * 1_000_000_000
|
||||||
)
|
)
|
||||||
reconnectRetryExpiryTasks[messageID] = Task {
|
reconnectRetryExpiryTasks[messageID] = Task { @MainActor [weak self] in
|
||||||
@MainActor [weak self] in
|
|
||||||
if nanoseconds > 0 {
|
if nanoseconds > 0 {
|
||||||
try? await Task.sleep(nanoseconds: nanoseconds)
|
try? await Task.sleep(nanoseconds: nanoseconds)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -482,7 +482,7 @@ private struct AutocompleteKeyboardNavigationModifier: ViewModifier {
|
|||||||
/// list is up. Inactive monitors pass everything through.
|
/// list is up. Inactive monitors pass everything through.
|
||||||
private func handleKeyDown(_ event: NSEvent) -> NSEvent? {
|
private func handleKeyDown(_ event: NSEvent) -> NSEvent? {
|
||||||
guard isActive(),
|
guard isActive(),
|
||||||
event.modifierFlags.intersection([.command, .option, .control]).isEmpty else {
|
event.modifierFlags.isDisjoint(with: [.command, .option, .control]) else {
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -653,8 +653,7 @@ struct ChatMediaTransferCoordinatorContextTests {
|
|||||||
|
|
||||||
@Test @MainActor
|
@Test @MainActor
|
||||||
func deleteStableMediaReleasesRetainedRetryBeforeTombstoneCommit()
|
func deleteStableMediaReleasesRetainedRetryBeforeTombstoneCommit()
|
||||||
async throws
|
async throws {
|
||||||
{
|
|
||||||
let context = MockChatMediaTransferContext()
|
let context = MockChatMediaTransferContext()
|
||||||
let peerID = PeerID(str: "1122334455667788")
|
let peerID = PeerID(str: "1122334455667788")
|
||||||
context.selectedPrivateChatPeer = peerID
|
context.selectedPrivateChatPeer = peerID
|
||||||
|
|||||||
@ -150,14 +150,12 @@ struct BLENoisePacketHandlerTests {
|
|||||||
recorder.clearedSessions.append(peerID)
|
recorder.clearedSessions.append(peerID)
|
||||||
service.clearSession(for: peerID)
|
service.clearSession(for: peerID)
|
||||||
},
|
},
|
||||||
handleAuthenticatedPeerState: {
|
handleAuthenticatedPeerState: { peerID, payload, generation in
|
||||||
peerID, payload, generation in
|
|
||||||
recorder.authenticatedPeerStates.append(
|
recorder.authenticatedPeerStates.append(
|
||||||
(peerID, payload, generation)
|
(peerID, payload, generation)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
deliverNoisePayload: {
|
deliverNoisePayload: { peerID, type, payload, timestamp in
|
||||||
peerID, type, payload, timestamp in
|
|
||||||
recorder.deliveries.append(
|
recorder.deliveries.append(
|
||||||
(peerID, type, payload, timestamp)
|
(peerID, type, payload, timestamp)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
// periphery:ignore - intentionally unreferenced by production code; nothing
|
||||||
|
// emits or consumes this type yet, and BLEService parses it only to ignore it.
|
||||||
|
// Delete this annotation when the mesh starts using it.
|
||||||
/// Identity-free presence announcement for rotating peer IDs.
|
/// Identity-free presence announcement for rotating peer IDs.
|
||||||
///
|
///
|
||||||
/// The v1 `AnnouncementPacket` broadcasts, in cleartext, every 4–30 seconds: the
|
/// The v1 `AnnouncementPacket` broadcasts, in cleartext, every 4–30 seconds: the
|
||||||
@ -37,9 +40,6 @@ import Foundation
|
|||||||
/// `docs/PEER-ID-ROTATION.md`.
|
/// `docs/PEER-ID-ROTATION.md`.
|
||||||
///
|
///
|
||||||
/// Not emitted or consumed by the shipping mesh yet.
|
/// Not emitted or consumed by the shipping mesh yet.
|
||||||
// periphery:ignore - intentionally unreferenced by production code; nothing
|
|
||||||
// emits or consumes this type yet, and BLEService parses it only to ignore it.
|
|
||||||
// Delete this annotation when the mesh starts using it.
|
|
||||||
public struct AnnounceV2Packet: Equatable, Sendable {
|
public struct AnnounceV2Packet: Equatable, Sendable {
|
||||||
/// Rotation epoch this announce was built for. Carried explicitly so a
|
/// Rotation epoch this announce was built for. Carried explicitly so a
|
||||||
/// receiver matches against a stated epoch instead of guessing.
|
/// receiver matches against a stated epoch instead of guessing.
|
||||||
|
|||||||
@ -9,6 +9,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
private import CryptoKit
|
private import CryptoKit
|
||||||
|
|
||||||
|
// periphery:ignore - intentionally unreferenced by production code. These are
|
||||||
|
// the reviewable primitives for a protocol change that cannot ship until both
|
||||||
|
// platforms agree on it; wiring them into the transport is the next step, not
|
||||||
|
// this one. Delete this annotation when the mesh starts using them.
|
||||||
/// Derivations for rotating peer IDs and pairwise recognition tags.
|
/// Derivations for rotating peer IDs and pairwise recognition tags.
|
||||||
///
|
///
|
||||||
/// See `docs/PEER-ID-ROTATION.md` for the design, the threat model, and the
|
/// See `docs/PEER-ID-ROTATION.md` for the design, the threat model, and the
|
||||||
@ -32,10 +36,6 @@ private import CryptoKit
|
|||||||
/// Recognition tags come from the X25519 shared secret between two static
|
/// Recognition tags come from the X25519 shared secret between two static
|
||||||
/// keys, so exactly two parties can compute a given tag and an observer can
|
/// keys, so exactly two parties can compute a given tag and an observer can
|
||||||
/// compute none of them.
|
/// compute none of them.
|
||||||
// periphery:ignore - intentionally unreferenced by production code. These are
|
|
||||||
// the reviewable primitives for a protocol change that cannot ship until both
|
|
||||||
// platforms agree on it; wiring them into the transport is the next step, not
|
|
||||||
// this one. Delete this annotation when the mesh starts using them.
|
|
||||||
public enum PeerIDRotation {
|
public enum PeerIDRotation {
|
||||||
// MARK: - Parameters
|
// MARK: - Parameters
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user