aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-16 10:18:40 -0500
committerChristian Cleberg <[email protected]>2026-07-16 10:18:40 -0500
commite93972f39150e5e590e49aaf46a369c463277c30 (patch)
tree2eb72968c1101155db1ee97e74367eb6491cd86b
parent9834b780b24a1dd617fa761155712920159f3d8d (diff)
downloadhutch-e93972f39150e5e590e49aaf46a369c463277c30.tar.gz
hutch-e93972f39150e5e590e49aaf46a369c463277c30.tar.bz2
hutch-e93972f39150e5e590e49aaf46a369c463277c30.zip
chore: clear the actionable SonarCloud code smells
- S1871: merge the identical .home / .recentActivity deep-link cases in RootView — recent activity is a section of Home, not its own screen. - S1186: comment the two intentionally-empty Cancel buttons (PatchsetDetailView, TicketDetailView) and the empty URLProtocol stopLoading override in APICacheTests. - S108: comment the expected-miss catch block in APICacheTests. - S1172: rename the unused url parameter in mimeType(for:) to _. - S4624: extract the nested template literal in the deep-link builders (background.js, content.js) to a pathSegment variable. Left as Won't Fix, with reasons: the 35 hardcoded-URI warnings (a one-forge client and its literal-URL tests), executeCached's 8 params (38 call sites, no benefit), the forceRefresh S1172 pair (fixed as a real bug instead), S1481 on ArtifactsView (false positive — $vm.error is used), and S7785 (top-level await would break a classic content script).
-rw-r--r--Hutch/App/RootView.swift8
-rw-r--r--Hutch/Views/Patchsets/PatchsetDetailView.swift2
-rw-r--r--Hutch/Views/Repositories/RepositoryDetailViewModel.swift2
-rw-r--r--Hutch/Views/Tickets/TicketDetailView.swift2
-rw-r--r--HutchSafariExtension/Resources/background.js3
-rw-r--r--HutchSafariExtension/Resources/content.js3
-rw-r--r--HutchTests/APICacheTests.swift3
7 files changed, 12 insertions, 11 deletions
diff --git a/Hutch/App/RootView.swift b/Hutch/App/RootView.swift
index 10720ad..2e16718 100644
--- a/Hutch/App/RootView.swift
+++ b/Hutch/App/RootView.swift
@@ -198,11 +198,9 @@ struct RootView: View {
}
switch link {
- case .home:
- homePath = NavigationPath()
- appState.selectedTab = .home
-
- case .recentActivity:
+ // Recent activity is a section of the Home tab, not a screen of its
+ // own, so its intent/widget deep link lands on Home like .home does.
+ case .home, .recentActivity:
homePath = NavigationPath()
appState.selectedTab = .home
diff --git a/Hutch/Views/Patchsets/PatchsetDetailView.swift b/Hutch/Views/Patchsets/PatchsetDetailView.swift
index f560326..91aa417 100644
--- a/Hutch/Views/Patchsets/PatchsetDetailView.swift
+++ b/Hutch/Views/Patchsets/PatchsetDetailView.swift
@@ -71,7 +71,7 @@ struct PatchsetDetailView: View {
Task { await viewModel.updateStatus(to: status) }
}
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) {} // dismisses the dialog; no action needed
}
.alert(
"Couldn't Update Patchset",
diff --git a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
index 9b6b942..82e1592 100644
--- a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
+++ b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
@@ -627,7 +627,7 @@ final class RepositoryDetailViewModel {
/// Artifacts are release tarballs and signatures rather than media, so a
/// generic binary type is honest more often than guessing from the extension.
- private nonisolated static func mimeType(for url: URL) -> String {
+ private nonisolated static func mimeType(for _: URL) -> String {
"application/octet-stream"
}
diff --git a/Hutch/Views/Tickets/TicketDetailView.swift b/Hutch/Views/Tickets/TicketDetailView.swift
index b114fa6..1705a73 100644
--- a/Hutch/Views/Tickets/TicketDetailView.swift
+++ b/Hutch/Views/Tickets/TicketDetailView.swift
@@ -204,7 +204,7 @@ struct TicketDetailView: View {
}
}
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) {} // dismisses the dialog; no action needed
} message: {
Text("This permanently deletes the ticket and its comments. This cannot be undone.")
}
diff --git a/HutchSafariExtension/Resources/background.js b/HutchSafariExtension/Resources/background.js
index 81bf8b6..0147de0 100644
--- a/HutchSafariExtension/Resources/background.js
+++ b/HutchSafariExtension/Resources/background.js
@@ -68,7 +68,8 @@ function hutchDeepLinkFor(rawURL) {
const path = deepLinkPath(url.hostname, normalizedPath(url.pathname));
const service = deepLinkService(url.hostname, path);
- return `hutch://${service}${path ? `/${path}` : ""}${url.search}${url.hash}`;
+ const pathSegment = path ? `/${path}` : "";
+ return `hutch://${service}${pathSegment}${url.search}${url.hash}`;
}
function showUnsupportedMessage(tabId) {
diff --git a/HutchSafariExtension/Resources/content.js b/HutchSafariExtension/Resources/content.js
index dba7c5d..e5cb087 100644
--- a/HutchSafariExtension/Resources/content.js
+++ b/HutchSafariExtension/Resources/content.js
@@ -63,7 +63,8 @@ function hutchDeepLinkForLocation() {
const path = hutchDeepLinkPath(location.hostname, hutchNormalizedPath(location.pathname));
const service = hutchDeepLinkService(location.hostname, path);
- return `hutch://${service}${path ? `/${path}` : ""}${location.search}${location.hash}`;
+ const pathSegment = path ? `/${path}` : "";
+ return `hutch://${service}${pathSegment}${location.search}${location.hash}`;
}
function storageGet(defaults) {
diff --git a/HutchTests/APICacheTests.swift b/HutchTests/APICacheTests.swift
index 89c6c53..a03e6f9 100644
--- a/HutchTests/APICacheTests.swift
+++ b/HutchTests/APICacheTests.swift
@@ -256,6 +256,7 @@ struct APICacheTests {
_ = try await cache.read(cacheKey: key)
Issue.record("Expected cache miss for \(key).")
} catch APICacheError.miss {
+ // expected: a miss is the success path here
} catch {
Issue.record("Unexpected error for \(key): \(error).")
}
@@ -293,7 +294,7 @@ private final class CachedURLProtocol: URLProtocol, @unchecked Sendable {
}
}
- override func stopLoading() {}
+ override func stopLoading() {} // required override; nothing to tear down
static func reset(responses: [CachedURLProtocolResponse], responseDelay: TimeInterval = 0) {
Self.responses = responses