-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPackage+Extensions.swift
More file actions
85 lines (80 loc) · 3.36 KB
/
Package+Extensions.swift
File metadata and controls
85 lines (80 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// Package+Extensions.swift
// Copyright (c) 2024 BrightDigit.
// Licensed under MIT License
//
import PackageDescription
extension Package {
/// Initializes a new `Package` instance with the provided properties.
/// - Parameters:
/// - name: The name of the package. If `nil`, the name will be inferred from the file path.
/// - entries: A closure that returns an array of `Product` instances.
/// - packageDependencies: A closure that returns an array of `PackageDependency` instances.
/// - testTargets: A closure that returns an array of `TestTarget` instances.
/// - swiftSettings: A closure that returns an array of `SwiftSetting` instances.
public convenience init(
name: String? = nil,
@ProductsBuilder entries: @escaping () -> [any Product],
@PackageDependencyBuilder dependencies packageDependencies: @escaping () -> [any PackageDependency] = { [any PackageDependency]() },
@TestTargetBuilder testTargets: @escaping () -> any TestTargets = { [any TestTarget]() },
@SwiftSettingsBuilder swiftSettings: @escaping () -> [SwiftSetting] = { [SwiftSetting]() }
) {
let packageName: String
if let name {
packageName = name
} else {
var pathComponents = #filePath.split(separator: "/")
pathComponents.removeLast()
// swift-format-ignore: NeverForceUnwrap
packageName = String(pathComponents.last!)
}
let allTestTargets = testTargets()
let entries = entries()
let products = entries.map(_PackageDescription_Product.entry)
var targets = entries.flatMap(\.productTargets)
let allTargetsDependencies = targets.flatMap { $0.allDependencies() }
let allTestTargetsDependencies = allTestTargets.flatMap { $0.allDependencies() }
let dependencies = allTargetsDependencies + allTestTargetsDependencies
let targetDependencies = dependencies.compactMap { $0 as? Target }
let packageTargetDependencies = dependencies.compactMap { $0 as? TargetDependency }
let allPackageDependencies = packageTargetDependencies.map(\.package) + packageDependencies()
targets += targetDependencies
targets += allTestTargets.map { $0 as Target }
let packgeTargets = Dictionary(
grouping: targets,
by: { $0.name }
)
.values
.compactMap(\.first)
.map { _PackageDescription_Target.entry($0, swiftSettings: swiftSettings()) }
let packageDeps = Dictionary(
grouping: allPackageDependencies,
by: { $0.packageName }
)
.values.compactMap(\.first).map(\.dependency)
self.init(
name: packageName,
products: products,
dependencies: packageDeps,
targets: packgeTargets
)
}
}
extension Package {
/// Adds supported platforms to the package.
/// - Parameter supportedPlatforms: A closure that returns an array of `SupportedPlatforms` instances.
/// - Returns: The modified `Package` instance.
public func supportedPlatforms(
@SupportedPlatformBuilder supportedPlatforms: @escaping () -> any SupportedPlatforms
) -> Package {
platforms = .init(supportedPlatforms())
return self
}
/// Sets the default localization for the package.
/// - Parameter defaultLocalization: The default localization for the package.
/// - Returns: The modified `Package` instance.
public func defaultLocalization(_ defaultLocalization: LanguageTag) -> Package {
self.defaultLocalization = defaultLocalization
return self
}
}