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
26 changes: 4 additions & 22 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 17 additions & 11 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ let package = Package(
.iOS(.v16),
.tvOS(.v16),
.watchOS(.v9),
.visionOS(.v1),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "TranslationCatalog",
targets: [
Expand All @@ -31,16 +31,13 @@ let package = Package(
),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/richardpiazza/LocaleSupport.git", from: "0.8.1"),
.package(url: "https://github.com/richardpiazza/Statement.git", .upToNextMajor(from: "0.8.1")),
.package(url: "https://github.com/richardpiazza/CoreDataPlus.git", .upToNextMajor(from: "0.5.0")),
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMajor(from: "1.5.1")),
.package(url: "https://github.com/apple/swift-syntax.git", .upToNextMajor(from: "509.0.0")),
.package(url: "https://github.com/CoreOffice/XMLCoder.git", .upToNextMajor(from: "0.17.1")),
.package(url: "https://github.com/alexisakers/HTMLString.git", .upToNextMajor(from: "6.0.0")),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", .upToNextMajor(from: "0.15.4")),
.package(url: "https://github.com/richardpiazza/Statement.git", from: "0.8.1"),
.package(url: "https://github.com/richardpiazza/CoreDataPlus.git", from: "0.5.0"),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.7.1"),
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
.package(url: "https://github.com/CoreOffice/XMLCoder.git", from: "0.17.1"),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.16.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
Expand All @@ -65,7 +62,6 @@ let package = Package(
dependencies: [
"TranslationCatalog",
.product(name: "XMLCoder", package: "XMLCoder"),
.product(name: "HTMLString", package: "HTMLString"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
.product(name: "LocaleSupport", package: "LocaleSupport"),
Expand Down Expand Up @@ -119,3 +115,13 @@ let package = Package(
],
swiftLanguageVersions: [.v5]
)

for target in package.targets {
var settings = target.swiftSettings ?? []
settings.append(contentsOf: [
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("MemberImportVisibility"),
.enableUpcomingFeature("StrictConcurrency=complete"),
])
target.swiftSettings = settings
}
18 changes: 9 additions & 9 deletions Sources/TranslationCatalog/Catalog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ public protocol Catalog {
/// Retrieve all `Project`s that match the provided query parameters
///
/// - parameter query: Parameters that filter the results
func projects(matching query: CatalogQuery) throws -> [Project]
func projects(matching query: any CatalogQuery) throws -> [Project]
/// Retrieve a single project for the provided identifier.
///
/// - parameter id: The unique identifier for the `Project`
func project(_ id: Project.ID) throws -> Project
/// Retrieves the first `Project` matching the query
///
/// - parameter query: Parameters that filter the results
func project(matching query: CatalogQuery) throws -> Project
func project(matching query: any CatalogQuery) throws -> Project
/// Inserts a `Project` into the catalog.
///
/// - parameter project: The entity to insert.
Expand All @@ -27,7 +27,7 @@ public protocol Catalog {
///
/// - parameter id: The unique identifier for the `Project`
/// - parameter action: The update to perform on the entity matching the provided id.
func updateProject(_ id: Project.ID, action: CatalogUpdate) throws
func updateProject(_ id: Project.ID, action: any CatalogUpdate) throws
/// Removes a `Project` from the catalog.
///
/// This should remove the `Project` only. Any `Expression`s that were linked to the project should remain intact, as expressions
Expand All @@ -39,15 +39,15 @@ public protocol Catalog {
// MARK: - Expression

func expressions() throws -> [Expression]
func expressions(matching query: CatalogQuery) throws -> [Expression]
func expressions(matching query: any CatalogQuery) throws -> [Expression]
func expression(_ id: Expression.ID) throws -> Expression
func expression(matching query: CatalogQuery) throws -> Expression
func expression(matching query: any CatalogQuery) throws -> Expression
/// Insert a `Expression` into the catalog.
///
/// - parameter expression: The entity to insert.
/// - returns The unique identifier created for the new entity.
@discardableResult func createExpression(_ expression: Expression) throws -> Expression.ID
func updateExpression(_ id: Expression.ID, action: CatalogUpdate) throws
func updateExpression(_ id: Expression.ID, action: any CatalogUpdate) throws
/// Remove a `Expression` from the catalog.
///
/// When removed, the `Translation`s linked to the expression should be removed - as well as - any references that
Expand All @@ -59,9 +59,9 @@ public protocol Catalog {
// MARK: - Translation

func translations() throws -> [Translation]
func translations(matching query: CatalogQuery) throws -> [Translation]
func translations(matching query: any CatalogQuery) throws -> [Translation]
func translation(_ id: Translation.ID) throws -> Translation
func translation(matching query: CatalogQuery) throws -> Translation
func translation(matching query: any CatalogQuery) throws -> Translation
/// Insert a `Translation` into the catalog.
///
/// - parameter translation: The entity to insert.
Expand All @@ -71,7 +71,7 @@ public protocol Catalog {
///
/// - parameter id: The unique identifier for the `Translation`.
/// - parameter action: The update to perform on the entity matching the provided id.
func updateTranslation(_ id: Translation.ID, action: CatalogUpdate) throws
func updateTranslation(_ id: Translation.ID, action: any CatalogUpdate) throws
/// Remove a `Translation` from the catalog.
///
/// - parameter id: The unique identifier for the `Translation`.
Expand Down
6 changes: 3 additions & 3 deletions Sources/TranslationCatalog/CatalogError.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
public enum CatalogError: Error {
case badQuery(CatalogQuery)
case badQuery(any CatalogQuery)
case dataTypeConversion(String? = nil)
case expressionExistingWithId(Expression.ID, Expression)
case expressionExistingWithKey(String, Expression)
Expand All @@ -9,6 +9,6 @@ public enum CatalogError: Error {
case translationExistingWithId(Translation.ID, Translation)
case translationExistingWithValue(String, Translation)
case translationId(Translation.ID)
case unhandledQuery(CatalogQuery)
case unhandledUpdate(CatalogUpdate)
case unhandledQuery(any CatalogQuery)
case unhandledUpdate(any CatalogUpdate)
}
2 changes: 1 addition & 1 deletion Sources/TranslationCatalog/CatalogQuery.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Associated parameters for performing query operations
public protocol CatalogQuery {}
public protocol CatalogQuery: Sendable {}

public enum GenericProjectQuery: CatalogQuery {
case id(Project.ID)
Expand Down
2 changes: 1 addition & 1 deletion Sources/TranslationCatalog/CatalogUpdate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Associated parameters when performing update operations
public protocol CatalogUpdate {}
public protocol CatalogUpdate: Sendable {}

public enum GenericProjectUpdate: CatalogUpdate {
case name(String)
Expand Down
4 changes: 2 additions & 2 deletions Sources/TranslationCatalogCoreData/CoreDataCatalog.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#if canImport(CoreData)
import CoreData
@preconcurrency import CoreData
import CoreDataPlus
import Foundation
import TranslationCatalog
@preconcurrency import TranslationCatalog

public class CoreDataCatalog: TranslationCatalog.Catalog {

Expand Down Expand Up @@ -47,7 +47,7 @@
public func projects() throws -> [TranslationCatalog.Project] {
try viewContext
.performAndWait {
try viewContext

Check warning on line 50 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (watchOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure

Check warning on line 50 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure
.fetch(ProjectEntity.fetchRequest())
.map {
try TranslationCatalog.Project($0)
Expand All @@ -68,7 +68,7 @@
}

return try viewContext.performAndWait {
try viewContext

Check warning on line 71 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (watchOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure

Check warning on line 71 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure
.fetch(request)
.map {
try TranslationCatalog.Project($0)
Expand All @@ -89,7 +89,7 @@
request.predicate = NSPredicate(format: "%K == %@", argumentArray: ["id", id])

project = try viewContext.performAndWait {
guard let entity = try viewContext.fetch(request).first else {

Check warning on line 92 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure
throw CatalogError.projectId(id)
}

Expand All @@ -99,7 +99,7 @@
request.predicate = NSPredicate(format: "%K == %@", "name", named)

project = try viewContext.performAndWait {
guard let entity = try viewContext.fetch(request).first else {

Check warning on line 102 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

capture of 'self' with non-Sendable type 'CoreDataCatalog' in a '@sendable' closure
throw CatalogError.badQuery(query)
}

Expand Down Expand Up @@ -127,7 +127,7 @@
let context = container.persistentContainer.newBackgroundContext()
try context.performAndWait {
let entity: ProjectEntity = context.make()
entity.id = id

Check warning on line 130 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

reference to captured var 'id' in concurrently-executing code
entity.name = project.name
try entity.addExpressions(project.expressions, context: context)
try context.save()
Expand All @@ -149,7 +149,7 @@
switch action {
case GenericProjectUpdate.name(let name):
try context.performAndWait {
projectEntity.name = name

Check warning on line 152 in Sources/TranslationCatalogCoreData/CoreDataCatalog.swift

View workflow job for this annotation

GitHub Actions / Xcode (tvOS)

capture of 'projectEntity' with non-Sendable type 'ProjectEntity' in a '@sendable' closure
try context.save()
}
case GenericProjectUpdate.linkExpression(let expressionId):
Expand Down
18 changes: 9 additions & 9 deletions Sources/TranslationCatalogFilesystem/FilesystemContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ extension FilesystemContainer {
}
}

public func projects(matching query: CatalogQuery) throws -> [Project] {
public func projects(matching query: any CatalogQuery) throws -> [Project] {
let documents: [ProjectDocument]

switch query {
Expand All @@ -158,7 +158,7 @@ extension FilesystemContainer {
try project(matching: GenericProjectQuery.id(id))
}

public func project(matching query: CatalogQuery) throws -> Project {
public func project(matching query: any CatalogQuery) throws -> Project {
let document: ProjectDocument

switch query {
Expand Down Expand Up @@ -212,7 +212,7 @@ extension FilesystemContainer {
return id
}

public func updateProject(_ id: Project.ID, action: CatalogUpdate) throws {
public func updateProject(_ id: Project.ID, action: any CatalogUpdate) throws {
guard let index = projectDocuments.firstIndex(where: { $0.id == id }) else {
throw CatalogError.projectId(id)
}
Expand Down Expand Up @@ -249,7 +249,7 @@ extension FilesystemContainer {
}
}

public func expressions(matching query: CatalogQuery) throws -> [TranslationCatalog.Expression] {
public func expressions(matching query: any CatalogQuery) throws -> [TranslationCatalog.Expression] {
switch query {
case GenericExpressionQuery.projectId(let projectId):
return try project(projectId).expressions
Expand Down Expand Up @@ -359,7 +359,7 @@ extension FilesystemContainer {
try expression(matching: GenericExpressionQuery.id(id))
}

public func expression(matching query: CatalogQuery) throws -> TranslationCatalog.Expression {
public func expression(matching query: any CatalogQuery) throws -> TranslationCatalog.Expression {
let document: ExpressionDocument

switch query {
Expand Down Expand Up @@ -423,7 +423,7 @@ extension FilesystemContainer {
return id
}

public func updateExpression(_ id: TranslationCatalog.Expression.ID, action: CatalogUpdate) throws {
public func updateExpression(_ id: TranslationCatalog.Expression.ID, action: any CatalogUpdate) throws {
guard let index = expressionDocuments.firstIndex(where: { $0.id == id }) else {
throw CatalogError.expressionId(id)
}
Expand Down Expand Up @@ -493,7 +493,7 @@ extension FilesystemContainer {
}
}

public func translations(matching query: CatalogQuery) throws -> [Translation] {
public func translations(matching query: any CatalogQuery) throws -> [Translation] {
var documents: [TranslationDocument]

switch query {
Expand Down Expand Up @@ -532,7 +532,7 @@ extension FilesystemContainer {
try translation(matching: GenericTranslationQuery.id(id))
}

public func translation(matching query: CatalogQuery) throws -> Translation {
public func translation(matching query: any CatalogQuery) throws -> Translation {
switch query {
case GenericTranslationQuery.id(let uuid):
guard let document = translationDocuments.first(where: { $0.id == uuid }) else {
Expand Down Expand Up @@ -589,7 +589,7 @@ extension FilesystemContainer {
return id
}

public func updateTranslation(_ id: Translation.ID, action: CatalogUpdate) throws {
public func updateTranslation(_ id: Translation.ID, action: any CatalogUpdate) throws {
guard let index = translationDocuments.firstIndex(where: { $0.id == id }) else {
throw CatalogError.translationId(id)
}
Expand Down
14 changes: 7 additions & 7 deletions Sources/TranslationCatalogIO/ExpressionImporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ public class ExpressionImporter {
public enum Operation: CustomStringConvertible {
case createdExpression(TranslationCatalog.Expression)
case skippedExpression(TranslationCatalog.Expression)
case failedExpression(TranslationCatalog.Expression, Error)
case failedExpression(TranslationCatalog.Expression, any Error)
case createdTranslation(Translation)
case skippedTranslation(Translation)
case failedTranslation(Translation, Error)
case failedTranslation(Translation, any Error)

public var description: String {
switch self {
Expand All @@ -29,10 +29,10 @@ public class ExpressionImporter {
}
}

private let catalog: Catalog
private let catalog: any Catalog
private let sequence = AsyncStream.makeStream(of: Operation.self)

public init(catalog: Catalog) {
public init(catalog: any Catalog) {
self.catalog = catalog
}

Expand All @@ -55,7 +55,7 @@ public class ExpressionImporter {
sequence.continuation.finish()
}

private func importExpression(_ expression: TranslationCatalog.Expression, into catalog: Catalog) {
private func importExpression(_ expression: TranslationCatalog.Expression, into catalog: any Catalog) {
do {
try catalog.createExpression(expression)
sequence.continuation.yield(.createdExpression(expression))
Expand All @@ -67,7 +67,7 @@ public class ExpressionImporter {
}
}

private func importTranslations(_ expression: TranslationCatalog.Expression, into catalog: Catalog) {
private func importTranslations(_ expression: TranslationCatalog.Expression, into catalog: any Catalog) {
guard let id = try? catalog.expression(matching: GenericExpressionQuery.key(expression.key)).id else {
return
}
Expand All @@ -82,7 +82,7 @@ public class ExpressionImporter {
}
}

private func importTranslation(_ translation: Translation, into catalog: Catalog) {
private func importTranslation(_ translation: Translation, into catalog: any Catalog) {
do {
try catalog.createTranslation(translation)
sequence.continuation.yield(.createdTranslation(translation))
Expand Down
2 changes: 2 additions & 0 deletions Sources/TranslationCatalogIO/FileFormat.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Foundation

/// Known/handled file types of expression/translation lists.
public enum FileFormat: CaseIterable {
/// Android-compatible XML format
Expand Down
2 changes: 2 additions & 0 deletions Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
import LocaleSupport
import SwiftBasicFormat
import SwiftSyntax

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (iOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (iOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (visionOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (visionOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (macOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'

Check warning on line 4 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (macOS)

add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'SwiftSyntax'
import SwiftSyntaxBuilder
import TranslationCatalog

Expand Down Expand Up @@ -42,7 +44,7 @@
}

extension ImportDeclSyntax {
static let localeSupport: ImportDeclSyntax = ImportDeclSyntax(

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (iOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (iOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (visionOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (visionOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (macOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (macOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode

Check warning on line 47 in Sources/TranslationCatalogIO/KeyHierarchy+Syntax.swift

View workflow job for this annotation

GitHub Actions / Xcode (macOS)

static property 'localeSupport' is not concurrency-safe because non-'Sendable' type 'ImportDeclSyntax' may have shared mutable state; this is an error in the Swift 6 language mode
path: ImportPathComponentListSyntax {
ImportPathComponentSyntax(name: TokenSyntax("LocaleSupport"))
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/TranslationCatalogIO/MarkdownTable.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Foundation

/// Creates a markdown formatted table when printed.
public class MarkdownTable<T: Collection>: CustomStringConvertible {

Expand Down
16 changes: 8 additions & 8 deletions Sources/TranslationCatalogSQLite/Entities/ExpressionEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ extension ExpressionEntity {

extension ExpressionEntity {
static let entity = ExpressionEntity()
static var id: Attribute { entity["id"]! }
static var uuid: Attribute { entity["uuid"]! }
static var key: Attribute { entity["key"]! }
static var name: Attribute { entity["name"]! }
static var defaultLanguage: Attribute { entity["default_language"]! }
static var defaultValue: Attribute { entity["default_value"]! }
static var context: Attribute { entity["context"]! }
static var feature: Attribute { entity["feature"]! }
static var id: any Attribute { entity["id"]! }
static var uuid: any Attribute { entity["uuid"]! }
static var key: any Attribute { entity["key"]! }
static var name: any Attribute { entity["name"]! }
static var defaultLanguage: any Attribute { entity["default_language"]! }
static var defaultValue: any Attribute { entity["default_value"]! }
static var context: any Attribute { entity["context"]! }
static var feature: any Attribute { entity["feature"]! }

init(_ expression: TranslationCatalog.Expression) {
uuid = expression.id.uuidString
Expand Down
Loading
Loading