Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,19 @@ jobs:
rm -rf ~/Library/Developer/Xcode/DerivedData
rm -rf .build

- name: Create .env for CI
- name: Create dummy Secrets.swift for CI
run: |
cat > .env << 'EOF'
export OPENAI_API_KEY
cat > SwiftGPT/Secrets.swift << 'EOF'
//
// Secrets.swift
// SwiftGPT - CI Build
//

import Foundation

enum Secrets {
static let openaiApiKey = "dummy-key-for-ci-build"
}
EOF

- name: Resolve packages
Expand All @@ -47,14 +56,6 @@ jobs:
-project SwiftGPT.xcodeproj \
-scheme "SwiftGPT"

- name: Build SecretsManager plugin
run: |
set -euo pipefail
xcodebuild -scheme SecretsManager \
-destination 'platform=macOS' \
-derivedDataPath ./DerivedData \
build || echo "SecretsManager build skipped"

- name: Build (no code signing)
run: |
set -euo pipefail
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ profile
.idea/

# system files
.DS_Store
.DS_Store

# Secrets
Secrets.swift
**/Secrets.swift
118 changes: 96 additions & 22 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,51 +1,125 @@
excluded:
- "bin/*"
- "Script/*"
- "Generated/*"
- "Package.swift"
- "Resources/Localizables/Strings+Generated.swift"

disabled_rules:
- identifier_name
- inclusive_language
- type_name
- redundant_string_enum_value
- todo

analyzer_rules:
- explicit_self
- unused_declaration
- unused_import

opt_in_rules:
- array_init
- closure_spacing
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- cyclomatic_complexity
- discouraged_object_literal
- empty_collection_literal
- empty_count
- empty_string
- expiring_todo
- explicit_init
- fatal_error_message
- file_name_no_space
- first_where
- flatmap_over_map_reduce
- identical_operands
- joined_default_parameter
- last_where
- legacy_multiple
- legacy_random
- literal_expression_end_indentation
- modifier_order
- nimble_operator
- operator_usage_whitespace
- optional_enum_case_matching
- overridden_super_call
- prefer_self_type_over_type_of_self
- prohibited_super_call
- raw_value_for_camel_cased_codable_enum
- redundant_nil_coalescing
- required_enum_case
- sorted_first_last
- static_operator
- toggle_bool
- unneeded_parentheses_in_closure_argument
- untyped_error_in_catch
- vertical_whitespace_closing_braces
- yoda_condition
- comment_spacing
- function_body_length
- file_length
- line_length
- type_body_length
- nesting
- large_tuple
- vertical_whitespace
- force_cast
- force_try
- force_unwrapping
- implicitly_unwrapped_optional
- trailing_whitespace

line_length:
warning: 160
error: 200
warning: 180
error: 250
ignores_comments: true

function_body_length:
warning: 100
error: 160
warning: 120
error: 180

file_length:
warning: 400
warning: 500
error: 600

nesting:
type_level: 6
type_body_length:
warning: 500
error: 600

vertical_whitespace:
max_empty_lines: 1

nesting:
type_level: 6

large_tuple:
warning: 5
error: 6

opt_in_rules:
- force_cast # as!
- force_try # try!
- force_unwrapping # !
- implicitly_unwrapped_optional # !
- unneeded_parentheses_in_closure_argument # ()

force_cast:
severity: warning
severity: error

force_try:
severity: warning
severity: error

force_unwrapping:
severity: warning
severity: error

implicitly_unwrapped_optional:
severity: warning

disabled_rules:
- multiple_closures_with_trailing_closure
severity: error

