Commit 48eb4d9dbf
48eb4d9dbf5408636b96f05510ffc13be8e84fdc
parent: fe4dc49efe
Verified · cmc
cmc <hello@cleberg.net> · 2026-09-17 15:03 UTC
Add KeycaskError with exit codes
Layout: unified · split
Sources/KeycaskCore/KeycaskCore.swift
deleted
−3
| @@ -1,3 +0,0 @@ |
| 1 | public enum KeycaskCore { |
| |
| 2 | public static let name = "keycask" |
| |
| 3 | } |
| |
Sources/KeycaskCore/KeycaskError.swift
added
+38
| @@ -0,0 +1,38 @@ |
| |
1 | public enum KeycaskError: Error, Equatable, Sendable { |
| |
2 | case notFound(String) |
| |
3 | case ambiguous(name: String, candidates: [String]) |
| |
4 | case cannotDecrypt |
| |
5 | case corrupt(String) |
| |
6 | case vaultExists(String) |
| |
7 | case noVault(String) |
| |
8 | case duplicateID(String) |
| |
9 | case io(String) |
| |
10 | case usage(String) |
| |
11 | case failure(String) |
| |
12 | |
| |
13 | public var exitCode: Int32 { |
| |
14 | switch self { |
| |
15 | case .failure, .io, .corrupt, .vaultExists, .duplicateID: 1 |
| |
16 | case .usage: 2 |
| |
17 | case .notFound, .noVault: 3 |
| |
18 | case .cannotDecrypt: 4 |
| |
19 | case .ambiguous: 5 |
| |
20 | } |
| |
21 | } |
| |
22 | |
| |
23 | public var message: String { |
| |
24 | switch self { |
| |
25 | case .notFound(let what): "\(what): not found" |
| |
26 | case .ambiguous(let name, let candidates): |
| |
27 | (["\(name): ambiguous, use an id:"] + candidates).joined(separator: "\n") |
| |
28 | case .cannotDecrypt: "cannot decrypt: wrong passphrase or damaged vault" |
| |
29 | case .corrupt(let why): "vault is corrupt: \(why)" |
| |
30 | case .vaultExists(let path): "vault \(path) already exists" |
| |
31 | case .noVault(let path): "vault \(path) not found (run `keycask init`)" |
| |
32 | case .duplicateID(let id): "duplicate id \(id)" |
| |
33 | case .io(let why): why |
| |
34 | case .usage(let why): why |
| |
35 | case .failure(let why): why |
| |
36 | } |
| |
37 | } |
| |
38 | } |
Sources/keycask/main.swift
+1 −1
| @@ -1,3 +1,3 @@ |
| 1 | import KeycaskCore |
1 | import KeycaskCore |
| 2 | |
2 | |
| 3 | print(KeycaskCore.name) |
3 | print("keycask") |
Tests/KeycaskCoreTests/KeycaskErrorTests.swift
added
+28
| @@ -0,0 +1,28 @@ |
| |
1 | import Testing |
| |
2 | |
| |
3 | @testable import KeycaskCore |
| |
4 | |
| |
5 | @Suite struct KeycaskErrorTests { |
| |
6 | @Test func exitCodesFollowTheSpec() { |
| |
7 | #expect(KeycaskError.failure("x").exitCode == 1) |
| |
8 | #expect(KeycaskError.io("x").exitCode == 1) |
| |
9 | #expect(KeycaskError.corrupt("x").exitCode == 1) |
| |
10 | #expect(KeycaskError.vaultExists("x").exitCode == 1) |
| |
11 | #expect(KeycaskError.duplicateID("abcd2345").exitCode == 1) |
| |
12 | #expect(KeycaskError.usage("x").exitCode == 2) |
| |
13 | #expect(KeycaskError.notFound("x").exitCode == 3) |
| |
14 | #expect(KeycaskError.noVault("/p").exitCode == 3) |
| |
15 | #expect(KeycaskError.cannotDecrypt.exitCode == 4) |
| |
16 | #expect(KeycaskError.ambiguous(name: "gh", candidates: []).exitCode == 5) |
| |
17 | } |
| |
18 | |
| |
19 | @Test func messagesNameTheSubject() { |
| |
20 | #expect(KeycaskError.notFound("gh").message == "gh: not found") |
| |
21 | #expect(KeycaskError.noVault("/v").message == "vault /v not found (run `keycask init`)") |
| |
22 | #expect(KeycaskError.vaultExists("/v").message == "vault /v already exists") |
| |
23 | #expect( |
| |
24 | KeycaskError.cannotDecrypt.message |
| |
25 | == "cannot decrypt: wrong passphrase or damaged vault") |
| |
26 | #expect(KeycaskError.corrupt("bad json").message == "vault is corrupt: bad json") |
| |
27 | } |
| |
28 | } |
Tests/KeycaskCoreTests/SmokeTests.swift
deleted
−7
| @@ -1,7 +0,0 @@ |
| 1 | import Testing |
| |
| 2 | |
| |
| 3 | @testable import KeycaskCore |
| |
| 4 | |
| |
| 5 | @Test func packageBuilds() { |
| |
| 6 | #expect(KeycaskCore.name == "keycask") |
| |
| 7 | } |
| |