Skip to content

Commit

Permalink
Initial addition of multiplatform support in ProjectDescription
Browse files Browse the repository at this point in the history
  • Loading branch information
waltflanagan committed Aug 28, 2023
1 parent e2bdcd3 commit e24a1d0
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 54 deletions.
51 changes: 0 additions & 51 deletions Sources/ProjectDescription/MultiplatformProject.swift

This file was deleted.

4 changes: 4 additions & 0 deletions Sources/ProjectDescription/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public struct Project: Codable, Equatable {
public let packages: [Package]
/// The targets of the project.
public let targets: [Target]
/// The targets of the project.
public let multiplatformTargets: [Multiplatform.Target]
/// The custom schemes for the project. Default schemes for each target are generated by default.
public let schemes: [Scheme]
/// The build settings and configuration for the project.
Expand All @@ -89,6 +91,7 @@ public struct Project: Codable, Equatable {
packages: [Package] = [],
settings: Settings? = nil,
targets: [Target] = [],
multiplatformTargets: [Multiplatform.Target] = [],
schemes: [Scheme] = [],
fileHeaderTemplate: FileHeaderTemplate? = nil,
additionalFiles: [FileElement] = [],
Expand All @@ -99,6 +102,7 @@ public struct Project: Codable, Equatable {
self.options = options
self.packages = packages
self.targets = targets
self.multiplatformTargets = multiplatformTargets
self.schemes = schemes
self.settings = settings
self.additionalFiles = additionalFiles
Expand Down
9 changes: 9 additions & 0 deletions Sources/TuistGenerator/Generator/ConfigGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@ final class ConfigGenerator: ConfigGenerating {
settings["SDKROOT"] = "auto"
}

if target.supportedPlatforms.count > 1 {
let simulatorSDKs = target.supportedPlatforms.compactMap(\.xcodeSimulatorSDK)
let platformSDKs = target.supportedPlatforms.map(\.xcodeDeviceSDK)
settings["SUPPORTED_PLATFORMS"] = .string(
[simulatorSDKs, platformSDKs].flatMap { $0 }.sorted()
.joined(separator: " ")
)
}

if target.product == .staticFramework {
settings["MACH_O_TYPE"] = "staticlib"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ import TuistCore
import TuistGraph

extension TuistGraph.DeploymentTargets {
/// Maps a ProjectDescription.DeploymentTargets instance into a TuistGraph.DeploymentTarget instance.
/// - Parameters:
/// - manifest: Manifest representation of deployment target model.
static func from(manifest: ProjectDescription.DeploymentTargets) -> TuistGraph.DeploymentTargets {
TuistGraph.DeploymentTargets(
iOS: manifest.iOS,
macOS: manifest.macOS,
watchOS: manifest.watchOS,
tvOS: manifest.tvOS,
visionOS: manifest.visionOS
)
}

/// Maps a ProjectDescription.DeploymentTarget instance into a TuistGraph.DeploymentTarget instance.
/// - Parameters:
/// - manifest: Manifest representation of deployment target model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@ import ProjectDescription
import TuistGraph

extension TuistGraph.Destination {
/// Maps a ProjectDescription.Package instance into a TuistGraph.Package model.
/// - Parameters:
/// - manifest: Manifest representation of Package.
/// - generatorPaths: Generator paths.
static func from(
destinations: ProjectDescription.Destinations
) throws -> TuistGraph.Destinations {
let mappedDestinations: [TuistGraph.Destination] = destinations.map { destination in
switch destination {
case .iPhone:
return .iPhone
case .iPad:
return .iPad
case .mac:
return .mac
case .macWithiPadDesign:
return .macWithiPadDesign
case .macCatalyst:
return .macCatalyst
case .appleWatch:
return .appleWatch
case .appleTv:
return .appleTv
case .appleVision:
return .appleVision
case .appleVisionWithiPadDesign:
return .appleVisionWithiPadDesign
}
}

return Set(mappedDestinations)
}

/// Maps a ProjectDescription.Package instance into a TuistGraph.Package model.
/// - Parameters:
/// - manifest: Manifest representation of Package.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,22 @@ extension TuistGraph.Project {
let options = TuistGraph.Project.Options.from(manifest: manifest.options)
let settings = try manifest.settings.map { try TuistGraph.Settings.from(manifest: $0, generatorPaths: generatorPaths) }

let targets = try manifest.targets.map {
var targets = try manifest.targets.map {
try TuistGraph.Target.from(
manifest: $0,
generatorPaths: generatorPaths,
externalDependencies: externalDependencies
)
}

targets.append(contentsOf: try manifest.multiplatformTargets.map {
try TuistGraph.Target.from(
manifest: $0,
generatorPaths: generatorPaths,
externalDependencies: externalDependencies
)
})

let schemes = try manifest.schemes.map { try TuistGraph.Scheme.from(manifest: $0, generatorPaths: generatorPaths) }
let additionalFiles = try manifest.additionalFiles
.flatMap { try TuistGraph.FileElement.from(manifest: $0, generatorPaths: generatorPaths) }
Expand Down
109 changes: 107 additions & 2 deletions Sources/TuistLoader/Models+ManifestMappers/Target+ManifestMapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,111 @@ public enum TargetManifestMapperError: FatalError {

// swiftlint:disable function_body_length
extension TuistGraph.Target {
/// Maps a ProjectDescription.Target instance into a TuistGraph.Target instance.
/// - Parameters:
/// - manifest: Manifest representation of the multiplatform target.
/// - generatorPaths: Generator paths.
/// - externalDependencies: External dependencies graph.
static func from(
manifest: ProjectDescription.Multiplatform.Target,
generatorPaths: GeneratorPaths,
externalDependencies: [TuistGraph.Platform: [String: [TuistGraph.TargetDependency]]]
) throws -> TuistGraph.Target {
let name = manifest.name
let destinations = try TuistGraph.Destination.from(destinations: manifest.destinations)
let product = TuistGraph.Product.from(manifest: manifest.product)

let bundleId = manifest.bundleId
let productName = manifest.productName
let deploymentTargets = manifest.deploymentTargets.map { TuistGraph.DeploymentTargets.from(manifest: $0) } ?? .empty()

let dependencies = try manifest.dependencies.flatMap { dependency in
try destinations.map(\.platform).flatMap { platform in
try TuistGraph.TargetDependency.from(
manifest: dependency,
generatorPaths: generatorPaths,
externalDependencies: externalDependencies,
platform: platform
)
}
}.uniqued()

let infoPlist = try TuistGraph.InfoPlist.from(manifest: manifest.infoPlist, generatorPaths: generatorPaths)
let entitlements = try manifest.entitlements.map { try generatorPaths.resolve(path: $0) }

let settings = try manifest.settings.map { try TuistGraph.Settings.from(manifest: $0, generatorPaths: generatorPaths) }

let (sources, sourcesPlaygrounds) = try sourcesAndPlaygrounds(
manifest: manifest,
targetName: name,
generatorPaths: generatorPaths
)

let (resources, resourcesPlaygrounds, resourcesCoreDatas, invalidResourceGlobs) = try resourcesAndOthers(
manifest: manifest,
generatorPaths: generatorPaths
)

if !invalidResourceGlobs.isEmpty {
throw TargetManifestMapperError.invalidResourcesGlob(targetName: name, invalidGlobs: invalidResourceGlobs)
}

let copyFiles = try (manifest.copyFiles ?? []).map {
try TuistGraph.CopyFilesAction.from(manifest: $0, generatorPaths: generatorPaths)
}

let headers = try manifest.headers.map { try TuistGraph.Headers.from(
manifest: $0,
generatorPaths: generatorPaths,
productName: manifest.productName
) }

let coreDataModels = try manifest.coreDataModels.map {
try TuistGraph.CoreDataModel.from(manifest: $0, generatorPaths: generatorPaths)
} + resourcesCoreDatas.map { try TuistGraph.CoreDataModel.from(path: $0) }

let scripts = try manifest.scripts.map {
try TuistGraph.TargetScript.from(manifest: $0, generatorPaths: generatorPaths)
}

let environment = manifest.environment
let launchArguments = manifest.launchArguments.map(LaunchArgument.from)

let playgrounds = sourcesPlaygrounds + resourcesPlaygrounds

let additionalFiles = try manifest.additionalFiles
.flatMap { try TuistGraph.FileElement.from(manifest: $0, generatorPaths: generatorPaths) }

let buildRules = manifest.buildRules.map {
TuistGraph.BuildRule.from(manifest: $0)
}

return TuistGraph.Target(
name: name,
destinations: destinations,
product: product,
productName: productName,
bundleId: bundleId,
deploymentTargets: deploymentTargets,
infoPlist: infoPlist,
entitlements: entitlements,
settings: settings,
sources: sources,
resources: resources,
copyFiles: copyFiles,
headers: headers,
coreDataModels: coreDataModels,
scripts: scripts,
environment: environment,
launchArguments: launchArguments,
filesGroup: .group(name: "Project"),
dependencies: dependencies,
playgrounds: playgrounds,
additionalFiles: additionalFiles,
buildRules: buildRules
)
}

/// Maps a ProjectDescription.Target instance into a TuistGraph.Target instance.
/// - Parameters:
/// - manifest: Manifest representation of the target.
Expand Down Expand Up @@ -129,7 +234,7 @@ extension TuistGraph.Target {
// MARK: - Fileprivate

fileprivate static func resourcesAndOthers(
manifest: ProjectDescription.Target,
manifest: MultiplatformCompatibilityTarget,
generatorPaths: GeneratorPaths
// swiftlint:disable:next large_tuple
) throws -> (
Expand Down Expand Up @@ -184,7 +289,7 @@ extension TuistGraph.Target {
}

fileprivate static func sourcesAndPlaygrounds(
manifest: ProjectDescription.Target,
manifest: MultiplatformCompatibilityTarget,
targetName: String,
generatorPaths: GeneratorPaths
) throws -> (sources: [TuistGraph.SourceFile], playgrounds: [AbsolutePath]) {
Expand Down
13 changes: 13 additions & 0 deletions Sources/TuistLoader/Utils/MultiplatformCompatibilityBridge.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation
import ProjectDescription

public typealias PDProject = ProjectDescription.Project
public typealias PDTarget = ProjectDescription.Target

protocol MultiplatformCompatibilityTarget {
var sources: SourceFilesList? { get }
var resources: ResourceFileElements? { get }
}

extension ProjectDescription.Target: MultiplatformCompatibilityTarget {}
extension ProjectDescription.Multiplatform.Target: MultiplatformCompatibilityTarget {}

0 comments on commit e24a1d0

Please sign in to comment.