mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
143 lines
4.4 KiB
Swift
143 lines
4.4 KiB
Swift
//
|
|
// Command.swift
|
|
// Cargo
|
|
//
|
|
// Created by Joseph Mattiello on 02/28/23.
|
|
// Copyright © 2023 Joseph Mattiello. All rights reserved.
|
|
//
|
|
|
|
import ArgumentParser
|
|
import Foundation
|
|
import PackageLoading
|
|
import PackageModel
|
|
import TSCBasic
|
|
import Workspace
|
|
import Xcodeproj
|
|
|
|
struct Command: ParsableCommand {
|
|
// MARK: - Configuration
|
|
|
|
static var configuration = CommandConfiguration(
|
|
abstract: "Builds a `rust` package using `cargo`.",
|
|
discussion:
|
|
"""
|
|
|
|
""",
|
|
version: "1.1.0"
|
|
)
|
|
|
|
// MARK: - Arguments
|
|
|
|
@OptionGroup()
|
|
var options: Options
|
|
|
|
// MARK: - Execution
|
|
|
|
// swiftlint:disable:next function_body_length
|
|
func run() throws {
|
|
// load all/validate of the package info
|
|
let package = try PackageInfo(options: options)
|
|
|
|
// validate that package to make sure we can generate it
|
|
let validation = package.validationErrors()
|
|
if validation.isEmpty == false {
|
|
for error in validation {
|
|
print(error.isFatal ? "Error:" : "Warning:", error.errorDescription!)
|
|
}
|
|
if validation.contains(where: { $0.isFatal }) {
|
|
Darwin.exit(1)
|
|
}
|
|
}
|
|
|
|
// generate the Xcode project file
|
|
let generator = ProjectGenerator(package: package)
|
|
|
|
let platforms = try package.supportedPlatforms()
|
|
|
|
// get what we're building
|
|
try generator.writeDistributionXcconfig()
|
|
let project = try generator.generate()
|
|
|
|
// printing packages?
|
|
if options.listProducts {
|
|
package.printAllProducts(project: project)
|
|
Darwin.exit(0)
|
|
}
|
|
|
|
// get valid packages and their SDKs
|
|
let productNames = try package.validProductNames(project: project)
|
|
let sdks = platforms.flatMap { $0.sdks }
|
|
|
|
// we've applied the xcconfig to everything, but some dependencies (*cough* swift-nio)
|
|
// have build errors, so we remove it from targets we're not building
|
|
if options.stackEvolution == false {
|
|
try project.enableDistribution(targets: productNames, xcconfig: AbsolutePath(package.distributionBuildXcconfig.path).relative(to: AbsolutePath(package.rootDirectory.path)))
|
|
}
|
|
|
|
// save the project
|
|
try project.save(to: generator.projectPath)
|
|
|
|
// start building
|
|
let builder = XcodeBuilder(project: project, projectPath: generator.projectPath, package: package, options: options)
|
|
|
|
// clean first
|
|
if options.clean {
|
|
try builder.clean()
|
|
}
|
|
|
|
// all of our targets for each platform, then group the resulting .frameworks by target
|
|
var frameworkFiles: [String: [XcodeBuilder.BuildResult]] = [:]
|
|
|
|
for sdk in sdks {
|
|
try builder.build(targets: productNames, sdk: sdk)
|
|
.forEach { pair in
|
|
if frameworkFiles[pair.key] == nil {
|
|
frameworkFiles[pair.key] = []
|
|
}
|
|
frameworkFiles[pair.key]?.append(pair.value)
|
|
}
|
|
}
|
|
|
|
var xcframeworkFiles: [(String, Foundation.URL)] = []
|
|
|
|
// then we merge the resulting frameworks
|
|
try frameworkFiles
|
|
.forEach { pair in
|
|
xcframeworkFiles.append((pair.key, try builder.merge(target: pair.key, buildResults: pair.value)))
|
|
}
|
|
|
|
// zip it up if thats what they want
|
|
if options.zip {
|
|
let zipper = Zipper(package: package)
|
|
let zipped = try xcframeworkFiles
|
|
.flatMap { pair -> [Foundation.URL] in
|
|
let zip = try zipper.zip(target: pair.0, version: self.options.zipVersion, file: pair.1)
|
|
let checksum = try zipper.checksum(file: zip)
|
|
try zipper.clean(file: pair.1)
|
|
|
|
return [zip, checksum]
|
|
}
|
|
|
|
// notify the action if we have one
|
|
if options.githubAction {
|
|
let zips = zipped.map { $0.path }.joined(separator: "\n")
|
|
let data = Data(zips.utf8)
|
|
let url = Foundation.URL(fileURLWithPath: options.buildPath).appendingPathComponent("xcframework-zipfile.url")
|
|
try data.write(to: url)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Errors
|
|
|
|
private enum Error: Swift.Error, LocalizedError {
|
|
case noProducts
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .noProducts: return ""
|
|
}
|
|
}
|
|
}
|