[Setup] Non Apple platforms #13

Merged
javier merged 14 commits from setup/linux-support into main 2023-04-28 17:37:09 +00:00
21 changed files with 232 additions and 75 deletions

2
.gitignore vendored
View File

@ -1,5 +1,6 @@
.DS_Store .DS_Store
/.build /.build
/.vscode
/Packages /Packages
/*.xcodeproj /*.xcodeproj
xcuserdata/ xcuserdata/
@ -7,3 +8,4 @@ DerivedData/
.swiftpm/config/registries.json .swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc .netrc
.env

87
Makefile Normal file
View File

@ -0,0 +1,87 @@
# --- IMPORTS ---
# Imports environment variables.
environment_vars ?= .env
include $(environment_vars)
export $(shell sed 's/=.*//' $(environment_vars))
# --- ARGUMENTS ---
override docker?=${CLI_USE_DOCKER}
override tag?=${DOCKER_IMAGE_TAG}
override platform?=${DOCKER_IMAGE_PLATFORM}
override config?=${SWIFT_BUILD_CONFIGURATION}
override clean?=${DOCKER_IMAGE_CLEAN}
# --- DEPENDENCIES ---
outdated: ## List the package dependencies that can be updated.
@swift package update --dry-run
update: ## Update the package dependencies defined in the project.
@swift package update
# --- DEVELOPMENT ---
build: ## Build this package with Swift either locally or in a Docker image.
ifeq ($(docker),yes)
@-docker run \
--rm \
--volume ${PWD}:${DOCKER_VOLUME_TARGET} \
--workdir ${DOCKER_VOLUME_TARGET} \
--platform ${platform} \
${DOCKER_IMAGE_NAME}:${tag} \
swift build --configuration ${config}
ifeq ($(clean),yes)
@docker rmi ${DOCKER_IMAGE_NAME}:${tag}
endif
else
@swift build --configuration ${config}
endif
# --- TESTING ---
test: ## Test this package with Swift either locally or in a Docker image.
ifeq ($(docker),yes)
@-docker run \
--rm \
--volume ${PWD}:${DOCKER_VOLUME_TARGET} \
--workdir ${DOCKER_VOLUME_TARGET} \
--platform ${platform} \
${DOCKER_IMAGE_NAME}:${tag} \
swift test --configuration ${config}
ifeq ($(clean),yes)
@docker rmi ${DOCKER_IMAGE_NAME}:${tag}
endif
else
@swift test --configuration ${config}
endif
# --- HOUSE-KEEPING ---
clean: ## Clean the build artifacts of the package.
@swift package clean
reset: ## Reset the build folder of the package.
@swift package reset
flush-images: ## Flush all outstanding Swift docker images.
@docker images \
--all | grep ${DOCKER_IMAGE_NAME} | awk '{print $$3}' | xargs docker rmi --force
# --- MISCELLANEOUS ---
xcode: ## Open this package in Xcode.
@open -a Xcode Package.swift
# --- HELP ---
# Outputs the documentation for each of the defined tasks when `help` is called.
# Reference: https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
.PHONY: help
help: ## Prints the written documentation for all the defined tasks.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
.DEFAULT_GOAL := help

View File

