mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-08-17 00:30:29 +03:00
Merge branch 'yonaskolb:master' into master
This commit is contained in:
commit
92c4092596
13
CHANGELOG.md
13
CHANGELOG.md
@ -2,13 +2,22 @@
|
||||
|
||||
## Next Version
|
||||
|
||||
## 2.38.0
|
||||
|
||||
### Added
|
||||
|
||||
- [Multi-destination targets](https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md#supported-destinations) #1336 @amatig
|
||||
- Added `supportedDestinations` to target
|
||||
- Added optional new `platform` value of `auto` when using `supportedDestinations`
|
||||
- Added `destinationFilters` for sources and dependencies
|
||||
- Added `inferDestinationFiltersByPath`, a convenience filter for sources
|
||||
- `.mlpackage` files now default to being a source type #1398 @aaron-foreflight
|
||||
|
||||
- Added support for `Build Tool Plug-ins` in `AggregateTarget` #1390 @BarredEwe
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed source file `includes` not working when no paths were found #1337 @shnhrrsn
|
||||
- Supports specifying multiple package products #1395 @simonbs
|
||||
|
||||
## 2.37.0
|
||||
|
||||
@ -359,7 +368,7 @@ Some support for Xcode Test Plans has been added. For now test plans are not gen
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed issue when linking and embeding static frameworks: they should be linked and NOT embed. #820 @acecilia
|
||||
- Fixed issue when linking and embedding static frameworks: they should be linked and NOT embed. #820 @acecilia
|
||||
- Fixed issue when generating projects for paths with a dot in the folder for swift sources. #826 @asifmohd
|
||||
- Prefix static library target filenames with 'lib' to match Xcode. #831 @ileitch
|
||||
- Fixed duplicate addition of carthage static frameworks. #829 @funzin
|
||||
|
@ -22,6 +22,7 @@ You can also use environment variables in your configuration file, by using `${S
|
||||
- [Target](#target)
|
||||
- [Product Type](#product-type)
|
||||
- [Platform](#platform)
|
||||
- [Supported Destinations](#supported-destinations)
|
||||
- [Sources](#sources)
|
||||
- [Target Source](#target-source)
|
||||
- [Dependency](#dependency)
|
||||
@ -69,7 +70,7 @@ You can also use environment variables in your configuration file, by using `${S
|
||||
- [ ] **targets**: **[String: [Target](#target)]** - The list of targets in the project mapped by name
|
||||
- [ ] **fileGroups**: **[String]** - A list of paths to add to the root of the project. These aren't files that will be included in your targets, but that you'd like to include in the project hierarchy anyway. For example a folder of xcconfig files that aren't already added by any target sources, or a Readme file.
|
||||
- [ ] **schemes**: **[Scheme](#scheme)** - A list of schemes by name. This allows more control over what is found in [Target Scheme](#target-scheme)
|
||||
- [ ] **schemeTemplates**: **[String: [Scheme Template](#scheme-template)]** - a list of schemes that can be used as templates for actual schems which reference them via a `template` property. They can be used to extract common scheme settings. Works great in combination with `include`.
|
||||
- [ ] **schemeTemplates**: **[String: [Scheme Template](#scheme-template)]** - a list of schemes that can be used as templates for actual schemes which reference them via a `template` property. They can be used to extract common scheme settings. Works great in combination with `include`.
|
||||
- [ ] **targetTemplates**: **[String: [Target Template](#target-template)]** - a list of targets that can be used as templates for actual targets which reference them via a `template` property. They can be used to extract common target settings. Works great in combination with `include`.
|
||||
- [ ] **packages**: **[String: [Swift Package](#swift-package)]** - a map of Swift packages by name.
|
||||
- [ ] **projectReferences**: **[String: [Project Reference](#project-reference)]** - a map of project references by name
|
||||
@ -357,6 +358,7 @@ Settings are merged in the following order: `groups`, `base`, `configs` (simple
|
||||
|
||||
- [x] **type**: **[Product Type](#product-type)** - Product type of the target
|
||||
- [x] **platform**: **[Platform](#platform)** - Platform of the target
|
||||
- [ ] **supportedDestinations**: **[[Supported Destinations](#supported-destinations)]** - List of supported platform destinations for the target.
|
||||
- [ ] **deploymentTarget**: **String** - The deployment target (eg `9.2`). If this is not specified the value from the project set in [Options](#options)`.deploymentTarget.PLATFORM` will be used.
|
||||
- [ ] **sources**: **[Sources](#sources)** - Source directories of the target
|
||||
- [ ] **configFiles**: **[Config Files](#config-files)** - `.xcconfig` files per config
|
||||
@ -434,12 +436,15 @@ This will provide default build settings for a certain product type. It can be a
|
||||
|
||||
This will provide default build settings for a certain platform. It can be any of the following:
|
||||
|
||||
- `auto` (available only when we use `supportedDestinations`)
|
||||
- `iOS`
|
||||
- `macOS`
|
||||
- `tvOS`
|
||||
- `macOS`
|
||||
- `watchOS`
|
||||
- `visionOS` (`visionOS` doesn't support Carthage usage)
|
||||
|
||||
Note that when we use supported destinations with Xcode 14+ we can avoid the definition of platform that fallbacks to the `auto` value.
|
||||
|
||||
**Multi Platform targets**
|
||||
|
||||
You can also specify an array of platforms. This will generate a target for each platform.
|
||||
@ -470,6 +475,33 @@ targets:
|
||||
|
||||
The above will generate 2 targets named `MyFramework_iOS` and `MyFramework_tvOS`, with all the relevant platform build settings. They will both have a `PRODUCT_NAME` of `MyFramework`
|
||||
|
||||
### Supported Destinations
|
||||
|
||||
This will provide a mix of default build settings for the chosen platform destinations. It can be any of the following:
|
||||
|
||||
- `iOS`
|
||||
- `tvOS`
|
||||
- `macOS`
|
||||
- `macCatalyst`
|
||||
- `visionOS`
|
||||
|
||||
```yaml
|
||||
targets:
|
||||
MyFramework:
|
||||
type: framework
|
||||
supportedDestinations: [iOS, tvOS]
|
||||
deploymentTarget:
|
||||
iOS: 9.0
|
||||
tvOS: 10.0
|
||||
sources:
|
||||
- path: MySources
|
||||
inferDestinationFiltersByPath: true
|
||||
- path: OtherSources
|
||||
destinationFilters: [iOS]
|
||||
```
|
||||
|
||||
Note that the definition of supported destinations can be applied to every type of bundle making everything more easy to manage (app targets, unit tests, UI tests etc).
|
||||
|
||||
### Sources
|
||||
|
||||
Specifies the source directories for a target. This can either be a single source or a list of sources. Applicable source files, resources, headers, and `.lproj` files will be parsed appropriately.
|
||||
@ -484,7 +516,9 @@ A source can be provided via a string (the path) or an object of the form:
|
||||
- [ ] **compilerFlags**: **[String]** or **String** - A list of compilerFlags to add to files under this specific path provided as a list or a space delimited string. Defaults to empty.
|
||||
- [ ] **excludes**: **[String]** - A list of [global patterns](https://en.wikipedia.org/wiki/Glob_(programming)) representing the files to exclude. These rules are relative to `path` and _not the directory where `project.yml` resides_. XcodeGen uses Bash 4's Glob behaviors where globstar (**) is enabled.
|
||||
- [ ] **includes**: **[String]** - A list of global patterns in the same format as `excludes` representing the files to include. These rules are relative to `path` and _not the directory where `project.yml` resides_. If **excludes** is present and file conflicts with **includes**, **excludes** will override the **includes** behavior.
|
||||
- [ ] **createIntermediateGroups**: **Bool** - This overrides the value in [Options](#options)
|
||||
- [ ] **destinationFilters**: **[[Supported Destinations](#supported-destinations)]** - List of supported platform destinations the files should filter to. Defaults to all supported destinations.
|
||||
- [ ] **inferDestinationFiltersByPath**: **Bool** - This is a convenience filter that helps you to filter the files if their paths match these patterns `**/<supportedDestination>/*` or `*_<supportedDestination>.swift`. Note, if you use `destinationFilters` this flag will be ignored.
|
||||
- [ ] **createIntermediateGroups**: **Bool** - This overrides the value in [Options](#options).
|
||||
- [ ] **optional**: **Bool** - Disable missing path check. Defaults to false.
|
||||
- [ ] **buildPhase**: **String** - This manually sets the build phase this file or files in this directory will be added to, otherwise XcodeGen will guess based on the file extension. Note that `Info.plist` files will never be added to any build phases, no matter what this setting is. Possible values are:
|
||||
- `sources` - Compile Sources phase
|
||||
@ -520,9 +554,11 @@ targets:
|
||||
MyTarget:
|
||||
sources: MyTargetSource
|
||||
MyOtherTarget:
|
||||
supportedDestinations: [iOS, tvOS]
|
||||
sources:
|
||||
- MyOtherTargetSource1
|
||||
- path: MyOtherTargetSource2
|
||||
inferDestinationFiltersByPath: true
|
||||
name: MyNewName
|
||||
excludes:
|
||||
- "ios/*.[mh]"
|
||||
@ -534,6 +570,7 @@ targets:
|
||||
- "-Werror"
|
||||
- "-Wextra"
|
||||
- path: MyOtherTargetSource3
|
||||
destinationFilters: [iOS]
|
||||
compilerFlags: "-Werror -Wextra"
|
||||
- path: ModuleMaps
|
||||
buildPhase:
|
||||
@ -561,10 +598,11 @@ A dependency can be one of a 6 types:
|
||||
|
||||
- [ ] **embed**: **Bool** - Whether to embed the dependency. Defaults to true for application target and false for non application targets.
|
||||
- [ ] **link**: **Bool** - Whether to link the dependency. Defaults to `true` depending on the type of the dependency and the type of the target (e.g. static libraries will only link to executables by default).
|
||||
- [ ] **codeSign**: **Bool** - Whether the `codeSignOnCopy` setting is applied when embedding framework. Defaults to true
|
||||
- [ ] **removeHeaders**: **Bool** - Whether the `removeHeadersOnCopy` setting is applied when embedding the framework. Defaults to true
|
||||
- [ ] **weak**: **Bool** - Whether the `Weak` setting is applied when linking the framework. Defaults to false
|
||||
- [ ] **platformFilter**: **String** - This field is specific to Mac Catalyst. It corresponds to the "Platforms" dropdown in the Frameworks & Libraries section of Target settings in Xcode. Available options are: **iOS**, **macOS** and **all**. Defaults is **all**
|
||||
- [ ] **codeSign**: **Bool** - Whether the `codeSignOnCopy` setting is applied when embedding framework. Defaults to true.
|
||||
- [ ] **removeHeaders**: **Bool** - Whether the `removeHeadersOnCopy` setting is applied when embedding the framework. Defaults to true.
|
||||
- [ ] **weak**: **Bool** - Whether the `Weak` setting is applied when linking the framework. Defaults to false.
|
||||
- [ ] **platformFilter**: **String** - This field is specific to Mac Catalyst. It corresponds to the "Platforms" dropdown in the Frameworks & Libraries section of Target settings in Xcode. Available options are: **iOS**, **macOS** and **all**. Defaults is **all**.
|
||||
- [ ] **destinationFilters**: **[[Supported Destinations](#supported-destinations)]** - List of supported platform destinations this dependency should filter to. Defaults to all supported destinations.
|
||||
- [ ] **platforms**: **[[Platform](#platform)]** - List of platforms this dependency should apply to. Defaults to all applicable platforms.
|
||||
- **copy** - Copy Files Phase for this dependency. This only applies when `embed` is true. Must be specified as an object with the following fields:
|
||||
- [x] **destination**: **String** - Destination of the Copy Files phase. This can be one of the following values:
|
||||
@ -614,13 +652,17 @@ projectReferences:
|
||||
path: path/to/FooLib.xcodeproj
|
||||
targets:
|
||||
MyTarget:
|
||||
supportedDestinations: [iOS, tvOS]
|
||||
dependencies:
|
||||
- target: MyFramework
|
||||
destinationFilters: [iOS]
|
||||
- target: FooLib/FooTarget
|
||||
- framework: path/to/framework.framework
|
||||
destinationFilters: [tvOS]
|
||||
- carthage: Result
|
||||
findFrameworks: false
|
||||
linkType: static
|
||||
destinationFilters: [iOS]
|
||||
- sdk: Contacts.framework
|
||||
- sdk: libc++.tbd
|
||||
- sdk: libz.dylib
|
||||
@ -646,7 +688,8 @@ targets:
|
||||
```
|
||||
|
||||
**Package dependency**
|
||||
- [ ] **product**: **String** - The product to use from the package. This defaults to the package name, so is only required if a Package has multiple libraries or a library with a differing name
|
||||
- [ ] **product**: **String** - The product to use from the package. This defaults to the package name, so is only required if a Package has multiple libraries or a library with a differing name. Use this over `products` when you want to define different linking options per product.
|
||||
- [ ] **products**: **String** - A list of products to use from the package. This can be used when depending on multiple products from a package.
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
@ -664,6 +707,21 @@ targets:
|
||||
product: SPMUtility
|
||||
```
|
||||
|
||||
Depending on multiple products from a package:
|
||||
|
||||
```yaml
|
||||
packages:
|
||||
FooFeature:
|
||||
path: Packages/FooFeature
|
||||
targets:
|
||||
App:
|
||||
dependencies:
|
||||
- package: FooFeature
|
||||
products:
|
||||
- FooDomain
|
||||
- FooUI
|
||||
```
|
||||
|
||||
### Config Files
|
||||
|
||||
Specifies `.xcconfig` files for each configuration.
|
||||
|
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
TOOL_NAME = XcodeGen
|
||||
export EXECUTABLE_NAME = xcodegen
|
||||
VERSION = 2.37.0
|
||||
VERSION = 2.38.0
|
||||
|
||||
PREFIX = /usr/local
|
||||
INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME)
|
||||
|
@ -113,7 +113,7 @@ swift run xcodegen
|
||||
Add the following to your Package.swift file's dependencies:
|
||||
|
||||
```swift
|
||||
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.37.0"),
|
||||
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.38.0"),
|
||||
```
|
||||
|
||||
And then import wherever needed: `import XcodeGenKit`
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGETED_DEVICE_FAMILY: 3
|
||||
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"]
|
||||
SDKROOT: appletvos
|
||||
TARGETED_DEVICE_FAMILY: 3
|
||||
|
5
SettingPresets/SupportedDestinations/iOS.yml
Normal file
5
SettingPresets/SupportedDestinations/iOS.yml
Normal file
@ -0,0 +1,5 @@
|
||||
SUPPORTED_PLATFORMS: iphoneos iphonesimulator
|
||||
TARGETED_DEVICE_FAMILY: '1,2'
|
||||
SUPPORTS_MACCATALYST: NO
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: YES
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: YES
|
2
SettingPresets/SupportedDestinations/macCatalyst.yml
Normal file
2
SettingPresets/SupportedDestinations/macCatalyst.yml
Normal file
@ -0,0 +1,2 @@
|
||||
SUPPORTS_MACCATALYST: YES
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
|
3
SettingPresets/SupportedDestinations/macOS.yml
Normal file
3
SettingPresets/SupportedDestinations/macOS.yml
Normal file
@ -0,0 +1,3 @@
|
||||
SUPPORTED_PLATFORMS: macosx
|
||||
SUPPORTS_MACCATALYST: NO
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
|
2
SettingPresets/SupportedDestinations/tvOS.yml
Normal file
2
SettingPresets/SupportedDestinations/tvOS.yml
Normal file
@ -0,0 +1,2 @@
|
||||
SUPPORTED_PLATFORMS: appletvos appletvsimulator
|
||||
TARGETED_DEVICE_FAMILY: '3'
|
3
SettingPresets/SupportedDestinations/visionOS.yml
Normal file
3
SettingPresets/SupportedDestinations/visionOS.yml
Normal file
@ -0,0 +1,3 @@
|
||||
SUPPORTED_PLATFORMS: xros xrsimulator
|
||||
TARGETED_DEVICE_FAMILY: '7'
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: NO
|
@ -8,6 +8,7 @@ public struct AggregateTarget: ProjectTarget {
|
||||
public var targets: [String]
|
||||
public var settings: Settings
|
||||
public var buildScripts: [BuildScript]
|
||||
public var buildToolPlugins: [BuildToolPlugin]
|
||||
public var configFiles: [String: String]
|
||||
public var scheme: TargetScheme?
|
||||
public var attributes: [String: Any]
|
||||
@ -18,6 +19,7 @@ public struct AggregateTarget: ProjectTarget {
|
||||
settings: Settings = .empty,
|
||||
configFiles: [String: String] = [:],
|
||||
buildScripts: [BuildScript] = [],
|
||||
buildToolPlugins: [BuildToolPlugin] = [],
|
||||
scheme: TargetScheme? = nil,
|
||||
attributes: [String: Any] = [:]
|
||||
) {
|
||||
@ -26,6 +28,7 @@ public struct AggregateTarget: ProjectTarget {
|
||||
self.settings = settings
|
||||
self.configFiles = configFiles
|
||||
self.buildScripts = buildScripts
|
||||
self.buildToolPlugins = buildToolPlugins
|
||||
self.scheme = scheme
|
||||
self.attributes = attributes
|
||||
}
|
||||
@ -46,6 +49,7 @@ extension AggregateTarget: Equatable {
|
||||
lhs.settings == rhs.settings &&
|
||||
lhs.configFiles == rhs.configFiles &&
|
||||
lhs.buildScripts == rhs.buildScripts &&
|
||||
lhs.buildToolPlugins == rhs.buildToolPlugins &&
|
||||
lhs.scheme == rhs.scheme &&
|
||||
NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
|
||||
}
|
||||
@ -59,6 +63,7 @@ extension AggregateTarget: NamedJSONDictionaryConvertible {
|
||||
settings = jsonDictionary.json(atKeyPath: "settings") ?? .empty
|
||||
configFiles = jsonDictionary.json(atKeyPath: "configFiles") ?? [:]
|
||||
buildScripts = jsonDictionary.json(atKeyPath: "buildScripts") ?? []
|
||||
buildToolPlugins = jsonDictionary.json(atKeyPath: "buildToolPlugins") ?? []
|
||||
scheme = jsonDictionary.json(atKeyPath: "scheme")
|
||||
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:]
|
||||
}
|
||||
@ -72,6 +77,7 @@ extension AggregateTarget: JSONEncodable {
|
||||
"configFiles": configFiles,
|
||||
"attributes": attributes,
|
||||
"buildScripts": buildScripts.map { $0.toJSONValue() },
|
||||
"buildToolPlugins": buildToolPlugins.map { $0.toJSONValue() },
|
||||
"scheme": scheme?.toJSONValue(),
|
||||
] as [String: Any?]
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ public struct Dependency: Equatable {
|
||||
public var implicit: Bool = implicitDefault
|
||||
public var weakLink: Bool = weakLinkDefault
|
||||
public var platformFilter: PlatformFilter = platformFilterDefault
|
||||
public var destinationFilters: [SupportedDestination]?
|
||||
public var platforms: Set<Platform>?
|
||||
public var copyPhase: BuildPhaseSpec.CopyFilesSettings?
|
||||
|
||||
@ -28,6 +29,7 @@ public struct Dependency: Equatable {
|
||||
implicit: Bool = implicitDefault,
|
||||
weakLink: Bool = weakLinkDefault,
|
||||
platformFilter: PlatformFilter = platformFilterDefault,
|
||||
destinationFilters: [SupportedDestination]? = nil,
|
||||
platforms: Set<Platform>? = nil,
|
||||
copyPhase: BuildPhaseSpec.CopyFilesSettings? = nil
|
||||
) {
|
||||
@ -39,6 +41,7 @@ public struct Dependency: Equatable {
|
||||
self.implicit = implicit
|
||||
self.weakLink = weakLink
|
||||
self.platformFilter = platformFilter
|
||||
self.destinationFilters = destinationFilters
|
||||
self.platforms = platforms
|
||||
self.copyPhase = copyPhase
|
||||
}
|
||||
@ -48,7 +51,7 @@ public struct Dependency: Equatable {
|
||||
case iOS
|
||||
case macOS
|
||||
}
|
||||
|
||||
|
||||
public enum CarthageLinkType: String {
|
||||
case dynamic
|
||||
case `static`
|
||||
@ -61,7 +64,7 @@ public struct Dependency: Equatable {
|
||||
case framework
|
||||
case carthage(findFrameworks: Bool?, linkType: CarthageLinkType)
|
||||
case sdk(root: String?)
|
||||
case package(product: String?)
|
||||
case package(products: [String])
|
||||
case bundle
|
||||
}
|
||||
}
|
||||
@ -69,9 +72,9 @@ public struct Dependency: Equatable {
|
||||
extension Dependency {
|
||||
public var uniqueID: String {
|
||||
switch type {
|
||||
case .package(let product):
|
||||
if let product = product {
|
||||
return "\(reference)/\(product)"
|
||||
case .package(let products):
|
||||
if !products.isEmpty {
|
||||
return "\(reference)/\(products.joined(separator: ","))"
|
||||
} else {
|
||||
return reference
|
||||
}
|
||||
@ -106,9 +109,16 @@ extension Dependency: JSONObjectConvertible {
|
||||
type = .sdk(root: sdkRoot)
|
||||
reference = sdk
|
||||
} else if let package: String = jsonDictionary.json(atKeyPath: "package") {
|
||||
let product: String? = jsonDictionary.json(atKeyPath: "product")
|
||||
type = .package(product: product)
|
||||
reference = package
|
||||
if let products: [String] = jsonDictionary.json(atKeyPath: "products") {
|
||||
type = .package(products: products)
|
||||
reference = package
|
||||
} else if let product: String = jsonDictionary.json(atKeyPath: "product") {
|
||||
type = .package(products: [product])
|
||||
reference = package
|
||||
} else {
|
||||
type = .package(products: [])
|
||||
reference = package
|
||||
}
|
||||
} else if let bundle: String = jsonDictionary.json(atKeyPath: "bundle") {
|
||||
type = .bundle
|
||||
reference = bundle
|
||||
@ -135,7 +145,11 @@ extension Dependency: JSONObjectConvertible {
|
||||
} else {
|
||||
self.platformFilter = .all
|
||||
}
|
||||
|
||||
|
||||
if let destinationFilters: [SupportedDestination] = jsonDictionary.json(atKeyPath: "destinationFilters") {
|
||||
self.destinationFilters = destinationFilters
|
||||
}
|
||||
|
||||
if let platforms: [ProjectSpec.Platform] = jsonDictionary.json(atKeyPath: "platforms") {
|
||||
self.platforms = Set(platforms)
|
||||
}
|
||||
@ -154,6 +168,7 @@ extension Dependency: JSONEncodable {
|
||||
"link": link,
|
||||
"platforms": platforms?.map(\.rawValue).sorted(),
|
||||
"copy": copyPhase?.toJSONValue(),
|
||||
"destinationFilters": destinationFilters?.map { $0.rawValue },
|
||||
]
|
||||
|
||||
if removeHeaders != Dependency.removeHeadersDefault {
|
||||
|
@ -26,6 +26,7 @@ public struct DeploymentTarget: Equatable {
|
||||
|
||||
public func version(for platform: Platform) -> Version? {
|
||||
switch platform {
|
||||
case .auto: return nil
|
||||
case .iOS: return iOS
|
||||
case .tvOS: return tvOS
|
||||
case .watchOS: return watchOS
|
||||
@ -39,6 +40,7 @@ extension Platform {
|
||||
|
||||
public var deploymentTargetSetting: String {
|
||||
switch self {
|
||||
case .auto: return ""
|
||||
case .iOS: return "IPHONEOS_DEPLOYMENT_TARGET"
|
||||
case .tvOS: return "TVOS_DEPLOYMENT_TARGET"
|
||||
case .watchOS: return "WATCHOS_DEPLOYMENT_TARGET"
|
||||
@ -49,6 +51,7 @@ extension Platform {
|
||||
|
||||
public var sdkRoot: String {
|
||||
switch self {
|
||||
case .auto: return "auto"
|
||||
case .iOS: return "iphoneos"
|
||||
case .tvOS: return "appletvos"
|
||||
case .watchOS: return "watchos"
|
||||
|
@ -1,9 +1,10 @@
|
||||
import Foundation
|
||||
|
||||
public enum Platform: String, Hashable, CaseIterable {
|
||||
case auto
|
||||
case iOS
|
||||
case watchOS
|
||||
case tvOS
|
||||
case macOS
|
||||
case watchOS
|
||||
case visionOS
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ extension Plist: JSONEncodable {
|
||||
[
|
||||
"path": path,
|
||||
"properties": properties,
|
||||
]
|
||||
] as [String : Any]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ public protocol ProjectTarget: BuildSettingsContainer {
|
||||
var name: String { get }
|
||||
var type: PBXProductType { get }
|
||||
var buildScripts: [BuildScript] { get }
|
||||
var buildToolPlugins: [BuildToolPlugin] { get }
|
||||
var scheme: TargetScheme? { get }
|
||||
var attributes: [String: Any] { get }
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ extension Settings: JSONEncodable {
|
||||
"base": buildSettings,
|
||||
"groups": groups,
|
||||
"configs": configSettings.mapValues { $0.toJSONValue() },
|
||||
]
|
||||
] as [String : Any]
|
||||
}
|
||||
return buildSettings
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
case unknownPackageRequirement([String: Any])
|
||||
case invalidSourceBuildPhase(String)
|
||||
case invalidTargetReference(String)
|
||||
case invalidTargetPlatformAsArray
|
||||
case invalidVersion(String)
|
||||
case unknownBreakpointType(String)
|
||||
case unknownBreakpointScope(String)
|
||||
@ -27,6 +28,8 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
return "Invalid Source Build Phase: \(error)"
|
||||
case let .invalidTargetReference(targetReference):
|
||||
return "Invalid Target Reference Syntax: \(targetReference)"
|
||||
case .invalidTargetPlatformAsArray:
|
||||
return "Invalid Target platform: Array not allowed with supported destinations"
|
||||
case let .invalidVersion(version):
|
||||
return "Invalid version: \(version)"
|
||||
case let .unknownPackageRequirement(package):
|
||||
|
@ -144,6 +144,12 @@ extension Project {
|
||||
}
|
||||
|
||||
errors += validateSettings(target.settings)
|
||||
|
||||
for buildToolPlugin in target.buildToolPlugins {
|
||||
if packages[buildToolPlugin.package] == nil {
|
||||
errors.append(.invalidPluginPackageReference(plugin: buildToolPlugin.plugin, package: buildToolPlugin.package))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for target in aggregateTargets {
|
||||
@ -174,11 +180,28 @@ extension Project {
|
||||
errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string))
|
||||
}
|
||||
}
|
||||
|
||||
for buildToolPlugin in target.buildToolPlugins {
|
||||
if packages[buildToolPlugin.package] == nil {
|
||||
errors.append(.invalidPluginPackageReference(plugin: buildToolPlugin.plugin, package: buildToolPlugin.package))
|
||||
}
|
||||
|
||||
if target.supportedDestinations != nil, target.platform == .watchOS {
|
||||
errors.append(.unexpectedTargetPlatformForSupportedDestinations(target: target.name, platform: target.platform))
|
||||
}
|
||||
|
||||
if target.supportedDestinations?.contains(.macOS) == true,
|
||||
target.supportedDestinations?.contains(.macCatalyst) == true {
|
||||
|
||||
errors.append(.multipleMacPlatformsInSupportedDestinations(target: target.name))
|
||||
}
|
||||
|
||||
if target.supportedDestinations?.contains(.macCatalyst) == true,
|
||||
target.platform != .iOS, target.platform != .auto {
|
||||
|
||||
errors.append(.invalidTargetPlatformForSupportedDestinations(target: target.name))
|
||||
}
|
||||
|
||||
if target.platform != .auto, target.platform != .watchOS,
|
||||
let supportedDestination = SupportedDestination(rawValue: target.platform.rawValue),
|
||||
target.supportedDestinations?.contains(supportedDestination) == false {
|
||||
|
||||
errors.append(.missingTargetPlatformInSupportedDestinations(target: target.name, platform: target.platform))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,10 @@ public struct SpecValidationError: Error, CustomStringConvertible {
|
||||
case invalidTargetConfigFile(target: String, configFile: String, config: String)
|
||||
case invalidTargetSchemeConfigVariant(target: String, configVariant: String, configType: ConfigType)
|
||||
case invalidTargetSchemeTest(target: String, testTarget: String)
|
||||
case invalidTargetPlatformForSupportedDestinations(target: String)
|
||||
case unexpectedTargetPlatformForSupportedDestinations(target: String, platform: Platform)
|
||||
case multipleMacPlatformsInSupportedDestinations(target: String)
|
||||
case missingTargetPlatformInSupportedDestinations(target: String, platform: Platform)
|
||||
case invalidSchemeTarget(scheme: String, target: String, action: String)
|
||||
case invalidSchemeConfig(scheme: String, config: String)
|
||||
case invalidSwiftPackage(name: String, target: String)
|
||||
@ -54,6 +58,14 @@ public struct SpecValidationError: Error, CustomStringConvertible {
|
||||
return "Target \(target.quoted) has an invalid scheme config variant which requires a config that has a \(configType.rawValue.quoted) type and contains the name \(configVariant.quoted)"
|
||||
case let .invalidTargetSchemeTest(target, test):
|
||||
return "Target \(target.quoted) scheme has invalid test \(test.quoted)"
|
||||
case let .invalidTargetPlatformForSupportedDestinations(target):
|
||||
return "Target \(target.quoted) has supported destinations that require a target platform iOS or auto"
|
||||
case let .unexpectedTargetPlatformForSupportedDestinations(target, platform):
|
||||
return "Target \(target.quoted) has platform \(platform.rawValue.quoted) that does not expect supported destinations"
|
||||
case let .multipleMacPlatformsInSupportedDestinations(target):
|
||||
return "Target \(target.quoted) has multiple definitions of mac platforms in supported destinations"
|
||||
case let .missingTargetPlatformInSupportedDestinations(target, platform):
|
||||
return "Target \(target.quoted) has platform \(platform.rawValue.quoted) that is missing in supported destinations"
|
||||
case let .invalidConfigFile(configFile, config):
|
||||
return "Invalid config file \(configFile.quoted) for config \(config.quoted)"
|
||||
case let .invalidSchemeTarget(scheme, target, action):
|
||||
|
45
Sources/ProjectSpec/SupportedDestination.swift
Normal file
45
Sources/ProjectSpec/SupportedDestination.swift
Normal file
@ -0,0 +1,45 @@
|
||||
import Foundation
|
||||
|
||||
public enum SupportedDestination: String, CaseIterable {
|
||||
case iOS
|
||||
case tvOS
|
||||
case macOS
|
||||
case macCatalyst
|
||||
case visionOS
|
||||
}
|
||||
|
||||
extension SupportedDestination {
|
||||
|
||||
public var string: String {
|
||||
switch self {
|
||||
case .iOS:
|
||||
return "ios"
|
||||
case .tvOS:
|
||||
return "tvos"
|
||||
case .macOS:
|
||||
return "macos"
|
||||
case .macCatalyst:
|
||||
return "maccatalyst"
|
||||
case .visionOS:
|
||||
return "xros"
|
||||
}
|
||||
}
|
||||
|
||||
// This is used to:
|
||||
// 1. Get the first one and apply SettingPresets 'Platforms' and 'Product_Platform' if the platform is 'auto'
|
||||
// 2. Sort, loop and merge together SettingPresets 'SupportedDestinations'
|
||||
public var priority: Int {
|
||||
switch self {
|
||||
case .iOS:
|
||||
return 0
|
||||
case .tvOS:
|
||||
return 1
|
||||
case .visionOS:
|
||||
return 2
|
||||
case .macOS:
|
||||
return 3
|
||||
case .macCatalyst:
|
||||
return 4
|
||||
}
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ public struct Target: ProjectTarget {
|
||||
public var name: String
|
||||
public var type: PBXProductType
|
||||
public var platform: Platform
|
||||
public var supportedDestinations: [SupportedDestination]?
|
||||
public var settings: Settings
|
||||
public var sources: [TargetSource]
|
||||
public var dependencies: [Dependency]
|
||||
@ -58,7 +59,7 @@ public struct Target: ProjectTarget {
|
||||
public var productName: String
|
||||
public var onlyCopyFilesOnInstall: Bool
|
||||
public var putResourcesBeforeSourcesBuildPhase: Bool
|
||||
|
||||
|
||||
public var isLegacy: Bool {
|
||||
legacy != nil
|
||||
}
|
||||
@ -78,6 +79,7 @@ public struct Target: ProjectTarget {
|
||||
name: String,
|
||||
type: PBXProductType,
|
||||
platform: Platform,
|
||||
supportedDestinations: [SupportedDestination]? = nil,
|
||||
productName: String? = nil,
|
||||
deploymentTarget: Version? = nil,
|
||||
settings: Settings = .empty,
|
||||
@ -103,6 +105,7 @@ public struct Target: ProjectTarget {
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.platform = platform
|
||||
self.supportedDestinations = supportedDestinations
|
||||
self.deploymentTarget = deploymentTarget
|
||||
self.productName = productName ?? name
|
||||
self.settings = settings
|
||||
@ -162,15 +165,17 @@ extension Target {
|
||||
guard let targetsDictionary: [String: JSONDictionary] = jsonDictionary["targets"] as? [String: JSONDictionary] else {
|
||||
return jsonDictionary
|
||||
}
|
||||
|
||||
|
||||
var crossPlatformTargets: [String: JSONDictionary] = [:]
|
||||
|
||||
for (targetName, target) in targetsDictionary {
|
||||
|
||||
if let platforms = target["platform"] as? [String] {
|
||||
|
||||
for platform in platforms {
|
||||
var platformTarget = target
|
||||
|
||||
/// This value is set to help us to check, in Target init, that there are no conflicts in the definition of the platforms. We want to ensure that the user didn't define, at the same time,
|
||||
/// the new Xcode 14 supported destinations and the XcodeGen generation of Multiple Platform Targets (when you define the platform field as an array).
|
||||
platformTarget["isMultiPlatformTarget"] = true
|
||||
|
||||
platformTarget = platformTarget.expand(variables: ["platform": platform])
|
||||
|
||||
@ -202,8 +207,8 @@ extension Target {
|
||||
crossPlatformTargets[targetName] = target
|
||||
}
|
||||
}
|
||||
|
||||
var merged = jsonDictionary
|
||||
|
||||
merged["targets"] = crossPlatformTargets
|
||||
return merged
|
||||
}
|
||||
@ -268,19 +273,41 @@ extension Target: NamedJSONDictionaryConvertible {
|
||||
let resolvedName: String = jsonDictionary.json(atKeyPath: "name") ?? name
|
||||
self.name = resolvedName
|
||||
productName = jsonDictionary.json(atKeyPath: "productName") ?? resolvedName
|
||||
let typeString: String = try jsonDictionary.json(atKeyPath: "type")
|
||||
|
||||
let typeString: String = jsonDictionary.json(atKeyPath: "type") ?? ""
|
||||
if let type = PBXProductType(string: typeString) {
|
||||
self.type = type
|
||||
} else {
|
||||
throw SpecParsingError.unknownTargetType(typeString)
|
||||
}
|
||||
let platformString: String = try jsonDictionary.json(atKeyPath: "platform")
|
||||
|
||||
if let supportedDestinations: [SupportedDestination] = jsonDictionary.json(atKeyPath: "supportedDestinations") {
|
||||
self.supportedDestinations = supportedDestinations
|
||||
}
|
||||
|
||||
let isResolved = jsonDictionary.json(atKeyPath: "isMultiPlatformTarget") ?? false
|
||||
if isResolved, supportedDestinations != nil {
|
||||
throw SpecParsingError.invalidTargetPlatformAsArray
|
||||
}
|
||||
|
||||
var platformString: String = jsonDictionary.json(atKeyPath: "platform") ?? ""
|
||||
// platform defaults to 'auto' if it is empty and we are using supported destinations
|
||||
if supportedDestinations != nil, platformString.isEmpty {
|
||||
platformString = Platform.auto.rawValue
|
||||
}
|
||||
// we add 'iOS' in supported destinations if it contains only 'macCatalyst'
|
||||
if supportedDestinations?.contains(.macCatalyst) == true,
|
||||
supportedDestinations?.contains(.iOS) == false {
|
||||
|
||||
supportedDestinations?.append(.iOS)
|
||||
}
|
||||
|
||||
if let platform = Platform(rawValue: platformString) {
|
||||
self.platform = platform
|
||||
} else {
|
||||
throw SpecParsingError.unknownTargetPlatform(platformString)
|
||||
}
|
||||
|
||||
|
||||
if let string: String = jsonDictionary.json(atKeyPath: "deploymentTarget") {
|
||||
deploymentTarget = try Version.parse(string)
|
||||
} else if let double: Double = jsonDictionary.json(atKeyPath: "deploymentTarget") {
|
||||
@ -351,6 +378,7 @@ extension Target: JSONEncodable {
|
||||
var dict: [String: Any?] = [
|
||||
"type": type.name,
|
||||
"platform": platform.rawValue,
|
||||
"supportedDestinations": supportedDestinations?.map { $0.rawValue },
|
||||
"settings": settings.toJSONValue(),
|
||||
"configFiles": configFiles,
|
||||
"attributes": attributes,
|
||||
|
@ -23,6 +23,8 @@ public struct TargetSource: Equatable {
|
||||
public var createIntermediateGroups: Bool?
|
||||
public var attributes: [String]
|
||||
public var resourceTags: [String]
|
||||
public var inferDestinationFiltersByPath: Bool?
|
||||
public var destinationFilters: [SupportedDestination]?
|
||||
|
||||
public enum HeaderVisibility: String {
|
||||
case `public`
|
||||
@ -51,7 +53,9 @@ public struct TargetSource: Equatable {
|
||||
headerVisibility: HeaderVisibility? = nil,
|
||||
createIntermediateGroups: Bool? = nil,
|
||||
attributes: [String] = [],
|
||||
resourceTags: [String] = []
|
||||
resourceTags: [String] = [],
|
||||
inferDestinationFiltersByPath: Bool? = nil,
|
||||
destinationFilters: [SupportedDestination]? = nil
|
||||
) {
|
||||
self.path = (path as NSString).standardizingPath
|
||||
self.name = name
|
||||
@ -66,6 +70,8 @@ public struct TargetSource: Equatable {
|
||||
self.createIntermediateGroups = createIntermediateGroups
|
||||
self.attributes = attributes
|
||||
self.resourceTags = resourceTags
|
||||
self.inferDestinationFiltersByPath = inferDestinationFiltersByPath
|
||||
self.destinationFilters = destinationFilters
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +118,12 @@ extension TargetSource: JSONObjectConvertible {
|
||||
createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups")
|
||||
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? []
|
||||
resourceTags = jsonDictionary.json(atKeyPath: "resourceTags") ?? []
|
||||
|
||||
inferDestinationFiltersByPath = jsonDictionary.json(atKeyPath: "inferDestinationFiltersByPath")
|
||||
|
||||
if let destinationFilters: [SupportedDestination] = jsonDictionary.json(atKeyPath: "destinationFilters") {
|
||||
self.destinationFilters = destinationFilters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +141,8 @@ extension TargetSource: JSONEncodable {
|
||||
"createIntermediateGroups": createIntermediateGroups,
|
||||
"resourceTags": resourceTags,
|
||||
"path": path,
|
||||
"inferDestinationFiltersByPath": inferDestinationFiltersByPath,
|
||||
"destinationFilters": destinationFilters?.map { $0.rawValue },
|
||||
]
|
||||
|
||||
if optional != TargetSource.optionalDefault {
|
||||
|
@ -25,7 +25,7 @@ extension TestPlan: JSONEncodable {
|
||||
[
|
||||
"path": path,
|
||||
"defaultPlan": defaultPlan,
|
||||
]
|
||||
] as [String : Any]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ extension Platform {
|
||||
|
||||
public var emoji: String {
|
||||
switch self {
|
||||
case .auto: return "🤖"
|
||||
case .iOS: return "📱"
|
||||
case .watchOS: return "⌚️"
|
||||
case .tvOS: return "📺"
|
||||
|
@ -3,6 +3,6 @@ import ProjectSpec
|
||||
import XcodeGenCLI
|
||||
import Version
|
||||
|
||||
let version = Version("2.37.0")
|
||||
let version = Version("2.38.0")
|
||||
let cli = XcodeGenCLI(version: version)
|
||||
cli.execute()
|
||||
|
@ -151,6 +151,9 @@ extension Platform {
|
||||
|
||||
public var carthageName: String {
|
||||
switch self {
|
||||
case .auto:
|
||||
// This is a dummy value
|
||||
return "auto"
|
||||
case .iOS:
|
||||
return "iOS"
|
||||
case .tvOS:
|
||||
|
@ -30,6 +30,7 @@ public class PBXProjGenerator {
|
||||
var generated = false
|
||||
|
||||
private var projects: [ProjectReference: PBXProj] = [:]
|
||||
lazy private var localPackageReferences: [String] = project.packages.compactMap { $0.value.isLocal ? $0.key : nil }
|
||||
|
||||
public init(project: Project, projectDirectory: Path? = nil) {
|
||||
self.project = project
|
||||
@ -339,7 +340,7 @@ public class PBXProjGenerator {
|
||||
return addObject(buildConfig)
|
||||
}
|
||||
|
||||
let dependencies = target.targets.map { generateTargetDependency(from: target.name, to: $0, platform: nil) }
|
||||
var dependencies = target.targets.map { generateTargetDependency(from: target.name, to: $0, platform: nil, platforms: nil) }
|
||||
|
||||
let defaultConfigurationName = project.options.defaultConfig ?? project.configs.first?.name ?? ""
|
||||
let buildConfigList = addObject(XCConfigurationList(
|
||||
@ -350,12 +351,15 @@ public class PBXProjGenerator {
|
||||
var buildPhases: [PBXBuildPhase] = []
|
||||
buildPhases += try target.buildScripts.map { try generateBuildScript(targetName: target.name, buildScript: $0) }
|
||||
|
||||
let packagePluginDependencies = makePackagePluginDependency(for: target)
|
||||
dependencies.append(contentsOf: packagePluginDependencies)
|
||||
|
||||
aggregateTarget.buildPhases = buildPhases
|
||||
aggregateTarget.buildConfigurationList = buildConfigList
|
||||
aggregateTarget.dependencies = dependencies
|
||||
}
|
||||
|
||||
func generateTargetDependency(from: String, to target: String, platform: String?) -> PBXTargetDependency {
|
||||
func generateTargetDependency(from: String, to target: String, platform: String?, platforms: [String]?) -> PBXTargetDependency {
|
||||
guard let targetObject = targetObjects[target] ?? targetAggregateObjects[target] else {
|
||||
fatalError("Target dependency not found: from ( \(from) ) to ( \(target) )")
|
||||
}
|
||||
@ -372,6 +376,7 @@ public class PBXProjGenerator {
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(
|
||||
platformFilter: platform,
|
||||
platformFilters: platforms,
|
||||
target: targetObject,
|
||||
targetProxy: targetProxy
|
||||
)
|
||||
@ -692,7 +697,6 @@ public class PBXProjGenerator {
|
||||
var systemExtensions: [PBXBuildFile] = []
|
||||
var appClips: [PBXBuildFile] = []
|
||||
var carthageFrameworksToEmbed: [String] = []
|
||||
let localPackageReferences: [String] = project.packages.compactMap { $0.value.isLocal ? $0.key : nil }
|
||||
|
||||
let targetDependencies = (target.transitivelyLinkDependencies ?? project.options.transitivelyLinkDependencies) ?
|
||||
getAllDependenciesPlusTransitiveNeedingEmbedding(target: target) : target.dependencies
|
||||
@ -724,7 +728,7 @@ public class PBXProjGenerator {
|
||||
return !linkingAttributes.isEmpty ? ["ATTRIBUTES": linkingAttributes] : nil
|
||||
}
|
||||
|
||||
func processTargetDependency(_ dependency: Dependency, dependencyTarget: Target, embedFileReference: PBXFileElement?, platform: String?) {
|
||||
func processTargetDependency(_ dependency: Dependency, dependencyTarget: Target, embedFileReference: PBXFileElement?, platform: String?, platforms: [String]?) {
|
||||
let dependencyLinkage = dependencyTarget.defaultLinkage
|
||||
let link = dependency.link ??
|
||||
((dependencyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
@ -733,6 +737,7 @@ public class PBXProjGenerator {
|
||||
if link, let dependencyFile = embedFileReference {
|
||||
let pbxBuildFile = PBXBuildFile(file: dependencyFile, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let buildFile = addObject(pbxBuildFile)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
|
||||
@ -749,6 +754,7 @@ public class PBXProjGenerator {
|
||||
settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? !dependencyTarget.type.isExecutable)
|
||||
)
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let embedFile = addObject(pbxBuildFile)
|
||||
|
||||
if dependency.copyPhase != nil {
|
||||
@ -784,6 +790,7 @@ public class PBXProjGenerator {
|
||||
|
||||
let embed = dependency.embed ?? target.shouldEmbedDependencies
|
||||
let platform = makePlatformFilter(for: dependency.platformFilter)
|
||||
let platforms = makeDestinationFilters(for: dependency.destinationFilters)
|
||||
|
||||
switch dependency.type {
|
||||
case .target:
|
||||
@ -792,15 +799,15 @@ public class PBXProjGenerator {
|
||||
switch dependencyTargetReference.location {
|
||||
case .local:
|
||||
let dependencyTargetName = dependency.reference
|
||||
let targetDependency = generateTargetDependency(from: target.name, to: dependencyTargetName, platform: platform)
|
||||
let targetDependency = generateTargetDependency(from: target.name, to: dependencyTargetName, platform: platform, platforms: platforms)
|
||||
dependencies.append(targetDependency)
|
||||
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: targetFileReferences[dependencyTarget.name], platform: platform)
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: targetFileReferences[dependencyTarget.name], platform: platform, platforms: platforms)
|
||||
case .project(let dependencyProjectName):
|
||||
let dependencyTargetName = dependencyTargetReference.name
|
||||
let (targetDependency, dependencyTarget, dependencyProductProxy) = try generateExternalTargetDependency(from: target.name, to: dependencyTargetName, in: dependencyProjectName, platform: target.platform)
|
||||
dependencies.append(targetDependency)
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: dependencyProductProxy, platform: platform)
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: dependencyProductProxy, platform: platform, platforms: platforms)
|
||||
}
|
||||
|
||||
case .framework:
|
||||
@ -826,6 +833,7 @@ public class PBXProjGenerator {
|
||||
if dependency.link ?? (target.type != .staticLibrary) {
|
||||
let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let buildFile = addObject(pbxBuildFile)
|
||||
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
@ -838,6 +846,7 @@ public class PBXProjGenerator {
|
||||
if embed {
|
||||
let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let embedFile = addObject(pbxBuildFile)
|
||||
|
||||
if dependency.copyPhase != nil {
|
||||
@ -888,12 +897,14 @@ public class PBXProjGenerator {
|
||||
settings: getDependencyFrameworkSettings(dependency: dependency)
|
||||
)
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let buildFile = addObject(pbxBuildFile)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
|
||||
if dependency.embed == true {
|
||||
let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let embedFile = addObject(pbxBuildFile)
|
||||
|
||||
if dependency.copyPhase != nil {
|
||||
@ -923,12 +934,13 @@ public class PBXProjGenerator {
|
||||
if dependency.link ?? (!isStaticLibrary && !isCarthageStaticLink) {
|
||||
let pbxBuildFile = PBXBuildFile(file: fileReference, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let buildFile = addObject(pbxBuildFile)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
}
|
||||
}
|
||||
// Embedding handled by iterating over `carthageDependencies` below
|
||||
case .package(let product):
|
||||
case .package(let products):
|
||||
let packageReference = packageReferences[dependency.reference]
|
||||
|
||||
// If package's reference is none and there is no specified package in localPackages,
|
||||
@ -937,40 +949,51 @@ public class PBXProjGenerator {
|
||||
continue
|
||||
}
|
||||
|
||||
let productName = product ?? dependency.reference
|
||||
let packageDependency = addObject(
|
||||
XCSwiftPackageProductDependency(productName: productName, package: packageReference)
|
||||
)
|
||||
|
||||
// Add package dependency if linking is true.
|
||||
if dependency.link ?? true {
|
||||
packageDependencies.append(packageDependency)
|
||||
}
|
||||
|
||||
let link = dependency.link ?? (target.type != .staticLibrary)
|
||||
if link {
|
||||
let file = PBXBuildFile(product: packageDependency, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
file.platformFilter = platform
|
||||
let buildFile = addObject(file)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
} else {
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(platformFilter: platform, product: packageDependency)
|
||||
func addPackageProductDependency(named productName: String) {
|
||||
let packageDependency = addObject(
|
||||
XCSwiftPackageProductDependency(productName: productName, package: packageReference)
|
||||
)
|
||||
dependencies.append(targetDependency)
|
||||
|
||||
// Add package dependency if linking is true.
|
||||
if dependency.link ?? true {
|
||||
packageDependencies.append(packageDependency)
|
||||
}
|
||||
|
||||
let link = dependency.link ?? (target.type != .staticLibrary)
|
||||
if link {
|
||||
let file = PBXBuildFile(product: packageDependency, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
file.platformFilter = platform
|
||||
file.platformFilters = platforms
|
||||
let buildFile = addObject(file)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
} else {
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(platformFilter: platform, platformFilters: platforms, product: packageDependency)
|
||||
)
|
||||
dependencies.append(targetDependency)
|
||||
}
|
||||
|
||||
if dependency.embed == true {
|
||||
let pbxBuildFile = PBXBuildFile(product: packageDependency,
|
||||
settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let embedFile = addObject(pbxBuildFile)
|
||||
|
||||
if dependency.copyPhase != nil {
|
||||
customCopyDependenciesReferences.append(embedFile)
|
||||
} else {
|
||||
copyFrameworksReferences.append(embedFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if dependency.embed == true {
|
||||
let pbxBuildFile = PBXBuildFile(product: packageDependency,
|
||||
settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true))
|
||||
pbxBuildFile.platformFilter = platform
|
||||
let embedFile = addObject(pbxBuildFile)
|
||||
|
||||
if dependency.copyPhase != nil {
|
||||
customCopyDependenciesReferences.append(embedFile)
|
||||
} else {
|
||||
copyFrameworksReferences.append(embedFile)
|
||||
if !products.isEmpty {
|
||||
for product in products {
|
||||
addPackageProductDependency(named: product)
|
||||
}
|
||||
} else {
|
||||
addPackageProductDependency(named: dependency.reference)
|
||||
}
|
||||
case .bundle:
|
||||
// Static and dynamic libraries can't copy resources
|
||||
@ -987,6 +1010,7 @@ public class PBXProjGenerator {
|
||||
settings: embed ? getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true) : nil
|
||||
)
|
||||
pbxBuildFile.platformFilter = platform
|
||||
pbxBuildFile.platformFilters = platforms
|
||||
let buildFile = addObject(pbxBuildFile)
|
||||
copyBundlesReferences.append(buildFile)
|
||||
|
||||
@ -1032,22 +1056,8 @@ public class PBXProjGenerator {
|
||||
|
||||
carthageFrameworksToEmbed = carthageFrameworksToEmbed.uniqued()
|
||||
|
||||
// Adding `Build Tools Plug-ins` as a dependency to the target
|
||||
for buildToolPlugin in target.buildToolPlugins {
|
||||
let packageReference = packageReferences[buildToolPlugin.package]
|
||||
if packageReference == nil, !localPackageReferences.contains(buildToolPlugin.package) {
|
||||
continue
|
||||
}
|
||||
|
||||
let packageDependency = addObject(
|
||||
XCSwiftPackageProductDependency(productName: buildToolPlugin.plugin, package: packageReference, isPlugin: true)
|
||||
)
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(product: packageDependency)
|
||||
)
|
||||
|
||||
dependencies.append(targetDependency)
|
||||
}
|
||||
let packagePluginDependencies = makePackagePluginDependency(for: target)
|
||||
dependencies.append(contentsOf: packagePluginDependencies)
|
||||
|
||||
var buildPhases: [PBXBuildPhase] = []
|
||||
|
||||
@ -1447,7 +1457,33 @@ public class PBXProjGenerator {
|
||||
return "ios"
|
||||
}
|
||||
}
|
||||
|
||||
private func makeDestinationFilters(for filters: [SupportedDestination]?) -> [String]? {
|
||||
guard let filters = filters, !filters.isEmpty else { return nil }
|
||||
return filters.map { $0.string }
|
||||
}
|
||||
|
||||
/// Make `Build Tools Plug-ins` as a dependency to the target
|
||||
/// - Parameter target: ProjectTarget
|
||||
/// - Returns: Elements for referencing other targets through content proxies.
|
||||
func makePackagePluginDependency(for target: ProjectTarget) -> [PBXTargetDependency] {
|
||||
target.buildToolPlugins.compactMap { buildToolPlugin in
|
||||
let packageReference = packageReferences[buildToolPlugin.package]
|
||||
if packageReference == nil, !localPackageReferences.contains(buildToolPlugin.package) {
|
||||
return nil
|
||||
}
|
||||
|
||||
let packageDependency = addObject(
|
||||
XCSwiftPackageProductDependency(productName: buildToolPlugin.plugin, package: packageReference, isPlugin: true)
|
||||
)
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(product: packageDependency)
|
||||
)
|
||||
|
||||
return targetDependency
|
||||
}
|
||||
}
|
||||
|
||||
func getInfoPlists(for target: Target) -> [Config: String] {
|
||||
var searchForDefaultInfoPlist: Bool = true
|
||||
var defaultInfoPlist: String?
|
||||
@ -1581,7 +1617,7 @@ extension Platform {
|
||||
/// - returns: `true` for platforms that the app store requires simulator slices to be stripped.
|
||||
public var requiresSimulatorStripping: Bool {
|
||||
switch self {
|
||||
case .iOS, .tvOS, .watchOS, .visionOS:
|
||||
case .auto, .iOS, .tvOS, .watchOS, .visionOS:
|
||||
return true
|
||||
case .macOS:
|
||||
return false
|
||||
|
@ -41,16 +41,63 @@ extension Project {
|
||||
|
||||
public func getTargetBuildSettings(target: Target, config: Config) -> BuildSettings {
|
||||
var buildSettings = BuildSettings()
|
||||
|
||||
|
||||
// list of supported destination sorted by priority
|
||||
let specSupportedDestinations = target.supportedDestinations?.sorted(by: { $0.priority < $1.priority }) ?? []
|
||||
|
||||
if options.settingPresets.applyTarget {
|
||||
buildSettings += SettingsPresetFile.platform(target.platform).getBuildSettings()
|
||||
let platform: Platform
|
||||
|
||||
if target.platform == .auto,
|
||||
let firstDestination = specSupportedDestinations.first,
|
||||
let firstDestinationPlatform = Platform(rawValue: firstDestination.rawValue) {
|
||||
|
||||
platform = firstDestinationPlatform
|
||||
} else {
|
||||
platform = target.platform
|
||||
}
|
||||
|
||||
buildSettings += SettingsPresetFile.platform(platform).getBuildSettings()
|
||||
buildSettings += SettingsPresetFile.product(target.type).getBuildSettings()
|
||||
buildSettings += SettingsPresetFile.productPlatform(target.type, target.platform).getBuildSettings()
|
||||
buildSettings += SettingsPresetFile.productPlatform(target.type, platform).getBuildSettings()
|
||||
|
||||
if target.platform == .auto {
|
||||
// this fix is necessary because the platform preset overrides the original value
|
||||
buildSettings["SDKROOT"] = Platform.auto.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !specSupportedDestinations.isEmpty {
|
||||
var supportedPlatforms: [String] = []
|
||||
var targetedDeviceFamily: [String] = []
|
||||
|
||||
for supportedDestination in specSupportedDestinations {
|
||||
let supportedPlatformBuildSettings = SettingsPresetFile.supportedDestination(supportedDestination).getBuildSettings()
|
||||
buildSettings += supportedPlatformBuildSettings
|
||||
|
||||
if let value = supportedPlatformBuildSettings?["SUPPORTED_PLATFORMS"] as? String {
|
||||
supportedPlatforms += value.components(separatedBy: " ")
|
||||
}
|
||||
if let value = supportedPlatformBuildSettings?["TARGETED_DEVICE_FAMILY"] as? String {
|
||||
targetedDeviceFamily += value.components(separatedBy: ",")
|
||||
}
|
||||
}
|
||||
|
||||
buildSettings["SUPPORTED_PLATFORMS"] = supportedPlatforms.joined(separator: " ")
|
||||
buildSettings["TARGETED_DEVICE_FAMILY"] = targetedDeviceFamily.joined(separator: ",")
|
||||
}
|
||||
|
||||
// apply custom platform version
|
||||
if let version = target.deploymentTarget {
|
||||
buildSettings[target.platform.deploymentTargetSetting] = version.deploymentTarget
|
||||
if !specSupportedDestinations.isEmpty {
|
||||
for supportedDestination in specSupportedDestinations {
|
||||
if let platform = Platform(rawValue: supportedDestination.rawValue) {
|
||||
buildSettings[platform.deploymentTargetSetting] = version.deploymentTarget
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buildSettings[target.platform.deploymentTargetSetting] = version.deploymentTarget
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent setting presets from overrwriting settings in target xcconfig files
|
||||
@ -205,7 +252,7 @@ extension SettingsPresetFile {
|
||||
|
||||
guard let settingsPath = possibleSettingsPaths.first(where: { $0.exists }) else {
|
||||
switch self {
|
||||
case .base, .config, .platform:
|
||||
case .base, .config, .platform, .supportedDestination:
|
||||
print("No \"\(name)\" settings found")
|
||||
case .product, .productPlatform:
|
||||
break
|
||||
|
@ -5,6 +5,7 @@ import XcodeProj
|
||||
public enum SettingsPresetFile {
|
||||
case config(ConfigType)
|
||||
case platform(Platform)
|
||||
case supportedDestination(SupportedDestination)
|
||||
case product(PBXProductType)
|
||||
case productPlatform(PBXProductType, Platform)
|
||||
case base
|
||||
@ -13,6 +14,7 @@ public enum SettingsPresetFile {
|
||||
switch self {
|
||||
case let .config(config): return "Configs/\(config.rawValue)"
|
||||
case let .platform(platform): return "Platforms/\(platform.rawValue)"
|
||||
case let .supportedDestination(supportedDestination): return "SupportedDestinations/\(supportedDestination.rawValue)"
|
||||
case let .product(product): return "Products/\(product.name)"
|
||||
case let .productPlatform(product, platform): return "Product_Platform/\(product.name)_\(platform.rawValue)"
|
||||
case .base: return "base"
|
||||
@ -23,6 +25,7 @@ public enum SettingsPresetFile {
|
||||
switch self {
|
||||
case let .config(config): return "\(config.rawValue) config"
|
||||
case let .platform(platform): return platform.rawValue
|
||||
case let .supportedDestination(supportedDestination): return supportedDestination.rawValue
|
||||
case let .product(product): return product.name
|
||||
case let .productPlatform(product, platform): return "\(platform) \(product)"
|
||||
case .base: return "base"
|
||||
|
@ -109,7 +109,23 @@ class SourceGenerator {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func makeDestinationFilters(for path: Path, with filters: [SupportedDestination]?, or inferDestinationFiltersByPath: Bool?) -> [String]? {
|
||||
if let filters = filters, !filters.isEmpty {
|
||||
return filters.map { $0.string }
|
||||
} else if inferDestinationFiltersByPath == true {
|
||||
for supportedDestination in SupportedDestination.allCases {
|
||||
let regex1 = try? NSRegularExpression(pattern: "\\/\(supportedDestination)\\/", options: .caseInsensitive)
|
||||
let regex2 = try? NSRegularExpression(pattern: "\\_\(supportedDestination)\\.swift$", options: .caseInsensitive)
|
||||
|
||||
if regex1?.isMatch(to: path.string) == true || regex2?.isMatch(to: path.string) == true {
|
||||
return [supportedDestination.string]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateSourceFile(targetType: PBXProductType, targetSource: TargetSource, path: Path, fileReference: PBXFileElement? = nil, buildPhases: [Path: BuildPhaseSpec]) -> SourceFile {
|
||||
let fileReference = fileReference ?? fileReferencesByPath[path.string.lowercased()]!
|
||||
var settings: [String: Any] = [:]
|
||||
@ -174,8 +190,10 @@ class SourceGenerator {
|
||||
if chosenBuildPhase == .resources && !assetTags.isEmpty {
|
||||
settings["ASSET_TAGS"] = assetTags
|
||||
}
|
||||
|
||||
let buildFile = PBXBuildFile(file: fileReference, settings: settings.isEmpty ? nil : settings)
|
||||
|
||||
let platforms = makeDestinationFilters(for: path, with: targetSource.destinationFilters, or: targetSource.inferDestinationFiltersByPath)
|
||||
|
||||
let buildFile = PBXBuildFile(file: fileReference, settings: settings.isEmpty ? nil : settings, platformFilters: platforms)
|
||||
return SourceFile(
|
||||
path: path,
|
||||
fileReference: fileReference,
|
||||
|
20
Tests/Fixtures/SPM/FooFeature/Package.swift
Normal file
20
Tests/Fixtures/SPM/FooFeature/Package.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// swift-tools-version: 5.8
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "FooFeature",
|
||||
products: [
|
||||
.library(name: "FooDomain", targets: [
|
||||
"FooDomain"
|
||||
]),
|
||||
.library(name: "FooUI", targets: [
|
||||
"FooUI"
|
||||
])
|
||||
],
|
||||
targets: [
|
||||
.target(name: "FooDomain"),
|
||||
.target(name: "FooUI")
|
||||
]
|
||||
)
|
@ -0,0 +1 @@
|
||||
public struct FooDomain {}
|
1
Tests/Fixtures/SPM/FooFeature/Sources/FooUI/FooUI.swift
Normal file
1
Tests/Fixtures/SPM/FooFeature/Sources/FooUI/FooUI.swift
Normal file
@ -0,0 +1 @@
|
||||
public struct FooUI {}
|
@ -6,13 +6,29 @@
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
ADD3CE771A0D5E996031A193 /* AggTarget */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = A7ABF1B35D9170092F822790 /* Build configuration list for PBXAggregateTarget "AggTarget" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
D287BAAB664D1A024D9DD57E /* PBXTargetDependency */,
|
||||
);
|
||||
name = AggTarget;
|
||||
productName = AggTarget;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
23C6626698DE560017A89F2F /* XcodeGen in Frameworks */ = {isa = PBXBuildFile; productRef = 6F7DEA2D82649EDF903FBDBD /* XcodeGen */; };
|
||||
2DA7998902987953B119E4CE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F7EFEE613987D1E1258A60 /* AppDelegate.swift */; };
|
||||
36CE2E6187D9709BAD9EF807 /* FooUI in Frameworks */ = {isa = PBXBuildFile; productRef = 927CB19D94339CC9960E930C /* FooUI */; };
|
||||
3986ED6965842721C46C0452 /* SwiftRoaringDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */; };
|
||||
4CC663B42B270404EF5FD037 /* libStaticLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */; };
|
||||
9AD886A88D3E4A1B5E900687 /* SPMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7970A2253B14A9B27C307FAC /* SPMTests.swift */; };
|
||||
9C4AD0711D706FD3ED0E436D /* StaticLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */; };
|
||||
AF8E362713B9D28EA9A5C9FC /* FooDomain in Frameworks */ = {isa = PBXBuildFile; productRef = 8D2DC638BEF7FDF23907E134 /* FooDomain */; };
|
||||
B89EA0F3859878A1DCF7BAFD /* SwiftRoaringDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
CE46CBA5671B951B546C8673 /* Codability in Frameworks */ = {isa = PBXBuildFile; productRef = 16E6FE01D5BD99F78D4A17E2 /* Codability */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
E368431019ABC696E4FFC0CF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */; };
|
||||
@ -57,6 +73,7 @@
|
||||
4E22B8BCC18A29EFE1DE3BE4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
61C17B77601A9D1B7895AB42 /* StaticLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLibrary.swift; sourceTree = "<group>"; };
|
||||
7970A2253B14A9B27C307FAC /* SPMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPMTests.swift; sourceTree = "<group>"; };
|
||||
979AE1767E2AF6B3B9D7F13D /* FooFeature */ = {isa = PBXFileReference; lastKnownFileType = folder; name = FooFeature; path = FooFeature; sourceTree = SOURCE_ROOT; };
|
||||
A9601593D0AD02931266A4E5 /* App.xctestplan */ = {isa = PBXFileReference; path = App.xctestplan; sourceTree = "<group>"; };
|
||||
CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libStaticLibrary.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ED284AB7C13DCC0A95DAA680 /* XcodeGen */ = {isa = PBXFileReference; lastKnownFileType = folder; name = XcodeGen; path = ../../..; sourceTree = SOURCE_ROOT; };
|
||||
@ -71,6 +88,8 @@
|
||||
3986ED6965842721C46C0452 /* SwiftRoaringDynamic in Frameworks */,
|
||||
4CC663B42B270404EF5FD037 /* libStaticLibrary.a in Frameworks */,
|
||||
23C6626698DE560017A89F2F /* XcodeGen in Frameworks */,
|
||||
AF8E362713B9D28EA9A5C9FC /* FooDomain in Frameworks */,
|
||||
36CE2E6187D9709BAD9EF807 /* FooUI in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -100,6 +119,7 @@
|
||||
218F6C96DF9E182F526258CF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AD0F3623091EEA8D1EA3DFF8 /* Packages */,
|
||||
17DD374CC81D710476AFF41C /* SPM */,
|
||||
CF3BD77AEAA56553289456BA /* SPMTests */,
|
||||
1FA59BFD192FB5A68D5F587C /* StaticLibrary */,
|
||||
@ -117,6 +137,14 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AD0F3623091EEA8D1EA3DFF8 /* Packages */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
979AE1767E2AF6B3B9D7F13D /* FooFeature */,
|
||||
);
|
||||
name = Packages;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
CF3BD77AEAA56553289456BA /* SPMTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -157,12 +185,16 @@
|
||||
D85FFB99444DD260A72DDDA7 /* PBXTargetDependency */,
|
||||
DDD17C561AD5065DF4FA4072 /* PBXTargetDependency */,
|
||||
C6360997FFC102F6725099D4 /* PBXTargetDependency */,
|
||||
00B467060F3DEC027711F9C2 /* PBXTargetDependency */,
|
||||
7EB17E90A4D8F26FEABEEDF6 /* PBXTargetDependency */,
|
||||
);
|
||||
name = StaticLibrary;
|
||||
packageProductDependencies = (
|
||||
AF233B61592982A7F6431FC6 /* Codability */,
|
||||
C816AEB28ED71C3C47F31B98 /* SwiftRoaringDynamic */,
|
||||
5A36E2FE69703FCAC0BE8064 /* XcodeGen */,
|
||||
6B8A6E1EA485E607A1D1DCD1 /* FooDomain */,
|
||||
15DB49096E2978F6BCA8D604 /* FooUI */,
|
||||
);
|
||||
productName = StaticLibrary;
|
||||
productReference = CAB5625F6FEA668410ED5482 /* libStaticLibrary.a */;
|
||||
@ -188,6 +220,8 @@
|
||||
16E6FE01D5BD99F78D4A17E2 /* Codability */,
|
||||
DC73B269C8B0C0BF6912842C /* SwiftRoaringDynamic */,
|
||||
6F7DEA2D82649EDF903FBDBD /* XcodeGen */,
|
||||
8D2DC638BEF7FDF23907E134 /* FooDomain */,
|
||||
927CB19D94339CC9960E930C /* FooUI */,
|
||||
);
|
||||
productName = App;
|
||||
productReference = 097F2DB5622B591E21BC3C73 /* App.app */;
|
||||
@ -221,6 +255,7 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
ADD3CE771A0D5E996031A193 /* AggTarget */,
|
||||
C99E3C420D63D5219CE57E33 /* App */,
|
||||
3F8D94C4EFC431F646AAFB28 /* StaticLibrary */,
|
||||
339863E54E2D955C00B56802 /* Tests */,
|
||||
@ -286,11 +321,19 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
00B467060F3DEC027711F9C2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = 6B8A6E1EA485E607A1D1DCD1 /* FooDomain */;
|
||||
};
|
||||
078202CF7B08B66ACF7FEC23 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 3F8D94C4EFC431F646AAFB28 /* StaticLibrary */;
|
||||
targetProxy = 29147E1DDAEB1AAC20CB0CF9 /* PBXContainerItemProxy */;
|
||||
};
|
||||
7EB17E90A4D8F26FEABEEDF6 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = 15DB49096E2978F6BCA8D604 /* FooUI */;
|
||||
};
|
||||
8693351DA9DBE579AC9DD513 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = C99E3C420D63D5219CE57E33 /* App */;
|
||||
@ -300,6 +343,10 @@
|
||||
isa = PBXTargetDependency;
|
||||
productRef = 5A36E2FE69703FCAC0BE8064 /* XcodeGen */;
|
||||
};
|
||||
D287BAAB664D1A024D9DD57E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = 896D1E2063A93D40F04D7864 /* PrefirePlaybookPlugin */;
|
||||
};
|
||||
D85FFB99444DD260A72DDDA7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
productRef = AF233B61592982A7F6431FC6 /* Codability */;
|
||||
@ -315,6 +362,12 @@
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0C023F1AE037C42683029CE9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0CCC06807E5CD8361D899B7F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -360,6 +413,12 @@
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
5E087A904FBC0E623E672507 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
7A384B9B9CF42FCF9EF02057 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -565,6 +624,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Debug;
|
||||
};
|
||||
A7ABF1B35D9170092F822790 /* Build configuration list for PBXAggregateTarget "AggTarget" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0C023F1AE037C42683029CE9 /* Debug */,
|
||||
5E087A904FBC0E623E672507 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Debug;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
@ -595,6 +663,10 @@
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
15DB49096E2978F6BCA8D604 /* FooUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = FooUI;
|
||||
};
|
||||
16E6FE01D5BD99F78D4A17E2 /* Codability */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */;
|
||||
@ -604,10 +676,27 @@
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = XcodeGen;
|
||||
};
|
||||
6B8A6E1EA485E607A1D1DCD1 /* FooDomain */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = FooDomain;
|
||||
};
|
||||
6F7DEA2D82649EDF903FBDBD /* XcodeGen */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = XcodeGen;
|
||||
};
|
||||
896D1E2063A93D40F04D7864 /* PrefirePlaybookPlugin */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 348C81C327DB1710B742C370 /* XCRemoteSwiftPackageReference "Prefire" */;
|
||||
productName = "plugin:PrefirePlaybookPlugin";
|
||||
};
|
||||
8D2DC638BEF7FDF23907E134 /* FooDomain */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = FooDomain;
|
||||
};
|
||||
927CB19D94339CC9960E930C /* FooUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = FooUI;
|
||||
};
|
||||
AF233B61592982A7F6431FC6 /* Codability */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 5BA91390AE78D2EE15C60091 /* XCRemoteSwiftPackageReference "Codability" */;
|
||||
|
@ -1,106 +1,122 @@
|
||||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "AEXML",
|
||||
"repositoryURL": "https://github.com/tadija/AEXML",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "e4d517844dd03dac557e35d77a8e9ab438de91a6",
|
||||
"version": "4.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Codability",
|
||||
"repositoryURL": "https://github.com/yonaskolb/Codability",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "eb5bac78e0679f521c3f058c1eb9be0dd657dadd",
|
||||
"version": "0.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "JSONUtilities",
|
||||
"repositoryURL": "https://github.com/yonaskolb/JSONUtilities.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "128d2ffc22467f69569ef8ff971683e2393191a0",
|
||||
"version": "4.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "PathKit",
|
||||
"repositoryURL": "https://github.com/kylef/PathKit.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Rainbow",
|
||||
"repositoryURL": "https://github.com/onevcat/Rainbow.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "9c52c1952e9b2305d4507cf473392ac2d7c9b155",
|
||||
"version": "3.1.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Spectre",
|
||||
"repositoryURL": "https://github.com/kylef/Spectre.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
|
||||
"version": "0.9.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftCLI",
|
||||
"repositoryURL": "https://github.com/jakeheis/SwiftCLI.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c72c4564f8c0a24700a59824880536aca45a4cae",
|
||||
"version": "6.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftRoaring",
|
||||
"repositoryURL": "https://github.com/piotte13/SwiftRoaring",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "9104cf3f35e7a38c9fb633084c7adb63a9f27f8b",
|
||||
"version": "1.0.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Version",
|
||||
"repositoryURL": "https://github.com/mxcl/Version",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a94b48f36763c05629fc102837398505032dead9",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "XcodeProj",
|
||||
"repositoryURL": "https://github.com/tuist/XcodeProj.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "f32704e01d2752bdc17cde3963bee4256c1f4df4",
|
||||
"version": "7.8.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Yams",
|
||||
"repositoryURL": "https://github.com/jpsim/Yams.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c947a306d2e80ecb2c0859047b35c73b8e1ca27f",
|
||||
"version": "2.0.0"
|
||||
}
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "aexml",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tadija/AEXML.git",
|
||||
"state" : {
|
||||
"revision" : "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3",
|
||||
"version" : "4.6.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"identity" : "codability",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/yonaskolb/Codability",
|
||||
"state" : {
|
||||
"revision" : "eb5bac78e0679f521c3f058c1eb9be0dd657dadd",
|
||||
"version" : "0.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "graphviz",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/SwiftDocOrg/GraphViz.git",
|
||||
"state" : {
|
||||
"revision" : "70bebcf4597b9ce33e19816d6bbd4ba9b7bdf038",
|
||||
"version" : "0.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "jsonutilities",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/yonaskolb/JSONUtilities.git",
|
||||
"state" : {
|
||||
"revision" : "128d2ffc22467f69569ef8ff971683e2393191a0",
|
||||
"version" : "4.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "pathkit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kylef/PathKit.git",
|
||||
"state" : {
|
||||
"revision" : "3bfd2737b700b9a36565a8c94f4ad2b050a5e574",
|
||||
"version" : "1.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "prefire",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/BarredEwe/Prefire",
|
||||
"state" : {
|
||||
"revision" : "abb8dfa44391b4f47edb4937a4ba124e76270a87",
|
||||
"version" : "1.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "rainbow",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/onevcat/Rainbow.git",
|
||||
"state" : {
|
||||
"revision" : "626c3d4b6b55354b4af3aa309f998fae9b31a3d9",
|
||||
"version" : "3.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "spectre",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kylef/Spectre.git",
|
||||
"state" : {
|
||||
"revision" : "26cc5e9ae0947092c7139ef7ba612e34646086c7",
|
||||
"version" : "0.10.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftcli",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/jakeheis/SwiftCLI.git",
|
||||
"state" : {
|
||||
"revision" : "2e949055d9797c1a6bddcda0e58dada16cc8e970",
|
||||
"version" : "6.0.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftroaring",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/piotte13/SwiftRoaring",
|
||||
"state" : {
|
||||
"revision" : "9104cf3f35e7a38c9fb633084c7adb63a9f27f8b",
|
||||
"version" : "1.0.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "version",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mxcl/Version",
|
||||
"state" : {
|
||||
"revision" : "1fe824b80d89201652e7eca7c9252269a1d85e25",
|
||||
"version" : "2.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "xcodeproj",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tuist/XcodeProj.git",
|
||||
"state" : {
|
||||
"revision" : "6e60fb55271c80f83a186c9b1b4982fd991cfc0a",
|
||||
"version" : "8.13.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "yams",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/jpsim/Yams.git",
|
||||
"state" : {
|
||||
"revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
|
||||
"version" : "5.0.6"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ packages:
|
||||
XcodeGen:
|
||||
path: ../../.. #XcodeGen itself
|
||||
group: SPM
|
||||
FooFeature:
|
||||
path: FooFeature
|
||||
aggregateTargets:
|
||||
AggTarget:
|
||||
buildToolPlugins:
|
||||
- plugin: PrefirePlaybookPlugin
|
||||
package: Prefire
|
||||
targets:
|
||||
App:
|
||||
type: application
|
||||
@ -32,6 +39,10 @@ targets:
|
||||
embed: true
|
||||
- target: StaticLibrary
|
||||
- package: XcodeGen
|
||||
- package: FooFeature
|
||||
products:
|
||||
- FooDomain
|
||||
- FooUI
|
||||
Tests:
|
||||
type: bundle.unit-test
|
||||
platform: iOS
|
||||
@ -47,3 +58,7 @@ targets:
|
||||
- package: SwiftRoaring
|
||||
product: SwiftRoaringDynamic
|
||||
- package: XcodeGen
|
||||
- package: FooFeature
|
||||
products:
|
||||
- FooDomain
|
||||
- FooUI
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>TestApp</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,10 @@
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct MyAppApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
var body: some View {
|
||||
VStack {
|
||||
Image(systemName: "globe")
|
||||
.imageScale(.large)
|
||||
.foregroundColor(.accentColor)
|
||||
Text("Hello, world! on iOS")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
var body: some View {
|
||||
VStack {
|
||||
Image(systemName: "house")
|
||||
.imageScale(.large)
|
||||
.foregroundColor(.accentColor)
|
||||
Text("Hello, world! tvOS")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -0,0 +1 @@
|
||||
import Foundation
|
@ -41,6 +41,7 @@
|
||||
0F99AECCB4691803C791CDCE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2FC2A8A829CE71B1CF415FF7 /* Main.storyboard */; };
|
||||
15129B8D9ED000BDA1FEEC27 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A2F16890ECF2EE3FED72AE /* AppDelegate.swift */; };
|
||||
1551370B0ACAC632E15C853B /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF47010E7368583405AA50CB /* SwiftyJSON.framework */; };
|
||||
1B485D6584C3B47AC58831C6 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18722C61B05FFF4CC63D5755 /* ContentView.swift */; platformFilters = (tvos, ); };
|
||||
1BC891D89980D82738D963F3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74FBDFA5CB063F6001AD8ACD /* Main.storyboard */; };
|
||||
1E03FC7312293997599C6435 /* Empty.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 068EDF47F0B087F6A4052AC0 /* Empty.h */; };
|
||||
1E2A4D61E96521FF7123D7B0 /* XPC Service.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 22237B8EBD9E6BE8EBC8735F /* XPC Service.xpc */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@ -56,6 +57,7 @@
|
||||
21CA04F29CD0DEB0DD27B808 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B /* Result.framework */; };
|
||||
262891CCD5F74316610437FA /* Framework2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EF21DF245F66BEF5446AAEF /* Framework2.framework */; platformFilter = ios; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
265B6A05C0198FD2EB485173 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93C033648A37D95027845BD3 /* main.swift */; };
|
||||
2698ED273D0A5820B28CAD20 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D52EC9AA9FFD3B690C355068 /* LaunchScreen.storyboard */; platformFilters = (ios, ); };
|
||||
2730C6D0A35AED4ADD6EDF17 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0704B6CAFBB53E0EBB08F6B3 /* ViewController.swift */; settings = {COMPILER_FLAGS = "-Werror"; }; };
|
||||
28A96EBC76D53817AABDA91C /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8AF20308873AEEEC4D8C45D1 /* Settings.bundle */; };
|
||||
2A5356FCC03EE312F1738C61 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B82F603D981398F38D762E /* AppDelegate.swift */; };
|
||||
@ -70,6 +72,7 @@
|
||||
339578307B9266AB3D7722D9 /* File2.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC56891DA7446EAC8C2F27EB /* File2.swift */; };
|
||||
3535891EC86283BB5064E7E1 /* Headers in Headers */ = {isa = PBXBuildFile; fileRef = 2E1E747C7BC434ADB80CC269 /* Headers */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
3788E1382B38DF4ACE3D2BB1 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
3A3BA9F91994D8B472C71F04 /* Swinject in Frameworks */ = {isa = PBXBuildFile; platformFilters = (tvos, ); productRef = C7F9B7EDE85527EFEA85D46D /* Swinject */; };
|
||||
3BBCA6F76E5F212E9C55FB78 /* BundleX.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 45C12576F5AA694DD0CE2132 /* BundleX.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
3C5134EE524310ACF7B7CD6E /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAF6C55B555E3E1352645B6 /* ExtensionDelegate.swift */; };
|
||||
3DF22C477446669094AC7C8C /* ExternalTarget.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F6ADE654A3459AFDA2CC0CD3 /* ExternalTarget.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@ -148,6 +151,7 @@
|
||||
B18C121B0A4D43ED8149D8E2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 79325B44B19B83EC6CEDBCC5 /* LaunchScreen.storyboard */; };
|
||||
B20617116B230DED1F7AF5E5 /* libStaticLibrary_ObjC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B221F5A689AD7D3AD52F56B8 /* libStaticLibrary_ObjC.a */; };
|
||||
B2D43A31C184E34EF9CB743C /* Framework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8A9274BE42A03DC5DA1FAD04 /* Framework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
B358AB913543E62237FCC4E3 /* MyAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A4363D659A58DA835DE8BA /* MyAppApp.swift */; };
|
||||
B47F2629BFE5853767C8BB5E /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB2B6A77D39CD5602F2125F /* Contacts.framework */; };
|
||||
B49D3A51787E362DE4D0E78A /* SomeXPCService.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70A8E15C81E454DC950C59F0 /* SomeXPCService.xpc */; };
|
||||
B502EF8F7605CBD038298F23 /* CrossOverlayFramework.swiftcrossimport in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8DD7A61B07AD2F91BDECC255 /* CrossOverlayFramework.swiftcrossimport */; };
|
||||
@ -163,6 +167,7 @@
|
||||
C836F09B677937EFF69B1FCE /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C934C1F7A68CCD0AB6B38478 /* NotificationController.swift */; };
|
||||
C88598A49087A212990F4E8B /* ResourceFolder in Resources */ = {isa = PBXBuildFile; fileRef = 6B1603BA83AA0C7B94E45168 /* ResourceFolder */; };
|
||||
CAE18A2194B57C830A297F83 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6680EFE4E908CDBDCE405C8 /* main.swift */; };
|
||||
CAF8470C7F1BF207DBE6AEE3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEFDE76B5FEC833403C0869 /* ContentView.swift */; platformFilters = (ios, ); };
|
||||
CCA17097382757012B58C17C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1BC32A813B80A53962A1F365 /* Assets.xcassets */; };
|
||||
D058D241BDF5FB0C919BBECA /* CrossOverlayFramework.swiftcrossimport in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8DD7A61B07AD2F91BDECC255 /* CrossOverlayFramework.swiftcrossimport */; };
|
||||
D5458D67C3596943114C3205 /* Standalone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5BD97AF0F94A15A5B7DDB7 /* Standalone.swift */; };
|
||||
@ -738,8 +743,10 @@
|
||||
108BB29172D27BE3BD1E7F35 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
13EEAB58665D79C15184D9D0 /* App_iOS_UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = App_iOS_UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
148B7C933698BCC4F1DBA979 /* XPC_Service.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPC_Service.m; sourceTree = "<group>"; };
|
||||
15A4363D659A58DA835DE8BA /* MyAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppApp.swift; sourceTree = "<group>"; };
|
||||
16AA52945B70B1BF9E246350 /* FilterDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterDataProvider.swift; sourceTree = "<group>"; };
|
||||
16D662EE577E4CD6AFF39D66 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
|
||||
18722C61B05FFF4CC63D5755 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
187E665975BB5611AF0F27E1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
1BC32A813B80A53962A1F365 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
1D0C79A8C750EC0DE748C463 /* StaticLibrary_ObjC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StaticLibrary_ObjC.m; sourceTree = "<group>"; };
|
||||
@ -766,6 +773,7 @@
|
||||
3ED831531AA349CCC19B258B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
3EF21DF245F66BEF5446AAEF /* Framework2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3FC04772130400920D68A167 /* App_Clip_Tests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = App_Clip_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
407C3F0009FDCE5B1B7DC2A8 /* App_supportedDestinations.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App_supportedDestinations.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
40863AE6202CFCD0529D8438 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
41FC82ED1C4C3B7B3D7B2FB7 /* Framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
432E2C071A4B6B3757BEA13E /* Driver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Driver.cpp; sourceTree = "<group>"; };
|
||||
@ -830,6 +838,7 @@
|
||||
AAA49985DFFE797EE8416887 /* inputList.xcfilelist */ = {isa = PBXFileReference; lastKnownFileType = text.xcfilelist; path = inputList.xcfilelist; sourceTree = "<group>"; };
|
||||
AB055761199DF36DB0C629A6 /* Framework2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
AEBCA8CFF769189C0D52031E /* App_iOS.xctestplan */ = {isa = PBXFileReference; path = App_iOS.xctestplan; sourceTree = "<group>"; };
|
||||
AEEFDE76B5FEC833403C0869 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
B17B8D9C9B391332CD176A35 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LocalizedStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
B198242976C3395E31FE000A /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
|
||||
B1C33BB070583BE3B0EC0E68 /* App_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -855,6 +864,7 @@
|
||||
D21BB1B6FA5A025305B223BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
D296BB7355994040E197A1EE /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = "<group>"; };
|
||||
D51CC8BCCBD68A90E90A3207 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
D52EC9AA9FFD3B690C355068 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
D629E142AB87C681D4EC90F7 /* iMessageExtension.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = iMessageExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D6C89D80B5458D8929F5C127 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
D70BE0C05E5779A077793BE6 /* Model 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Model 2.xcdatamodel"; sourceTree = "<group>"; };
|
||||
@ -909,6 +919,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
36418B6CABA06BA9B206556E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3A3BA9F91994D8B472C71F04 /* Swinject in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
5EFF61D0A49AA8EABD72DF44 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -1102,6 +1120,7 @@
|
||||
0D039F2E62354C7C8E283BE6 /* App_iOS_UITests */,
|
||||
EE78B4FBD0137D1975C47D76 /* App_macOS */,
|
||||
6DE1C805DC13547F27FD86C6 /* App_macOS_Tests */,
|
||||
D27117FBA2920408002F0B4C /* App_supportedDestinations */,
|
||||
BAE6C12745737019DC9E98BF /* App_watchOS */,
|
||||
795B8D70B674C850B57DD39D /* App_watchOS Extension */,
|
||||
6DBE0EE90642BB3F6E58AD43 /* Configs */,
|
||||
@ -1194,6 +1213,23 @@
|
||||
path = UnderFileGroup;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
69C61547C081D04364A5DE42 /* Storyboards */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D52EC9AA9FFD3B690C355068 /* LaunchScreen.storyboard */,
|
||||
);
|
||||
name = Storyboards;
|
||||
path = Storyboards;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6A90AFD865B13D26DA108CAB /* tvOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18722C61B05FFF4CC63D5755 /* ContentView.swift */,
|
||||
);
|
||||
path = tvOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6BD8F0932CCAD4BBE752866B /* App_Clip_UITests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1266,6 +1302,17 @@
|
||||
path = "XPC Service";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
85FEBB7D2103B020423407A2 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E5249A284275B0CDF4E5DDA /* iOS */,
|
||||
6A90AFD865B13D26DA108CAB /* tvOS */,
|
||||
15A4363D659A58DA835DE8BA /* MyAppApp.swift */,
|
||||
);
|
||||
name = Sources;
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8CFD8AD4820FAB9265663F92 /* Tool */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1301,6 +1348,14 @@
|
||||
path = StandaloneFiles;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E5249A284275B0CDF4E5DDA /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AEEFDE76B5FEC833403C0869 /* ContentView.swift */,
|
||||
);
|
||||
path = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9EDF27BB8A57733E6639D36D /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1343,6 +1398,7 @@
|
||||
B1C33BB070583BE3B0EC0E68 /* App_iOS.app */,
|
||||
0B9D98D935F2C69A1F5BA539 /* App_macOS_Tests.xctest */,
|
||||
33F6DCDC37D2E66543D4965D /* App_macOS.app */,
|
||||
407C3F0009FDCE5B1B7DC2A8 /* App_supportedDestinations.app */,
|
||||
0D09D243DBCF9D32E239F1E8 /* App_watchOS Extension.appex */,
|
||||
A680BE9F68A255B0FB291AE6 /* App_watchOS.app */,
|
||||
84317819C92F78425870E483 /* BundleX.bundle */,
|
||||
@ -1432,6 +1488,15 @@
|
||||
path = StaticLibrary_Swift;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D27117FBA2920408002F0B4C /* App_supportedDestinations */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
85FEBB7D2103B020423407A2 /* Sources */,
|
||||
69C61547C081D04364A5DE42 /* Storyboards */,
|
||||
);
|
||||
path = App_supportedDestinations;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D557819B1EE5B42A0A3DD4D1 /* tvOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2205,6 +2270,26 @@
|
||||
productReference = 7D700FA699849D2F95216883 /* EntitledApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
C0570E2FB50D830D8D423396 /* App_supportedDestinations */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 5EC789CCE1928A4CDA00DD1E /* Build configuration list for PBXNativeTarget "App_supportedDestinations" */;
|
||||
buildPhases = (
|
||||
CF8BAE171BAAFB2E5DDB9C19 /* Sources */,
|
||||
97119CD9F01D9A9522EF3526 /* Resources */,
|
||||
36418B6CABA06BA9B206556E /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = App_supportedDestinations;
|
||||
packageProductDependencies = (
|
||||
C7F9B7EDE85527EFEA85D46D /* Swinject */,
|
||||
);
|
||||
productName = App_supportedDestinations;
|
||||
productReference = 407C3F0009FDCE5B1B7DC2A8 /* App_supportedDestinations.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
C7F90FD0FAAF232B3E015D38 /* CrossOverlayFramework_watchOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C483BD5456B09C276DE6EFC1 /* Build configuration list for PBXNativeTarget "CrossOverlayFramework_watchOS" */;
|
||||
@ -2415,6 +2500,7 @@
|
||||
F674B2CFC4738EEC49BAD0DA /* App_iOS_UITests */,
|
||||
020A320BB3736FCDE6CC4E70 /* App_macOS */,
|
||||
71E2BDAC4B8E8FC2BBF75C55 /* App_macOS_Tests */,
|
||||
C0570E2FB50D830D8D423396 /* App_supportedDestinations */,
|
||||
208179651927D1138D19B5AD /* App_watchOS */,
|
||||
307AE3FA155FFD09B74AE351 /* App_watchOS Extension */,
|
||||
DA40AB367B606CCE2FDD398D /* BundleX */,
|
||||
@ -2520,6 +2606,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97119CD9F01D9A9522EF3526 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2698ED273D0A5820B28CAD20 /* LaunchScreen.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AA12B5909FEE45016F469C78 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -3000,6 +3094,16 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CF8BAE171BAAFB2E5DDB9C19 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CAF8470C7F1BF207DBE6AEE3 /* ContentView.swift in Sources */,
|
||||
1B485D6584C3B47AC58831C6 /* ContentView.swift in Sources */,
|
||||
B358AB913543E62237FCC4E3 /* MyAppApp.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D1F422E9C4DD531AA88418C9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -4108,6 +4212,26 @@
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
24CFBB3ABB9E14E85035B892 /* Production Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Production Debug";
|
||||
};
|
||||
2569D399CA3C4828EF87AD78 /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -4815,6 +4939,26 @@
|
||||
};
|
||||
name = "Production Release";
|
||||
};
|
||||
4C11A3E7EA48B5FB556D4614 /* Staging Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
4D5DC2028DC046B8AF0B9B83 /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -5558,6 +5702,26 @@
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
75B3C83C754AA9C12ABF5E54 /* Staging Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Staging Release";
|
||||
};
|
||||
77B8B41EBA5D778EB3AF89DC /* Production Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -5757,6 +5921,26 @@
|
||||
};
|
||||
name = "Production Release";
|
||||
};
|
||||
7F3F6A813F8B126258780E8D /* Production Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Production Release";
|
||||
};
|
||||
7F86E00770E76CA3412A03BD /* Staging Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -6288,6 +6472,26 @@
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
98EE00BF46FAE62F16C25E9C /* Test Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Test Release";
|
||||
};
|
||||
9A891313A139893990989BDD /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -6469,6 +6673,26 @@
|
||||
};
|
||||
name = "Production Debug";
|
||||
};
|
||||
A4015127D0A01FE60CF5621B /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
INFOPLIST_FILE = App_supportedDestinations/Info.generated.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.test.TestApp;
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = "Test Debug";
|
||||
};
|
||||
A59DDFBFCF18C44A993CFB00 /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -8721,6 +8945,19 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "Production Debug";
|
||||
};
|
||||
5EC789CCE1928A4CDA00DD1E /* Build configuration list for PBXNativeTarget "App_supportedDestinations" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
24CFBB3ABB9E14E85035B892 /* Production Debug */,
|
||||
7F3F6A813F8B126258780E8D /* Production Release */,
|
||||
4C11A3E7EA48B5FB556D4614 /* Staging Debug */,
|
||||
75B3C83C754AA9C12ABF5E54 /* Staging Release */,
|
||||
A4015127D0A01FE60CF5621B /* Test Debug */,
|
||||
98EE00BF46FAE62F16C25E9C /* Test Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "Production Debug";
|
||||
};
|
||||
62C52A55CB8D3BD9A055FD14 /* Build configuration list for PBXNativeTarget "App_macOS_Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
@ -9125,6 +9362,11 @@
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
C7F9B7EDE85527EFEA85D46D /* Swinject */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */;
|
||||
productName = Swinject;
|
||||
};
|
||||
D7917D10F77DA9D69937D493 /* Swinject */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */;
|
||||
|
@ -239,6 +239,29 @@ targets:
|
||||
properties:
|
||||
com.apple.security.application-groups: group.com.app
|
||||
|
||||
App_supportedDestinations:
|
||||
type: application
|
||||
supportedDestinations: [iOS, tvOS]
|
||||
info:
|
||||
path: App_supportedDestinations/Info.generated.plist
|
||||
properties:
|
||||
CFBundleDisplayName: "TestApp"
|
||||
CFBundleVersion: "1.0.0"
|
||||
settings:
|
||||
base:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.test.TestApp
|
||||
sources:
|
||||
- path: App_supportedDestinations/Sources
|
||||
group: App_supportedDestinations
|
||||
inferDestinationFiltersByPath: true
|
||||
- path: App_supportedDestinations/Storyboards
|
||||
group: App_supportedDestinations
|
||||
destinationFilters: [iOS]
|
||||
dependencies:
|
||||
- package: Swinject
|
||||
product: Swinject
|
||||
destinationFilters: [tvOS]
|
||||
|
||||
App_watchOS:
|
||||
type: application.watchapp2
|
||||
platform: watchOS
|
||||
@ -489,7 +512,7 @@ schemes:
|
||||
enableGPUFrameCaptureMode: "disabled"
|
||||
enableGPUValidationMode: "disabled"
|
||||
storeKitConfiguration: "App_iOS/Configuration.storekit"
|
||||
macroExpansion: App_iOS
|
||||
macroExpansion: App_iOS
|
||||
test:
|
||||
gatherCoverageData: true
|
||||
targets:
|
||||
|
@ -73,12 +73,23 @@ class ProjectSpecTests: XCTestCase {
|
||||
describe {
|
||||
|
||||
$0.it("has correct build setting") {
|
||||
try expect(Platform.auto.deploymentTargetSetting) == ""
|
||||
try expect(Platform.iOS.deploymentTargetSetting) == "IPHONEOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.tvOS.deploymentTargetSetting) == "TVOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.watchOS.deploymentTargetSetting) == "WATCHOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.macOS.deploymentTargetSetting) == "MACOSX_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.visionOS.deploymentTargetSetting) == "XROS_DEPLOYMENT_TARGET"
|
||||
}
|
||||
|
||||
$0.it("has correct sdk root") {
|
||||
try expect(Platform.auto.sdkRoot) == "auto"
|
||||
try expect(Platform.iOS.sdkRoot) == "iphoneos"
|
||||
try expect(Platform.tvOS.sdkRoot) == "appletvos"
|
||||
try expect(Platform.watchOS.sdkRoot) == "watchos"
|
||||
try expect(Platform.macOS.sdkRoot) == "macosx"
|
||||
try expect(Platform.visionOS.sdkRoot) == "xros"
|
||||
}
|
||||
|
||||
$0.it("parses version correctly") {
|
||||
try expect(Version.parse("2").deploymentTarget) == "2.0"
|
||||
try expect(Version.parse("2.0").deploymentTarget) == "2.0"
|
||||
@ -156,8 +167,8 @@ class ProjectSpecTests: XCTestCase {
|
||||
Dependency(type: .framework, reference: "dependency2"),
|
||||
|
||||
// multiple package dependencies with different products should be allowed
|
||||
Dependency(type: .package(product: "one"), reference: "package1"),
|
||||
Dependency(type: .package(product: "two"), reference: "package1"),
|
||||
Dependency(type: .package(products: ["one"]), reference: "package1"),
|
||||
Dependency(type: .package(products: ["two"]), reference: "package1"),
|
||||
]
|
||||
),
|
||||
Target(
|
||||
@ -178,7 +189,59 @@ class ProjectSpecTests: XCTestCase {
|
||||
|
||||
try expectNoValidationError(project, .duplicateDependencies(target: "target1", dependencyReference: "package1"))
|
||||
}
|
||||
|
||||
|
||||
$0.it("unexpected supported destinations for watch app") {
|
||||
var project = baseProject
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .watchOS,
|
||||
supportedDestinations: [.macOS]
|
||||
)
|
||||
]
|
||||
try expectValidationError(project, .unexpectedTargetPlatformForSupportedDestinations(target: "target1", platform: .watchOS))
|
||||
}
|
||||
|
||||
$0.it("multiple definitions of mac platform in supported destinations") {
|
||||
var project = baseProject
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
supportedDestinations: [.macOS, .macCatalyst]
|
||||
)
|
||||
]
|
||||
try expectValidationError(project, .multipleMacPlatformsInSupportedDestinations(target: "target1"))
|
||||
}
|
||||
|
||||
$0.it("invalid target platform for macCatalyst supported destinations") {
|
||||
var project = baseProject
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .tvOS,
|
||||
supportedDestinations: [.tvOS, .macCatalyst]
|
||||
)
|
||||
]
|
||||
try expectValidationError(project, .invalidTargetPlatformForSupportedDestinations(target: "target1"))
|
||||
}
|
||||
|
||||
$0.it("missing target platform in supported destinations") {
|
||||
var project = baseProject
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
supportedDestinations: [.tvOS]
|
||||
)
|
||||
]
|
||||
try expectValidationError(project, .missingTargetPlatformInSupportedDestinations(target: "target1", platform: .iOS))
|
||||
}
|
||||
|
||||
$0.it("allows non-existent configurations") {
|
||||
var project = baseProject
|
||||
project.options = SpecOptions(disabledValidations: [.missingConfigs])
|
||||
@ -205,7 +268,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
sources: ["invalidSource"],
|
||||
dependencies: [
|
||||
Dependency(type: .target, reference: "invalidDependency"),
|
||||
Dependency(type: .package(product: nil), reference: "invalidPackage"),
|
||||
Dependency(type: .package(products: []), reference: "invalidPackage"),
|
||||
],
|
||||
preBuildScripts: [BuildScript(script: .path("invalidPreBuildScript"), name: "preBuildScript1")],
|
||||
postCompileScripts: [BuildScript(script: .path("invalidPostCompileScript"))],
|
||||
|
@ -38,7 +38,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
||||
]
|
||||
try expect(project.targets) == [
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "Yams")]),
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "Yams")]),
|
||||
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
||||
]
|
||||
}
|
||||
@ -54,7 +54,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
||||
]
|
||||
try expect(project.targets) == [
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "SwiftPM"), Dependency(type: .package(product: nil), reference: "Yams")]),
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "SwiftPM"), Dependency(type: .package(products: []), reference: "Yams")]),
|
||||
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
||||
]
|
||||
}
|
||||
@ -70,7 +70,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
||||
]
|
||||
try expect(project.targets) == [
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(product: nil), reference: "Yams")]),
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"], dependencies: [Dependency(type: .package(products: []), reference: "Yams")]),
|
||||
Target(name: "NewTarget", type: .application, platform: .iOS, sources: ["template", "target"]),
|
||||
]
|
||||
}
|
||||
@ -613,10 +613,66 @@ class SpecLoadingTests: XCTestCase {
|
||||
target_iOS.deploymentTarget = Version(major: 9, minor: 0, patch: 0)
|
||||
target_tvOS.deploymentTarget = Version(major: 10, minor: 0, patch: 0)
|
||||
|
||||
try expect(project.targets.count) == 2
|
||||
try expect(project.targets) == [target_iOS, target_tvOS]
|
||||
}
|
||||
|
||||
$0.it("parses no platform fallbacks to auto if we are using supported destinations") {
|
||||
let targetDictionary: [String: Any] = [
|
||||
"type": "framework",
|
||||
"supportedDestinations": ["iOS", "tvOS"]
|
||||
]
|
||||
|
||||
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
||||
let target = Target(name: "Framework", type: .framework, platform: .auto)
|
||||
|
||||
try expect(project.targets) == [target]
|
||||
}
|
||||
|
||||
$0.it("parses no platform fails if we are not using supported destinations") {
|
||||
let expectedError = SpecParsingError.unknownTargetPlatform("")
|
||||
|
||||
let projectDictionary: [String: Any] = [
|
||||
"name": "test",
|
||||
"targets": ["target1": [
|
||||
"type": "application"
|
||||
] as [String : Any]]
|
||||
]
|
||||
|
||||
try expectError(expectedError) {
|
||||
_ = try Project(jsonDictionary: projectDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("parses supported destinations with macCatalyst but not iOS, we add iOS") {
|
||||
let targetDictionary: [String: Any] = [
|
||||
"type": "framework",
|
||||
"supportedDestinations": ["macCatalyst"]
|
||||
]
|
||||
|
||||
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
||||
let target = Target(name: "Framework", type: .framework, platform: .auto)
|
||||
|
||||
try expect(project.targets) == [target]
|
||||
try expect(project.targets.first?.supportedDestinations) == [.macCatalyst, .iOS]
|
||||
}
|
||||
|
||||
$0.it("invalid target platform because platform is an array and supported destinations is in use") {
|
||||
let expectedError = SpecParsingError.invalidTargetPlatformAsArray
|
||||
|
||||
let projectDictionary: [String: Any] = [
|
||||
"name": "test",
|
||||
"targets": ["target1": [
|
||||
"type": "application",
|
||||
"platform": ["iOS", "tvOS"],
|
||||
"supportedDestinations": ["iOS", "tvOS"]
|
||||
] as [String : Any]]
|
||||
]
|
||||
|
||||
try expectError(expectedError) {
|
||||
_ = try Project(jsonDictionary: projectDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("parses target templates") {
|
||||
|
||||
let targetDictionary: [String: Any] = [
|
||||
|
@ -14,7 +14,7 @@ private let app = Target(
|
||||
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"),
|
||||
Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "MyDynamicFramework"),
|
||||
Dependency(type: .framework, reference: "MyExternalFramework"),
|
||||
Dependency(type: .package(product: "MyPackage"), reference: "MyPackage"),
|
||||
Dependency(type: .package(products: ["MyPackage"]), reference: "MyPackage"),
|
||||
Dependency(type: .sdk(root: "MySDK"), reference: "MySDK"),
|
||||
]
|
||||
)
|
||||
|
@ -357,7 +357,7 @@ class PBXProjGeneratorTests: XCTestCase {
|
||||
let dependency1 = Dependency(type: .target, reference: "TestAll", platformFilter: .all)
|
||||
let dependency2 = Dependency(type: .target, reference: "TestiOS", platformFilter: .iOS)
|
||||
let dependency3 = Dependency(type: .target, reference: "TestmacOS", platformFilter: .macOS)
|
||||
let dependency4 = Dependency(type: .package(product: "Swinject"), reference: "Swinject", platformFilter: .iOS)
|
||||
let dependency4 = Dependency(type: .package(products: ["Swinject"]), reference: "Swinject", platformFilter: .iOS)
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"], dependencies: [dependency1, dependency2, dependency3, dependency4])
|
||||
let swinjectPackage = SwiftPackage.remote(url: "https://github.com/Swinject/Swinject", versionRequirement: .exact("2.8.0"))
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target, target1, target2, target3], packages: ["Swinject": swinjectPackage])
|
||||
|
@ -335,7 +335,156 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(targetConfig.buildSettings["WATCHOS_DEPLOYMENT_TARGET"] as? String) == "2.0"
|
||||
try expect(targetConfig.buildSettings["TVOS_DEPLOYMENT_TARGET"]).beNil()
|
||||
}
|
||||
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, tvOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.tvOS, .iOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator appletvos appletvsimulator"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2,3"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, visionOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.visionOS, .iOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator xros xrsimulator"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2,7"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, tvOS, macOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.iOS, .tvOS, .macOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator appletvos appletvsimulator macosx"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2,3"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, tvOS, macCatalyst") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.iOS, .tvOS, .macCatalyst])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator appletvos appletvsimulator"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2,3"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == true
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, macOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.iOS, .macOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator macosx"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - tvOS, macOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.tvOS, .macOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "appletvos appletvsimulator macosx"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "3"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "App Icon & Top Shelf Image"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME"] as? String) == "LaunchImage"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - visionOS, macOS") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.visionOS, .macOS])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "xros xrsimulator macosx"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "7"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
}
|
||||
|
||||
$0.it("supportedPlaforms merges settings - iOS, macCatalyst") {
|
||||
let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.iOS, .macCatalyst])
|
||||
let project = Project(name: "", targets: [target])
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let targetConfig1 = try unwrap(pbxProject.nativeTargets.first?.buildConfigurationList?.buildConfigurations.first)
|
||||
|
||||
try expect(targetConfig1.buildSettings["SUPPORTED_PLATFORMS"] as? String) == "iphoneos iphonesimulator"
|
||||
try expect(targetConfig1.buildSettings["TARGETED_DEVICE_FAMILY"] as? String) == "1,2"
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MACCATALYST"] as? Bool) == true
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == false
|
||||
try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true
|
||||
|
||||
try expect(targetConfig1.buildSettings["LD_RUNPATH_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "@executable_path/Frameworks"]
|
||||
try expect(targetConfig1.buildSettings["SDKROOT"] as? String) == "auto"
|
||||
try expect(targetConfig1.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] as? String) == "AppIcon"
|
||||
try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer"
|
||||
}
|
||||
|
||||
$0.it("generates dependencies") {
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
|
||||
@ -555,12 +704,12 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
Dependency(type: .target, reference: resourceBundle.name),
|
||||
Dependency(type: .framework, reference: "FrameworkC.framework"),
|
||||
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageA"),
|
||||
Dependency(type: .package(product: "RxSwift"), reference: "RxSwift"),
|
||||
Dependency(type: .package(product: "RxCocoa"), reference: "RxSwift"),
|
||||
Dependency(type: .package(product: "RxRelay"), reference: "RxSwift"),
|
||||
Dependency(type: .package(products: ["RxSwift"]), reference: "RxSwift"),
|
||||
Dependency(type: .package(products: ["RxCocoa"]), reference: "RxSwift"),
|
||||
Dependency(type: .package(products: ["RxRelay"]), reference: "RxSwift"),
|
||||
|
||||
// Validate - Do not link package
|
||||
Dependency(type: .package(product: "KeychainAccess"), reference: "KeychainAccess", link: false),
|
||||
Dependency(type: .package(products: ["KeychainAccess"]), reference: "KeychainAccess", link: false),
|
||||
|
||||
// Statically linked, so don't embed into test
|
||||
Dependency(type: .target, reference: staticLibrary.name),
|
||||
@ -1066,7 +1215,108 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(app2OtherLinkerSettings.contains("-ObjC")) == false
|
||||
try expect(app3OtherLinkerSettings.contains("-ObjC")) == true
|
||||
}
|
||||
|
||||
|
||||
$0.it("filter sources with inferDestinationFiltersByPath") {
|
||||
let sourceFiles = TargetSource(path: "App_supportedDestinations/TestResources", inferDestinationFiltersByPath: true)
|
||||
|
||||
let target = Target(
|
||||
name: "test",
|
||||
type: .application,
|
||||
platform: .auto,
|
||||
sources: [sourceFiles],
|
||||
dependencies: []
|
||||
)
|
||||
|
||||
let project = Project(
|
||||
basePath: fixturePath + "TestProject",
|
||||
name: "test",
|
||||
targets: [target]
|
||||
)
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let buildFiles = pbxProject.buildFiles
|
||||
|
||||
try expect(buildFiles.count) == 8
|
||||
|
||||
for buildFile in buildFiles {
|
||||
let name = buildFile.file?.nameOrPath
|
||||
|
||||
if buildFile.platformFilters == [SupportedDestination.iOS.string] &&
|
||||
(name == "File_ios.swift" || name == "File_A.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.tvOS.string] &&
|
||||
(name == "File_tvOs.swift" || name == "File_B.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.macOS.string] &&
|
||||
(name == "File_macOS.swift" || name == "File_C.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.macCatalyst.string] &&
|
||||
(name == "File_MACCATALYST.swift" || name == "File_D.swift") {
|
||||
continue
|
||||
}
|
||||
|
||||
throw failure("Unexpected source file / destinationFilters")
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("filter sources with destinationFilters") {
|
||||
let sourceFile1 = TargetSource(path: "App_supportedDestinations/TestResources/iOs",
|
||||
destinationFilters: [.iOS])
|
||||
let sourceFile2 = TargetSource(path: "App_supportedDestinations/TestResources/TVOS",
|
||||
destinationFilters: [.tvOS])
|
||||
let sourceFile3 = TargetSource(path: "App_supportedDestinations/TestResources/macos",
|
||||
destinationFilters: [.macOS, .macCatalyst])
|
||||
let sourceFile4 = TargetSource(path: "App_supportedDestinations/TestResources/macCatalyst",
|
||||
destinationFilters: [.macOS, .macCatalyst])
|
||||
let sourceFile5 = TargetSource(path: "App_supportedDestinations/TestResources/File_ios.swift",
|
||||
destinationFilters: [.iOS])
|
||||
let sourceFile6 = TargetSource(path: "App_supportedDestinations/TestResources/File_tvOs.swift",
|
||||
destinationFilters: [.tvOS])
|
||||
let sourceFile7 = TargetSource(path: "App_supportedDestinations/TestResources/File_macOS.swift",
|
||||
destinationFilters: [.macOS, .macCatalyst])
|
||||
let sourceFile8 = TargetSource(path: "App_supportedDestinations/TestResources/File_MACCATALYST.swift",
|
||||
destinationFilters: [.macOS, .macCatalyst])
|
||||
|
||||
let target = Target(
|
||||
name: "test",
|
||||
type: .application,
|
||||
platform: .auto,
|
||||
sources: [sourceFile1, sourceFile2, sourceFile3, sourceFile4, sourceFile5, sourceFile6, sourceFile7, sourceFile8],
|
||||
dependencies: []
|
||||
)
|
||||
|
||||
let project = Project(
|
||||
basePath: fixturePath + "TestProject",
|
||||
name: "test",
|
||||
targets: [target]
|
||||
)
|
||||
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let buildFiles = pbxProject.buildFiles
|
||||
|
||||
try expect(buildFiles.count) == 8
|
||||
|
||||
for buildFile in buildFiles {
|
||||
let name = buildFile.file?.nameOrPath
|
||||
|
||||
if buildFile.platformFilters == [SupportedDestination.iOS.string] &&
|
||||
(name == "File_ios.swift" || name == "File_A.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.tvOS.string] &&
|
||||
(name == "File_tvOs.swift" || name == "File_B.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.macOS.string, SupportedDestination.macCatalyst.string] &&
|
||||
(name == "File_C.swift" || name == "File_D.swift") {
|
||||
continue
|
||||
} else if buildFile.platformFilters == [SupportedDestination.macOS.string, SupportedDestination.macCatalyst.string] &&
|
||||
(name == "File_macOS.swift" || name == "File_MACCATALYST.swift") {
|
||||
continue
|
||||
}
|
||||
|
||||
throw failure("Unexpected source file / destinationFilters")
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("copies Swift Objective-C Interface Header") {
|
||||
let swiftStaticLibraryWithHeader = Target(
|
||||
name: "swiftStaticLibraryWithHeader",
|
||||
@ -1263,8 +1513,8 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(product: "ProjectSpec"), reference: "XcodeGen"),
|
||||
Dependency(type: .package(product: nil), reference: "Codability"),
|
||||
Dependency(type: .package(products: ["ProjectSpec"]), reference: "XcodeGen"),
|
||||
Dependency(type: .package(products: []), reference: "Codability"),
|
||||
]
|
||||
)
|
||||
|
||||
@ -1300,7 +1550,7 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(product: nil), reference: "XcodeGen"),
|
||||
Dependency(type: .package(products: []), reference: "XcodeGen"),
|
||||
]
|
||||
)
|
||||
|
||||
@ -1324,14 +1574,13 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(file.product?.productName) == "XcodeGen"
|
||||
}
|
||||
|
||||
|
||||
$0.it("generates local swift packages with custom xcode path") {
|
||||
let app = Target(
|
||||
name: "MyApp",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(product: nil), reference: "XcodeGen"),
|
||||
Dependency(type: .package(products: []), reference: "XcodeGen"),
|
||||
]
|
||||
)
|
||||
|
||||
@ -1495,6 +1744,40 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
|
||||
try expect(NSDictionary(dictionary: expectedInfoPlist).isEqual(to: infoPlist)).beTrue()
|
||||
}
|
||||
|
||||
$0.it("generates local swift packages with multiple products") {
|
||||
let app = Target(
|
||||
name: "MyApp",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(products: ["FooDomain", "FooUI"]), reference: "FooFeature")
|
||||
]
|
||||
)
|
||||
|
||||
let project = Project(name: "test", targets: [app], packages: [
|
||||
"FooFeature": .local(path: "../FooFeature", group: nil)
|
||||
], options: .init(localPackagesGroup: "MyPackages"))
|
||||
|
||||
let pbxProject = try project.generatePbxProj(specValidate: false)
|
||||
let nativeTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.name == app.name }))
|
||||
let localPackageFile = try unwrap(pbxProject.fileReferences.first(where: { $0.path == "../FooFeature" }))
|
||||
try expect(localPackageFile.lastKnownFileType) == "folder"
|
||||
|
||||
let frameworkPhases = nativeTarget.buildPhases.compactMap { $0 as? PBXFrameworksBuildPhase }
|
||||
|
||||
guard let frameworkPhase = frameworkPhases.first else {
|
||||
return XCTFail("frameworkPhases should have more than one")
|
||||
}
|
||||
|
||||
guard let files = frameworkPhase.files, files.count == 2 else {
|
||||
return XCTFail("frameworkPhase should have exactly two files")
|
||||
}
|
||||
|
||||
let productNames = files.compactMap(\.product?.productName)
|
||||
try expect(productNames).contains { $0 == "FooDomain" }
|
||||
try expect(productNames).contains { $0 == "FooUI" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1612,7 +1895,197 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testGenerateXcodeProjectWithPlatformFilteredDependencies() throws {
|
||||
|
||||
describe("generateXcodeProject with destinationFilters") {
|
||||
|
||||
func generateProjectForApp(withDependencies: [Dependency], targets: [Target], packages: [String: SwiftPackage] = [:]) throws -> PBXProj {
|
||||
|
||||
let app = Target(
|
||||
name: "App",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: withDependencies
|
||||
)
|
||||
|
||||
let project = Project(
|
||||
name: "test",
|
||||
targets: targets + [app],
|
||||
packages: packages
|
||||
)
|
||||
|
||||
return try project.generatePbxProj()
|
||||
}
|
||||
|
||||
func expectLinkedDependecies(_ expectedLinkedFiles: [String: [String]], in project: PBXProj) throws {
|
||||
let buildPhases = project.buildPhases
|
||||
let frameworkPhases = project.frameworksBuildPhases.filter { buildPhases.contains($0) }
|
||||
|
||||
var linkedFiles: [String: [String]] = [:]
|
||||
|
||||
for link in frameworkPhases[0].files ?? [] {
|
||||
if let name = link.file?.nameOrPath ?? link.product?.productName {
|
||||
linkedFiles[name] = link.platformFilters
|
||||
}
|
||||
}
|
||||
|
||||
try expect(linkedFiles) == expectedLinkedFiles
|
||||
}
|
||||
|
||||
func expectCopiedBundles(_ expectedCopiedBundleFiles: [String: [String]], in project: PBXProj) throws {
|
||||
let buildPhases = project.buildPhases
|
||||
let copyBundlesPhase = project.copyFilesBuildPhases.filter { buildPhases.contains($0) }
|
||||
|
||||
var copiedFiles: [String: [String]] = [:]
|
||||
|
||||
for copy in copyBundlesPhase[0].files ?? [] {
|
||||
if let name = copy.file?.nameOrPath {
|
||||
copiedFiles[name] = copy.platformFilters
|
||||
}
|
||||
}
|
||||
|
||||
try expect(copiedFiles) == expectedCopiedBundleFiles
|
||||
}
|
||||
|
||||
$0.it("target dependencies") {
|
||||
|
||||
let frameworkA = Target(
|
||||
name: "frameworkA",
|
||||
type: .framework,
|
||||
platform: .iOS
|
||||
)
|
||||
|
||||
let frameworkB = Target(
|
||||
name: "frameworkB",
|
||||
type: .framework,
|
||||
platform: .iOS
|
||||
)
|
||||
|
||||
let expectedLinkedFiles = [
|
||||
"frameworkA.framework": [SupportedDestination.iOS.string],
|
||||
"frameworkB.framework": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .target, reference: frameworkA.name, destinationFilters: [.iOS]),
|
||||
Dependency(type: .target, reference: frameworkB.name, destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [frameworkA, frameworkB])
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectLinkedDependecies(expectedLinkedFiles, in: pbxProject)
|
||||
}
|
||||
|
||||
$0.it("framework dependencies") {
|
||||
|
||||
let expectedLinkedFiles = [
|
||||
"frameworkA.framework": [SupportedDestination.iOS.string],
|
||||
"frameworkB.framework": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .framework, reference: "frameworkA.framework", destinationFilters: [.iOS]),
|
||||
Dependency(type: .framework, reference: "frameworkB.framework", destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [])
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectLinkedDependecies(expectedLinkedFiles, in: pbxProject)
|
||||
}
|
||||
|
||||
$0.it("carthage dependencies") {
|
||||
|
||||
let expectedLinkedFiles = [
|
||||
"frameworkA.framework": [SupportedDestination.iOS.string],
|
||||
"frameworkB.framework": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "frameworkA.framework", destinationFilters: [.iOS]),
|
||||
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "frameworkB.framework", destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [])
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectLinkedDependecies(expectedLinkedFiles, in: pbxProject)
|
||||
}
|
||||
|
||||
$0.it("sdk dependencies") {
|
||||
|
||||
let expectedLinkedFiles = [
|
||||
"sdkA.framework": [SupportedDestination.iOS.string],
|
||||
"sdkB.framework": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .sdk(root: nil), reference: "sdkA.framework", destinationFilters: [.iOS]),
|
||||
Dependency(type: .sdk(root: nil), reference: "sdkB.framework", destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [])
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectLinkedDependecies(expectedLinkedFiles, in: pbxProject)
|
||||
}
|
||||
|
||||
$0.it("package dependencies") {
|
||||
|
||||
let packages: [String: SwiftPackage] = [
|
||||
"RxSwift": .remote(url: "https://github.com/ReactiveX/RxSwift", versionRequirement: .upToNextMajorVersion("5.1.1")),
|
||||
]
|
||||
|
||||
let expectedLinkedFiles = [
|
||||
"RxSwift": [SupportedDestination.iOS.string],
|
||||
"RxCocoa": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .package(products: ["RxSwift"]), reference: "RxSwift", destinationFilters: [.iOS]),
|
||||
Dependency(type: .package(products: ["RxCocoa"]), reference: "RxSwift", destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [], packages: packages)
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectLinkedDependecies(expectedLinkedFiles, in: pbxProject)
|
||||
}
|
||||
|
||||
$0.it("bundle dependencies") {
|
||||
|
||||
let expectedCopiedBundleFiles = [
|
||||
"bundleA.bundle": [SupportedDestination.iOS.string],
|
||||
"bundleB.bundle": [SupportedDestination.iOS.string, SupportedDestination.tvOS.string]
|
||||
]
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .bundle, reference: "bundleA.bundle", destinationFilters: [.iOS]),
|
||||
Dependency(type: .bundle, reference: "bundleB.bundle", destinationFilters: [.iOS, .tvOS]),
|
||||
]
|
||||
|
||||
// when
|
||||
let pbxProject = try generateProjectForApp(withDependencies: dependencies, targets: [])
|
||||
|
||||
// then ensure that everything is linked
|
||||
try expectCopiedBundles(expectedCopiedBundleFiles, in: pbxProject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testGenerateXcodeProjectWithCustomDependencyDestinations() throws {
|
||||
|
||||
describe("generateXcodeProject") {
|
||||
@ -2978,8 +3451,8 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .package(product: "RxSwift"), reference: "RxSwift", embed: true),
|
||||
Dependency(type: .package(product: "RxCocoa"), reference: "RxSwift", embed: false),
|
||||
Dependency(type: .package(products: ["RxSwift"]), reference: "RxSwift", embed: true),
|
||||
Dependency(type: .package(products: ["RxCocoa"]), reference: "RxSwift", embed: false),
|
||||
]
|
||||
|
||||
// when
|
||||
@ -2993,8 +3466,8 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
|
||||
// given
|
||||
let dependencies = [
|
||||
Dependency(type: .package(product: "RxSwift"), reference: "RxSwift", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)),
|
||||
Dependency(type: .package(product: "RxCocoa"), reference: "RxSwift", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)),
|
||||
Dependency(type: .package(products: ["RxSwift"]), reference: "RxSwift", embed: true, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)),
|
||||
Dependency(type: .package(products: ["RxCocoa"]), reference: "RxSwift", embed: false, copyPhase: BuildPhaseSpec.CopyFilesSettings(destination: .plugins, subpath: "test", phaseOrder: .postCompile)),
|
||||
]
|
||||
|
||||
// when
|
||||
|
@ -487,7 +487,7 @@ class SchemeGeneratorTests: XCTestCase {
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .package(product: nil), reference: "XcodeGen")
|
||||
Dependency(type: .package(products: []), reference: "XcodeGen")
|
||||
],
|
||||
scheme: targetScheme
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user