custom_rules:
private_state_finder:
include: "*.swift"
name: "Private State"
regex: "(@State\\s+var)"
message: "States should be private."
severity: warning
sf_safe_symbol:
name: "Safe SFSymbol"
message: "Use `SFSafeSymbols` via `systemSymbol` parameters for type safety."
regex: "(Image\\(systemName:)|(NSImage\\(symbolName:)|(Label[^,]+?,\\s*systemImage:)|(UIApplicationShortcutIcon\\(systemImageName:)"
severity: error
severity: warning
17 changes: 17 additions & 0 deletions Resources/Localizables/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,20 @@
"dalle.error.image_conversion" = "Image conversion error";
"message.textfield.placeholder" = "Message...";
"chat.introduce.title" = "Write your first message!";
"error.network" = "Network error occurred";
"error.api" = "API request failed";
"error.unknown" = "An unexpected error occurred";
"error.save_photo" = "Failed to save image to Photos";
"error.save_photo_permission" = "Permission denied. Please allow access to Photos in Settings.";

// Accessibility
"accessibility.tab.chatgpt" = "Chat with GPT";
"accessibility.tab.dalle" = "Generate images with DALL·E";
"accessibility.button.send" = "Send message";
"accessibility.button.send.hint" = "Sends your message to the AI";
"accessibility.button.share" = "Share image";
"accessibility.button.save" = "Save image to photos";
"accessibility.textfield.message" = "Message input field";
"accessibility.image.generated" = "Generated image";
"accessibility.image.user" = "User avatar";
"accessibility.image.gpt" = "AI avatar";
44 changes: 44 additions & 0 deletions Resources/Localizables/Strings+Generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@ import Foundation
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
internal enum L10n {
internal enum Accessibility {
internal enum Button {
/// Save image to photos
internal static let save = L10n.tr("Localizable", "accessibility.button.save", fallback: "Save image to photos")
/// Send message
internal static let send = L10n.tr("Localizable", "accessibility.button.send", fallback: "Send message")
/// Share image
internal static let share = L10n.tr("Localizable", "accessibility.button.share", fallback: "Share image")
internal enum Send {
/// Sends your message to the AI
internal static let hint = L10n.tr("Localizable", "accessibility.button.send.hint", fallback: "Sends your message to the AI")
}
}
internal enum Image {
/// Generated image
internal static let generated = L10n.tr("Localizable", "accessibility.image.generated", fallback: "Generated image")
/// AI avatar
internal static let gpt = L10n.tr("Localizable", "accessibility.image.gpt", fallback: "AI avatar")
/// User avatar
internal static let user = L10n.tr("Localizable", "accessibility.image.user", fallback: "User avatar")
}
internal enum Tab {
/// Chat with GPT
internal static let chatgpt = L10n.tr("Localizable", "accessibility.tab.chatgpt", fallback: "Chat with GPT")
/// Generate images with DALL·E
internal static let dalle = L10n.tr("Localizable", "accessibility.tab.dalle", fallback: "Generate images with DALL·E")
}
internal enum Textfield {
/// Message input field
internal static let message = L10n.tr("Localizable", "accessibility.textfield.message", fallback: "Message input field")
}
}
internal enum Chat {
internal enum Introduce {
/// Write your first message!
Expand All @@ -32,6 +64,18 @@ internal enum L10n {
internal static let title = L10n.tr("Localizable", "dalle.tab.title", fallback: "DALL·E 2")
}
}
internal enum Error {
/// API request failed
internal static let api = L10n.tr("Localizable", "error.api", fallback: "API request failed")
/// Network error occurred
internal static let network = L10n.tr("Localizable", "error.network", fallback: "Network error occurred")
/// Failed to save image to Photos
internal static let savePhoto = L10n.tr("Localizable", "error.save_photo", fallback: "Failed to save image to Photos")
/// Permission denied. Please allow access to Photos in Settings.
internal static let savePhotoPermission = L10n.tr("Localizable", "error.save_photo_permission", fallback: "Permission denied. Please allow access to Photos in Settings.")
/// An unexpected error occurred
internal static let unknown = L10n.tr("Localizable", "error.unknown", fallback: "An unexpected error occurred")
}
internal enum Message {
internal enum Textfield {
/// Message...
Expand Down
Loading