@ -1,4 +1,4 @@
// swift-tools-version: 5.5 // swift-tools-version: 5.7
// //
// This source file is part of the SwiftLibs open source project // This source file is part of the SwiftLibs open source project
// //
@ -11,14 +11,86 @@
import PackageDescription import PackageDescription
private var excludePlatforms: [String] = [.PlatformFolder.iOS] // MARK: - Variables
#if os(iOS) private var targetsLibrary: [String] = [
excludePlatforms = [] .Target.communications,
.Target.coordination,
.Target.core,
.Target.dependencies,
]
private var targetsPackage: [Target] = [
.target(
name: .Target.communications,
dependencies: []
),
.target(
name: .Target.coordination,
dependencies: []
),
.target(
name: .Target.core,
dependencies: []
),
.target(
name: .Target.dependencies,
dependencies: []
),
.testTarget(
name: "CommunicationsTests",
dependencies: [
.init(stringLiteral: .Target.communications)
],
path: "Tests/Communications"
),
.testTarget(
name: "CoordinationTests",
dependencies: [
.init(stringLiteral: .Target.coordination)
],
path: "Tests/Coordination"
),
.testTarget(
name: "CoreTests",
dependencies: [
.init(stringLiteral: .Target.core)
],
path: "Tests/Core"
),
.testTarget(
name: "DependenciesTests",
dependencies: [
.init(stringLiteral: .Target.dependencies)
],
path: "Tests/Dependencies"
),
]
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
targetsLibrary.append(.Target.persistence)
targetsPackage.append(contentsOf: [
.target(
name: .Target.persistence,
dependencies: []
),
.testTarget(
name: "PersistenceTests",
dependencies: [
.init(stringLiteral: .Target.persistence)
],
path: "Tests/Persistence",
resources: [
.process("Resources")
]
),
])
#endif #endif
// MARK: - Package
let package = Package( let package = Package(
name: "SwiftLibs", name: .Package.name,
platforms: [ platforms: [
.iOS(.v15), .iOS(.v15),
.macOS(.v12), .macOS(.v12),
@ -27,82 +99,26 @@ let package = Package(
], ],
products: [ products: [
.library( .library(
name: "SwiftLibs", name: .Package.name,
targets: [ targets: targetsLibrary
"Communications",
"Coordination",
"Core",
"Dependencies",
"Persistence"
]
), ),
], ],
dependencies: [], dependencies: [],
targets: [ targets: targetsPackage
.target(
name: "Communications",
dependencies: []
),
.target(
name: "Coordination",
dependencies: [],
exclude: excludePlatforms
),
.target(
name: "Core",
dependencies: []
),
.target(
name: "Dependencies",
dependencies: []
),
.target(
name: "Persistence",
dependencies: []
),
.testTarget(
name: "CommunicationsTests",
dependencies: [
"Communications"
],
path: "Tests/Communications"
),
.testTarget(
name: "CoordinationTests",
dependencies: [
"Coordination"
],
path: "Tests/Coordination",
exclude: excludePlatforms
),
.testTarget(
name: "CoreTests",
dependencies: [
"Core"
],
path: "Tests/Core"
),
.testTarget(
name: "DependenciesTests",
dependencies: [
"Dependencies"
],
path: "Tests/Dependencies"
),
.testTarget(
name: "PersistenceTests",
dependencies: [
"Persistence"
],
path: "Tests/Persistence"
),
]
) )
// MARK: - String+Constants // MARK: - String+Constants
private extension String { private extension String {
enum PlatformFolder { enum Package {
static let iOS = "Platform/iOS" static let name = "SwiftLibs"
}
enum Target {
static let communications = "Communications"
static let coordination = "Coordination"
static let core = "Core"
static let dependencies = "Dependencies"
static let persistence = "Persistence"
} }
} }

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
import Foundation import Foundation
/// This class overrides the `URLProtocol` protocol used by the `URLSession` to handle the loading of protocol-specific URL data so it is possible to mock URL response for testing purposes. /// This class overrides the `URLProtocol` protocol used by the `URLSession` to handle the loading of protocol-specific URL data so it is possible to mock URL response for testing purposes.
@ -116,3 +117,4 @@ public struct MockURLResponse {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
import Foundation import Foundation
/// This use case generate a url request out of a given endpoint. /// This use case generate a url request out of a given endpoint.
@ -55,3 +56,4 @@ public struct MakeURLRequestUseCase {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS)
import UIKit import UIKit
/// This is a base class for the `NavigationRouter` concrete router implementations. /// This is a base class for the `NavigationRouter` concrete router implementations.
@ -70,3 +71,4 @@ extension BaseNavigationRouter: UINavigationControllerDelegate {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS)
import UIKit import UIKit
/// This class is responsible for showing view controllers modally, as it is a concrete implementation of the `Router` protocol. /// This class is responsible for showing view controllers modally, as it is a concrete implementation of the `Router` protocol.
@ -88,3 +89,4 @@ private extension ModalNavigationRouter {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS)
import UIKit import UIKit
/// This class is responsible for pushing view controllers into a navigation controller, as it is a concrete implementation of the `Router` protocol. /// This class is responsible for pushing view controllers into a navigation controller, as it is a concrete implementation of the `Router` protocol.
@ -66,3 +67,4 @@ extension PushNavigationRouter: Router {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS)
import UIKit import UIKit
/// This class is responsible for populating the window of an application. /// This class is responsible for populating the window of an application.
@ -45,3 +46,4 @@ public class WindowRouter: Router {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if canImport(Combine) && canImport(CoreData)
import Combine import Combine
import CoreData import CoreData
@ -167,3 +168,4 @@ public enum Change: Hashable {
case section(SectionUpdate) case section(SectionUpdate)
case object(ObjectUpdate) case object(ObjectUpdate)
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if canImport(CoreData)
import CoreData import CoreData
public protocol Service { public protocol Service {
@ -38,3 +39,4 @@ public protocol Service {
func save(childContext context: NSManagedObjectContext) throws func save(childContext context: NSManagedObjectContext) throws
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
import Communications import Communications
import Foundation import Foundation
import XCTest import XCTest
@ -141,3 +142,4 @@ private struct TestEndpoint: Endpoint {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if canImport(UIKit)
import Coordination import Coordination
import UIKit import UIKit
import XCTest import XCTest
@ -139,3 +140,4 @@ final class CoordinatorTests: XCTestCase {
} }
} }
#endif

View File

@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if canImport(UIKit)
import Coordination import Coordination
import UIKit import UIKit
@ -108,3 +109,4 @@ class SpyRouter: Router {
class SomeViewController: UIViewController {} class SomeViewController: UIViewController {}
class SomeOtherViewController: UIViewController {} class SomeOtherViewController: UIViewController {}
#endif

View File

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftLibs open source project
//
// Copyright (c) 2023 Röck+Cöde VoF. and the SwiftLibs project authors
// Licensed under the EUPL 1.2 or later.
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftLibs project authors
//
//===----------------------------------------------------------------------===//
import Foundation
import CoreData
@objc(TestEntity)
public class TestEntity: NSManagedObject {}
// MARK: - Fetch requests
extension TestEntity {
// MARK: Functions
@nonobjc public class func fetchRequest() -> NSFetchRequest<TestEntity> {
return NSFetchRequest<TestEntity>(entityName: "TestEntity")
}
}

View File

@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
import CoreData import CoreData
import Foundation
import Persistence import Persistence
struct TestPersistenceService { struct TestPersistenceService {

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22E261" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22E261" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="TestEntity" representedClassName="TestEntity" syncable="YES" codeGenerationType="class"/> <entity name="TestEntity" representedClassName="TestEntity" syncable="YES"/>
</model> </model>