From c4a1ce759f1a29dc6528bd45c330a1200ea4d6d1 Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Sun, 30 Nov 2025 13:39:43 +0900 Subject: [PATCH 1/2] Add SwiftLint configuration and CI enforcement --- .github/workflows/build-and-test.yml | 6 ++++ .swiftlint.yml | 47 ++++++++++++++++++++++++++++ AGENTS.md | 3 ++ AsyncImageView/Caching.swift | 29 +++++++++++++---- 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 .swiftlint.yml create mode 100644 AGENTS.md diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index cd49a706..6e9e4150 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -27,3 +27,9 @@ jobs: action: test warnings-as-errors: false verbosity: xcbeautify + + - name: Install SwiftLint + run: brew install swiftlint + + - name: Run SwiftLint + run: swiftlint --config .swiftlint.yml --reporter github-actions-logging diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 00000000..79652c2f --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,47 @@ +included: + - AsyncImageView + - AsyncImageViewTests + - Example + - Package.swift + +excluded: + - .build + - .swiftpm + - Carthage + - Example/Carthage + - Example/Pods + - Docs + +opt_in_rules: + - empty_count + - explicit_init + - overridden_super_call + - redundant_nil_coalescing + +analyzer_rules: + - unused_import + - unused_optional_binding + +disabled_rules: + - closure_parameter_position + - comma + - colon + - control_statement + - force_cast + - function_body_length + - function_name_whitespace + - identifier_name + - line_length + - nesting + - opening_brace + - private_over_fileprivate + - return_arrow_whitespace + - todo + - trailing_comma + - trailing_newline + - trailing_whitespace + - type_body_length + - unneeded_synthesized_initializer + - vertical_parameter_alignment + - vertical_whitespace + - void_return diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..a5a1ab34 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,3 @@ +# Agent Instructions + +- Always run `swiftlint --config .swiftlint.yml` from the repository root before submitting changes. This lints the AsyncImageView codebase with the shared configuration. diff --git a/AsyncImageView/Caching.swift b/AsyncImageView/Caching.swift index ab7c6cb7..4e1d9266 100644 --- a/AsyncImageView/Caching.swift +++ b/AsyncImageView/Caching.swift @@ -102,9 +102,14 @@ public protocol NSDataConvertible { /// Returns the directory where all `DiskCache` caches are stored /// by default. public func diskCacheDefaultCacheDirectory() -> URL { - return try! FileManager() - .url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) - .appendingPathComponent("AsyncImageView", isDirectory: true) + do { + return try FileManager() + .url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) + .appendingPathComponent("AsyncImageView", isDirectory: true) + } catch { + assertionFailure("Failed to resolve caches directory: \(error)") + return FileManager.default.temporaryDirectory.appendingPathComponent("AsyncImageView", isDirectory: true) + } } /// `CacheType` backed by files on disk. @@ -138,9 +143,17 @@ public final class DiskCache: CacheType { self.guaranteeDirectoryExists(url.deletingLastPathComponent()) if let data = value.flatMap({ $0.data }) { - try! data.write(to: url, options: .atomicWrite) + do { + try data.write(to: url, options: .atomicWrite) + } catch { + assertionFailure("Failed to persist cache entry at \(url): \(error)") + } } else if self.fileManager.fileExists(atPath: url.path) { - try! self.fileManager.removeItem(at: url) + do { + try self.fileManager.removeItem(at: url) + } catch { + assertionFailure("Failed to delete cache entry at \(url): \(error)") + } } } } @@ -165,6 +178,10 @@ public final class DiskCache: CacheType { } private func guaranteeDirectoryExists(_ url: URL) { - try! self.fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + do { + try self.fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + } catch { + assertionFailure("Failed to create cache directory at \(url): \(error)") + } } } From 830eaf6d9b302fd87ea2d61674f8ba45979be4aa Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Sun, 30 Nov 2025 13:42:02 +0900 Subject: [PATCH 2/2] Update .swiftlint.yml --- .swiftlint.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 79652c2f..97111aac 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,13 +1,11 @@ included: - AsyncImageView - AsyncImageViewTests - - Example - Package.swift excluded: - .build - .swiftpm - - Carthage - Example/Carthage - Example/Pods - Docs @@ -23,25 +21,11 @@ analyzer_rules: - unused_optional_binding disabled_rules: - - closure_parameter_position - - comma - - colon - - control_statement - force_cast - function_body_length - - function_name_whitespace - identifier_name - line_length - nesting - - opening_brace - private_over_fileprivate - - return_arrow_whitespace - todo - - trailing_comma - - trailing_newline - - trailing_whitespace - type_body_length - - unneeded_synthesized_initializer - - vertical_parameter_alignment - - vertical_whitespace - - void_return