Skip to content

Commit

Permalink
Merge pull request #113 from giginet/swift-510
Browse files Browse the repository at this point in the history
Support Xcode 15.3 and Swift 5.10
  • Loading branch information
giginet authored Jan 30, 2024
2 parents b2d8453 + c3b18c4 commit b62d108
Show file tree
Hide file tree
Showing 21 changed files with 298 additions and 58 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Lint

on:
push:
branches:
- main
pull_request:
branches:
- '*'
jobs:
SwiftLint:
strategy:
matrix:
xcode_version: ["15.2"]
env:
DEVELOPER_DIR: "/Applications/Xcode_${{ matrix.xcode_version }}.app/Contents/Developer"
runs-on: macos-13
steps:
- uses: actions/checkout@v2
- name: SwiftLint
run: swiftlint --strict
19 changes: 15 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,27 @@ jobs:
Tests:
strategy:
matrix:
xcode_version: ["14.3.1", "15.0"]
xcode_version: ["15.2"]
swift: ["5.8.1", "5.9.2", "5.10.0"]
env:
DEVELOPER_DIR: "/Applications/Xcode_${{ matrix.xcode_version }}.app/Contents/Developer"
runs-on: macos-13
steps:
- uses: SwiftyLab/setup-swift@latest
with:
development: true
swift-version: ${{ matrix.swift }}
- name: Get swift version
run: swift --version
- uses: actions/checkout@v2
- name: SwiftLint
run: swiftlint --strict
- name: Run Tests
run: |
swift test --verbose
# If default toolchain in Xcode is used, `env.TOOLCHAINS` will be empty
if [[ -n "${{ env.TOOLCHAINS }}" ]]; then
xcrun --toolchain ${{ env.TOOLCHAINS }} swift test --verbose
else
swift test --verbose
fi
env:
ENABLE_INTEGRATION_TESTS: 1
IS_CI: 1
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/apple/swift-package-manager.git",
revision: "swift-5.9-RELEASE"),
revision: "swift-5.10-DEVELOPMENT-SNAPSHOT-2024-01-25-a"),
.package(url: "https://github.com/apple/swift-log.git",
.upToNextMinor(from: "1.4.2")),
.package(url: "https://github.com/apple/swift-collections",
Expand Down
94 changes: 94 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
import Foundation

let package = Package(
name: "Scipio",
platforms: [
.macOS(.v12),
],
products: [
.executable(name: "scipio",
targets: ["scipio"]),
.library(
name: "ScipioKit",
targets: ["ScipioKit"]),
.library(
name: "ScipioS3Storage",
targets: ["ScipioS3Storage"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-package-manager.git",
revision: "swift-5.9-RELEASE"),
.package(url: "https://github.com/apple/swift-log.git",
.upToNextMinor(from: "1.4.2")),
.package(url: "https://github.com/apple/swift-collections",
from: "1.0.4"),
.package(url: "https://github.com/apple/swift-argument-parser.git",
from: "1.1.0"),
.package(url: "https://github.com/apple/swift-algorithms.git",
from: "1.0.0"),
.package(url: "https://github.com/onevcat/Rainbow",
.upToNextMinor(from: "4.0.1")),
.package(url: "https://github.com/soto-project/soto-codegenerator",
from: "0.6.0"),
.package(url: "https://github.com/soto-project/soto-core.git",
from: "6.4.0"),
],
targets: [
.executableTarget(name: "scipio",
dependencies: [
.target(name: "ScipioKit"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
]),
.target(
name: "ScipioKit",
dependencies: [
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
.product(name: "XCBuildSupport", package: "swift-package-manager"),
.product(name: "Logging", package: "swift-log"),
.product(name: "Collections", package: "swift-collections"),
.product(name: "Algorithms", package: "swift-algorithms"),
.product(name: "Rainbow", package: "Rainbow"),
],
plugins: [
.plugin(name: "GenerateScipioVersion")
]
),
.plugin(
name: "GenerateScipioVersion",
capability: .buildTool()
),
.target(
name: "ScipioS3Storage",
dependencies: [
.target(name: "ScipioKit"),
.product(name: "SotoCore", package: "soto-core"),
],
plugins: [
.plugin(name: "SotoCodeGeneratorPlugin", package: "soto-codegenerator"),
]
),
.testTarget(
name: "ScipioKitTests",
dependencies: [
.target(name: "ScipioKit"),
],
exclude: ["Resources/Fixtures/"],
resources: [.copy("Resources/Fixtures")]),
.testTarget(
name: "ScipioS3StorageTests",
dependencies: ["ScipioS3Storage"]),
]
)

let isDevelopment = ProcessInfo.processInfo.environment["SCIPIO_DEVELOPMENT"] == "1"

// swift-docs is not needed for package users
if isDevelopment {
package.dependencies += [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0"),
]
}
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Scipio

![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/giginet/Scipio/tests.yml?style=flat-square&logo=github)
![Swift 5.10](https://img.shields.io/badge/Swift-5.10-FA7343?logo=swift&style=flat-square)
![Swift 5.9](https://img.shields.io/badge/Swift-5.9-FA7343?logo=swift&style=flat-square)
![Swift 5.8](https://img.shields.io/badge/Swift-5.8-FA7343?logo=swift&style=flat-square)
[![Xcode 15.0](https://img.shields.io/badge/Xcode-15.0-147EFB?style=flat-square&logo=xcode&link=https%3A%2F%2Fdeveloper.apple.com%2Fxcode%2F)](https://developer.apple.com/xcode/)
[![Xcode 15.3](https://img.shields.io/badge/Xcode-15.3-147EFB?style=flat-square&logo=xcode&link=https%3A%2F%2Fdeveloper.apple.com%2Fxcode%2F)](https://developer.apple.com/xcode/)
[![Xcode 15.2](https://img.shields.io/badge/Xcode-15.2-147EFB?style=flat-square&logo=xcode&link=https%3A%2F%2Fdeveloper.apple.com%2Fxcode%2F)](https://developer.apple.com/xcode/)
[![Xcode 14.3](https://img.shields.io/badge/Xcode-14.3-147EFB?style=flat-square&logo=xcode&link=https%3A%2F%2Fdeveloper.apple.com%2Fxcode%2F)](https://developer.apple.com/xcode/)
[![SwiftPM](https://img.shields.io/badge/SwiftPM-compatible-green?logo=swift&style=flat-square)](https://swift.org/package-manager/)
[![Documentation](https://img.shields.io/badge/Documentation-available-green?style=flat-square)](https://giginet.github.io/Scipio/documentation/scipio/)
Expand Down Expand Up @@ -132,6 +134,18 @@ $ scipio create path/to/MyPackage

See [Convert Single Swift Package to XCFramework](https://giginet.github.io/Scipio/documentation/scipio/create-frameworks) for detail.

## Supported Xcode and Swift version

Currently, we support Swift 5.8, 5.9, and 5.10.

Swift 5.8 support will be dropped in the future.

| | Xcode | Swift |
|----|--------------|-------|
|| 15.3(Beta 1) | 5.10 |
|| 15.0<=15.2 | 5.9 |
|| 14.3 | 5.8 |

## Reliability

Scipio only builts with standard dependencies and Apple official tools to keep reliability.
Expand Down
32 changes: 18 additions & 14 deletions Sources/ScipioKit/DescriptionPackage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Basics

struct DescriptionPackage {
let mode: Runner.Mode
let packageDirectory: AbsolutePath
let packageDirectory: ScipioAbsolutePath
private let toolchain: UserToolchain
let workspace: Workspace
let graph: PackageGraph
Expand All @@ -34,32 +34,32 @@ struct DescriptionPackage {
manifest.displayName
}

var buildDirectory: AbsolutePath {
var buildDirectory: ScipioAbsolutePath {
packageDirectory.appending(component: ".build")
}

var workspaceDirectory: AbsolutePath {
var workspaceDirectory: ScipioAbsolutePath {
buildDirectory.appending(component: "scipio")
}

var supportedSDKs: Set<SDK> {
Set(manifest.platforms.map(\.platformName).compactMap(SDK.init(platformName:)))
}

var derivedDataPath: AbsolutePath {
var derivedDataPath: ScipioAbsolutePath {
workspaceDirectory.appending(component: "DerivedData")
}

func generatedModuleMapPath(of target: ResolvedTarget, sdk: SDK) throws -> AbsolutePath {
let relativePath = try RelativePath(validating: "ModuleMapsForFramework/\(sdk.settingValue)")
func generatedModuleMapPath(of target: ResolvedTarget, sdk: SDK) throws -> ScipioAbsolutePath {
let relativePath = try TSCBasic.RelativePath(validating: "ModuleMapsForFramework/\(sdk.settingValue)")
return workspaceDirectory
.appending(relativePath)
.appending(component: target.modulemapName)
}

/// Returns an Products directory path
/// It should be the default setting of `TARGET_BUILD_DIR`
func productsDirectory(buildConfiguration: BuildConfiguration, sdk: SDK) -> AbsolutePath {
func productsDirectory(buildConfiguration: BuildConfiguration, sdk: SDK) -> ScipioAbsolutePath {
let intermediateDirectoryName = productDirectoryName(
buildConfiguration: buildConfiguration,
sdk: sdk
Expand All @@ -68,12 +68,12 @@ struct DescriptionPackage {
}

/// Returns a directory path which contains assembled frameworks
var assembledFrameworksRootDirectory: AbsolutePath {
var assembledFrameworksRootDirectory: ScipioAbsolutePath {
workspaceDirectory.appending(component: "AssembledFrameworks")
}

/// Returns a directory path of the assembled frameworks path for the specific Configuration/Platform
func assembledFrameworksDirectory(buildConfiguration: BuildConfiguration, sdk: SDK) -> AbsolutePath {
func assembledFrameworksDirectory(buildConfiguration: BuildConfiguration, sdk: SDK) -> ScipioAbsolutePath {
let intermediateDirName = productDirectoryName(buildConfiguration: buildConfiguration, sdk: sdk)
return assembledFrameworksRootDirectory
.appending(component: intermediateDirName)
Expand All @@ -91,7 +91,7 @@ struct DescriptionPackage {

// MARK: Initializer

private static func makeWorkspace(toolchain: UserToolchain, packagePath: AbsolutePath) throws -> Workspace {
private static func makeWorkspace(toolchain: UserToolchain, packagePath: ScipioAbsolutePath) throws -> Workspace {
var workspaceConfiguration: WorkspaceConfiguration = .default
// override default configuration to treat XIB files
workspaceConfiguration.additionalFileRules = FileRuleDescription.xcbuildFileTypes
Expand All @@ -101,7 +101,7 @@ struct DescriptionPackage {
.makeAuthorizationProvider(fileSystem: fileSystem, observabilityScope: observabilitySystem.topScope)
let workspace = try Workspace(
fileSystem: fileSystem,
location: Workspace.Location(forRootPackage: packagePath, fileSystem: fileSystem),
location: Workspace.Location(forRootPackage: packagePath.spmAbsolutePath, fileSystem: fileSystem),
authorizationProvider: authorizationProvider,
configuration: workspaceConfiguration,
customHostToolchain: toolchain
Expand All @@ -116,25 +116,29 @@ struct DescriptionPackage {
/// Then, use package versions only from existing Package.resolved.
/// If it is `true`, Package.resolved never be updated.
/// Instead, the resolving will fail if the Package.resolved is mis-matched with the workspace.
init(packageDirectory: AbsolutePath, mode: Runner.Mode, onlyUseVersionsFromResolvedFile: Bool) throws {
init(packageDirectory: ScipioAbsolutePath, mode: Runner.Mode, onlyUseVersionsFromResolvedFile: Bool) throws {
self.packageDirectory = packageDirectory
self.mode = mode

#if swift(>=5.10)
let toolchain = try UserToolchain(swiftSDK: try .hostSwiftSDK())
#else
let toolchain = try UserToolchain(destination: try .hostDestination())
#endif
self.toolchain = toolchain

let workspace = try Self.makeWorkspace(toolchain: toolchain, packagePath: packageDirectory)
let scope = observabilitySystem.topScope
self.graph = try workspace.loadPackageGraph(
rootInput: PackageGraphRootInput(packages: [packageDirectory]),
rootInput: PackageGraphRootInput(packages: [packageDirectory.spmAbsolutePath]),
// This option is same with resolver option `--disable-automatic-resolution`
// Never update Package.resolved of the package
forceResolvedVersions: onlyUseVersionsFromResolvedFile,
observabilityScope: scope
)
self.manifest = try tsc_await {
workspace.loadRootManifest(
at: packageDirectory,
at: packageDirectory.spmAbsolutePath,
observabilityScope: scope,
completion: $0
)
Expand Down
5 changes: 4 additions & 1 deletion Sources/ScipioKit/Producer/BinaryExtractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ struct BinaryExtractor {
logger.info("🗑️ Delete \(frameworkName)", metadata: .color(.red))
try fileSystem.removeFileTree(destinationPath.absolutePath)
}
try fileSystem.copy(from: sourcePath, to: destinationPath.absolutePath)
try fileSystem.copy(
from: sourcePath,
to: destinationPath.absolutePath.spmAbsolutePath
)

return destinationPath
}
Expand Down
13 changes: 11 additions & 2 deletions Sources/ScipioKit/Producer/Cache/CacheSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ struct CacheSystem {

let data = try jsonEncoder.encode(cacheKey)
let versionFilePath = outputDirectory.appendingPathComponent(versionFileName(for: target.buildProduct.target.name))
try fileSystem.writeFileContents(versionFilePath.absolutePath, data: data)
try fileSystem.writeFileContents(
versionFilePath.absolutePath.spmAbsolutePath,
data: data
)
}

func existsValidCache(cacheKey: CacheKey) async -> Bool {
Expand Down Expand Up @@ -254,9 +257,15 @@ struct CacheSystem {

private func retrievePin(product: BuildProduct) throws -> PinsStore.Pin {
let pinsStore = try descriptionPackage.workspace.pinsStore.load()
#if swift(>=5.10)
guard let pin = pinsStore.pins[product.package.identity] else {
throw Error.revisionNotDetected(product.package.manifest.displayName)
}
#else
guard let pin = pinsStore.pinsMap[product.package.identity] else {
throw Error.revisionNotDetected(product.package.manifest.displayName)
}
#endif
return pin
}

Expand Down Expand Up @@ -285,7 +294,7 @@ public struct VersionFileDecoder {

public func decode(versionFile: URL) throws -> CacheKey {
try jsonDecoder.decode(
path: versionFile.absolutePath,
path: versionFile.absolutePath.spmAbsolutePath,
fileSystem: fileSystem,
as: CacheKey.self
)
Expand Down
5 changes: 4 additions & 1 deletion Sources/ScipioKit/Producer/InfoPlistGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ struct InfoPlistGenerator {

func generateForResourceBundle(at path: AbsolutePath) throws {
let body = resourceBundleBody

#if swift(>=5.10)
try fileSystem.writeFileContents(path.spmAbsolutePath, string: body)
#else
try fileSystem.writeFileContents(path, string: body)
#endif
}

private var resourceBundleBody: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ struct BuildParametersGenerator {
}

func generate(for sdk: SDK, buildParameters: BuildParameters, destinationDir: AbsolutePath) throws -> AbsolutePath {
#if swift(>=5.9)
#if swift(>=5.10)
let targetArchitecture = buildParameters.targetTriple.arch?.rawValue ?? "arm64"
#elseif swift(>=5.9)
let targetArchitecture = buildParameters.triple.arch?.rawValue ?? "arm64"
#else
let targetArchitecture = buildParameters.triple.arch.rawValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ struct FrameworkComponentsCollector {
.headers
.filter { $0.isDescendant(of: clangTarget.includeDir) }
let notSymlinks = publicHeaders.filter { !fileSystem.isSymlink($0) }
.map { $0.scipioAbsolutePath }
let symlinks = publicHeaders.filter { fileSystem.isSymlink($0) }

// Sometimes, public headers include a file and its symlink both.
Expand Down
Loading

0 comments on commit b62d108

Please sign in to comment.