Skip to content

Commit 1babba4

Browse files
committed
Support building only tests using SwiftPM
This allows us to build everything required for the executable using CMake and only the test targets using SwiftPM, enabling us to run tests on Windows from build.ps1 with minimal overhead.
1 parent 9df5622 commit 1babba4

File tree

1 file changed

+137
-126
lines changed

1 file changed

+137
-126
lines changed

Package.swift

Lines changed: 137 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -14,123 +14,143 @@
1414
import Foundation
1515
import PackageDescription
1616

17+
var products: [Product] = [
18+
.executable(
19+
name: "swift-format",
20+
targets: ["swift-format"]
21+
),
22+
.library(
23+
name: "SwiftFormat",
24+
targets: ["SwiftFormat"]
25+
),
26+
.plugin(
27+
name: "FormatPlugin",
28+
targets: ["Format Source Code"]
29+
),
30+
.plugin(
31+
name: "LintPlugin",
32+
targets: ["Lint Source Code"]
33+
),
34+
]
35+
36+
var targets: [Target] = [
37+
.target(
38+
name: "_SwiftFormatInstructionCounter",
39+
exclude: ["CMakeLists.txt"]
40+
),
41+
42+
.target(
43+
name: "SwiftFormat",
44+
dependencies: [
45+
.product(name: "Markdown", package: "swift-markdown"),
46+
.product(name: "SwiftSyntax", package: "swift-syntax"),
47+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
48+
.product(name: "SwiftOperators", package: "swift-syntax"),
49+
.product(name: "SwiftParser", package: "swift-syntax"),
50+
.product(name: "SwiftParserDiagnostics", package: "swift-syntax"),
51+
],
52+
exclude: ["CMakeLists.txt"]
53+
),
54+
.target(
55+
name: "_SwiftFormatTestSupport",
56+
dependencies: [
57+
"SwiftFormat",
58+
.product(name: "SwiftOperators", package: "swift-syntax"),
59+
]
60+
),
61+
.plugin(
62+
name: "Format Source Code",
63+
capability: .command(
64+
intent: .sourceCodeFormatting(),
65+
permissions: [
66+
.writeToPackageDirectory(reason: "This command formats the Swift source files")
67+
]
68+
),
69+
dependencies: [
70+
.target(name: "swift-format")
71+
],
72+
path: "Plugins/FormatPlugin"
73+
),
74+
.plugin(
75+
name: "Lint Source Code",
76+
capability: .command(
77+
intent: .custom(
78+
verb: "lint-source-code",
79+
description: "Lint source code for a specified target."
80+
)
81+
),
82+
dependencies: [
83+
.target(name: "swift-format")
84+
],
85+
path: "Plugins/LintPlugin"
86+
),
87+
.executableTarget(
88+
name: "generate-swift-format",
89+
dependencies: [
90+
"SwiftFormat"
91+
]
92+
),
93+
.executableTarget(
94+
name: "swift-format",
95+
dependencies: [
96+
"_SwiftFormatInstructionCounter",
97+
"SwiftFormat",
98+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
99+
.product(name: "SwiftSyntax", package: "swift-syntax"),
100+
.product(name: "SwiftParser", package: "swift-syntax"),
101+
],
102+
exclude: ["CMakeLists.txt"],
103+
linkerSettings: swiftformatLinkSettings
104+
),
105+
106+
.testTarget(
107+
name: "SwiftFormatPerformanceTests",
108+
dependencies: [
109+
"SwiftFormat",
110+
"_SwiftFormatTestSupport",
111+
.product(name: "SwiftSyntax", package: "swift-syntax"),
112+
.product(name: "SwiftParser", package: "swift-syntax"),
113+
]
114+
),
115+
.testTarget(
116+
name: "SwiftFormatTests",
117+
dependencies: [
118+
"SwiftFormat",
119+
"_SwiftFormatTestSupport",
120+
.product(name: "Markdown", package: "swift-markdown"),
121+
.product(name: "SwiftOperators", package: "swift-syntax"),
122+
.product(name: "SwiftParser", package: "swift-syntax"),
123+
.product(name: "SwiftSyntax", package: "swift-syntax"),
124+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
125+
]
126+
),
127+
]
128+
129+
if buildOnlyTests {
130+
products = []
131+
targets = targets.compactMap { target in
132+
guard target.isTest || target.name == "_SwiftFormatTestSupport" else {
133+
return nil
134+
}
135+
target.dependencies = target.dependencies.filter { dependency in
136+
if case .byNameItem(name: "_SwiftFormatTestSupport", _) = dependency {
137+
return true
138+
}
139+
return false
140+
}
141+
return target
142+
}
143+
}
144+
17145
let package = Package(
18146
name: "swift-format",
19147
platforms: [
20148
.macOS("12.0"),
21149
.iOS("13.0"),
22150
],
23-
products: [
24-
.executable(
25-
name: "swift-format",
26-
targets: ["swift-format"]
27-
),
28-
.library(
29-
name: "SwiftFormat",
30-
targets: ["SwiftFormat"]
31-
),
32-
.plugin(
33-
name: "FormatPlugin",
34-
targets: ["Format Source Code"]
35-
),
36-
.plugin(
37-
name: "LintPlugin",
38-
targets: ["Lint Source Code"]
39-
),
40-
],
151+
products: products,
41152
dependencies: dependencies,
42-
targets: [
43-
.target(
44-
name: "_SwiftFormatInstructionCounter",
45-
exclude: ["CMakeLists.txt"]
46-
),
47-
48-
.target(
49-
name: "SwiftFormat",
50-
dependencies: omittingExternalDependenciesIfNecessary([
51-
.product(name: "Markdown", package: "swift-markdown"),
52-
.product(name: "SwiftSyntax", package: "swift-syntax"),
53-
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
54-
.product(name: "SwiftOperators", package: "swift-syntax"),
55-
.product(name: "SwiftParser", package: "swift-syntax"),
56-
.product(name: "SwiftParserDiagnostics", package: "swift-syntax"),
57-
]),
58-
exclude: ["CMakeLists.txt"]
59-
),
60-
.target(
61-
name: "_SwiftFormatTestSupport",
62-
dependencies: omittingExternalDependenciesIfNecessary([
63-
"SwiftFormat",
64-
.product(name: "SwiftOperators", package: "swift-syntax"),
65-
])
66-
),
67-
.plugin(
68-
name: "Format Source Code",
69-
capability: .command(
70-
intent: .sourceCodeFormatting(),
71-
permissions: [
72-
.writeToPackageDirectory(reason: "This command formats the Swift source files")
73-
]
74-
),
75-
dependencies: [
76-
.target(name: "swift-format")
77-
],
78-
path: "Plugins/FormatPlugin"
79-
),
80-
.plugin(
81-
name: "Lint Source Code",
82-
capability: .command(
83-
intent: .custom(
84-
verb: "lint-source-code",
85-
description: "Lint source code for a specified target."
86-
)
87-
),
88-
dependencies: [
89-
.target(name: "swift-format")
90-
],
91-
path: "Plugins/LintPlugin"
92-
),
93-
.executableTarget(
94-
name: "generate-swift-format",
95-
dependencies: [
96-
"SwiftFormat"
97-
]
98-
),
99-
.executableTarget(
100-
name: "swift-format",
101-
dependencies: omittingExternalDependenciesIfNecessary([
102-
"_SwiftFormatInstructionCounter",
103-
"SwiftFormat",
104-
.product(name: "ArgumentParser", package: "swift-argument-parser"),
105-
.product(name: "SwiftSyntax", package: "swift-syntax"),
106-
.product(name: "SwiftParser", package: "swift-syntax"),
107-
]),
108-
exclude: ["CMakeLists.txt"],
109-
linkerSettings: swiftformatLinkSettings
110-
),
111-
112-
.testTarget(
113-
name: "SwiftFormatPerformanceTests",
114-
dependencies: omittingExternalDependenciesIfNecessary([
115-
"SwiftFormat",
116-
"_SwiftFormatTestSupport",
117-
.product(name: "SwiftSyntax", package: "swift-syntax"),
118-
.product(name: "SwiftParser", package: "swift-syntax"),
119-
])
120-
),
121-
.testTarget(
122-
name: "SwiftFormatTests",
123-
dependencies: omittingExternalDependenciesIfNecessary([
124-
"SwiftFormat",
125-
"_SwiftFormatTestSupport",
126-
.product(name: "Markdown", package: "swift-markdown"),
127-
.product(name: "SwiftOperators", package: "swift-syntax"),
128-
.product(name: "SwiftParser", package: "swift-syntax"),
129-
.product(name: "SwiftSyntax", package: "swift-syntax"),
130-
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
131-
])
132-
),
133-
]
153+
targets: targets
134154
)
135155

136156
// MARK: - Parse build arguments
@@ -147,26 +167,17 @@ var installAction: Bool { hasEnvironmentVariable("SWIFTFORMAT_CI_INSTALL") }
147167
/// remote dependency.
148168
var useLocalDependencies: Bool { hasEnvironmentVariable("SWIFTCI_USE_LOCAL_DEPS") }
149169

150-
var omitExternalDependencies: Bool { hasEnvironmentVariable("SWIFTFORMAT_OMIT_EXTERNAL_DEPENDENCIES") }
151-
152-
func omittingExternalDependenciesIfNecessary(
153-
_ dependencies: [Target.Dependency]
154-
) -> [Target.Dependency] {
155-
guard omitExternalDependencies else {
156-
return dependencies
157-
}
158-
return dependencies.filter { dependency in
159-
if case .productItem(_, let package, _, _) = dependency {
160-
return package == nil
161-
}
162-
return true
163-
}
164-
}
170+
/// Build only tests targets and test support modules.
171+
///
172+
/// This is used to test swift-format on Windows, where the modules required for the `swift-format` executable are
173+
/// built using CMake. When using this setting, the caller is responsible for passing the required search paths to
174+
/// the `swift test` invocation so that all pre-built modules can be found.
175+
var buildOnlyTests: Bool { hasEnvironmentVariable("SWIFTFORMAT_BUILD_ONLY_TESTS") }
165176

166177
// MARK: - Dependencies
167178

168179
var dependencies: [Package.Dependency] {
169-
if omitExternalDependencies {
180+
if buildOnlyTests {
170181
return []
171182
} else if useLocalDependencies {
172183
return [

0 commit comments

Comments
 (0)