Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
276 changes: 152 additions & 124 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,125 +14,153 @@
import Foundation
import PackageDescription

let package = Package(
name: "swift-format",
platforms: [
.macOS("12.0"),
.iOS("13.0"),
],
products: [
.executable(
name: "swift-format",
targets: ["swift-format"]
),
.library(
name: "SwiftFormat",
targets: ["SwiftFormat"]
),
.plugin(
name: "FormatPlugin",
targets: ["Format Source Code"]
),
.plugin(
name: "LintPlugin",
targets: ["Lint Source Code"]
),
],
dependencies: dependencies,
targets: [
.target(
name: "_SwiftFormatInstructionCounter",
exclude: ["CMakeLists.txt"]
),
var products: [Product] = [
.executable(
name: "swift-format",
targets: ["swift-format"]
),
.library(
name: "SwiftFormat",
targets: ["SwiftFormat"]
),
.plugin(
name: "FormatPlugin",
targets: ["Format Source Code"]
),
.plugin(
name: "LintPlugin",
targets: ["Lint Source Code"]
),
]

var targets: [Target] = [
.target(
name: "_SwiftFormatInstructionCounter",
exclude: ["CMakeLists.txt"]
),

.target(
name: "SwiftFormat",
dependencies: omittingExternalDependenciesIfNecessary([
.product(name: "Markdown", package: "swift-markdown"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
.product(name: "SwiftParserDiagnostics", package: "swift-syntax"),
.target(
name: "SwiftFormat",
dependencies: [
.product(name: "Markdown", package: "swift-markdown")
]
+ swiftSyntaxDependencies([
"SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax", "SwiftSyntaxBuilder",
]),
exclude: ["CMakeLists.txt"]
),
.target(
name: "_SwiftFormatTestSupport",
dependencies: omittingExternalDependenciesIfNecessary([
"SwiftFormat",
.product(name: "SwiftOperators", package: "swift-syntax"),
exclude: ["CMakeLists.txt"]
),
.target(
name: "_SwiftFormatTestSupport",
dependencies: [
"SwiftFormat"
]
+ swiftSyntaxDependencies([
"SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax", "SwiftSyntaxBuilder",
])
),
.plugin(
name: "Format Source Code",
capability: .command(
intent: .sourceCodeFormatting(),
permissions: [
.writeToPackageDirectory(reason: "This command formats the Swift source files")
]
),
dependencies: [
.target(name: "swift-format")
],
path: "Plugins/FormatPlugin"
),
.plugin(
name: "Lint Source Code",
capability: .command(
intent: .custom(
verb: "lint-source-code",
description: "Lint source code for a specified target."
)
),
dependencies: [
.target(name: "swift-format")
],
path: "Plugins/LintPlugin"
),
.executableTarget(
name: "generate-swift-format",
dependencies: [
"SwiftFormat"
),
.plugin(
name: "Format Source Code",
capability: .command(
intent: .sourceCodeFormatting(),
permissions: [
.writeToPackageDirectory(reason: "This command formats the Swift source files")
]
),
.executableTarget(
name: "swift-format",
dependencies: omittingExternalDependenciesIfNecessary([
"_SwiftFormatInstructionCounter",
"SwiftFormat",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
]),
exclude: ["CMakeLists.txt"],
linkerSettings: swiftformatLinkSettings
dependencies: [
.target(name: "swift-format")
],
path: "Plugins/FormatPlugin"
),
.plugin(
name: "Lint Source Code",
capability: .command(
intent: .custom(
verb: "lint-source-code",
description: "Lint source code for a specified target."
)
),
dependencies: [
.target(name: "swift-format")
],
path: "Plugins/LintPlugin"
),
.executableTarget(
name: "generate-swift-format",
dependencies: [
"SwiftFormat"
]
),
.executableTarget(
name: "swift-format",
dependencies: [
"_SwiftFormatInstructionCounter",
"SwiftFormat",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
] + swiftSyntaxDependencies(["SwiftParser", "SwiftSyntax"]),
exclude: ["CMakeLists.txt"],
linkerSettings: swiftformatLinkSettings
),

.testTarget(
name: "SwiftFormatPerformanceTests",
dependencies: omittingExternalDependenciesIfNecessary([
"SwiftFormat",
"_SwiftFormatTestSupport",
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
])
),
.testTarget(
name: "SwiftFormatTests",
dependencies: omittingExternalDependenciesIfNecessary([
"SwiftFormat",
"_SwiftFormatTestSupport",
.product(name: "Markdown", package: "swift-markdown"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
])
),
]
.testTarget(
name: "SwiftFormatPerformanceTests",
dependencies: [
"SwiftFormat",
"_SwiftFormatTestSupport",
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
] + swiftSyntaxDependencies(["SwiftParser", "SwiftSyntax"])
),
.testTarget(
name: "SwiftFormatTests",
dependencies: [
"SwiftFormat",
"_SwiftFormatTestSupport",
.product(name: "Markdown", package: "swift-markdown"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
]
),
]

if buildOnlyTests {
products = []
targets = targets.compactMap { target in
guard target.isTest || target.name == "_SwiftFormatTestSupport" else {
return nil
}
target.dependencies = target.dependencies.filter { dependency in
if case .byNameItem(name: "_SwiftFormatTestSupport", _) = dependency {
return true
}
return false
}
return target
}
}

let package = Package(
name: "swift-format",
platforms: [
.macOS("12.0"),
.iOS("13.0"),
],
products: products,
dependencies: dependencies,
targets: targets
)

func swiftSyntaxDependencies(_ names: [String]) -> [Target.Dependency] {
if buildDynamicSwiftSyntaxLibrary {
return [.product(name: "_SwiftSyntaxDynamic", package: "swift-syntax")]
} else {
return names.map { .product(name: $0, package: "swift-syntax") }
}
}

// MARK: - Parse build arguments

func hasEnvironmentVariable(_ name: String) -> Bool {
Expand All @@ -147,26 +175,26 @@ var installAction: Bool { hasEnvironmentVariable("SWIFTFORMAT_CI_INSTALL") }
/// remote dependency.
var useLocalDependencies: Bool { hasEnvironmentVariable("SWIFTCI_USE_LOCAL_DEPS") }

var omitExternalDependencies: Bool { hasEnvironmentVariable("SWIFTFORMAT_OMIT_EXTERNAL_DEPENDENCIES") }
/// Build only tests targets and test support modules.
///
/// This is used to test swift-format on Windows, where the modules required for the `swift-format` executable are
/// built using CMake. When using this setting, the caller is responsible for passing the required search paths to
/// the `swift test` invocation so that all pre-built modules can be found.
var buildOnlyTests: Bool { hasEnvironmentVariable("SWIFTFORMAT_BUILD_ONLY_TESTS") }

func omittingExternalDependenciesIfNecessary(
_ dependencies: [Target.Dependency]
) -> [Target.Dependency] {
guard omitExternalDependencies else {
return dependencies
}
return dependencies.filter { dependency in
if case .productItem(_, let package, _, _) = dependency {
return package == nil
}
return true
}
/// Whether swift-syntax is being built as a single dynamic library instead of as a separate library per module.
///
/// This means that the swift-syntax symbols don't need to be statically linked, which alles us to stay below the
/// maximum number of exported symbols on Windows, in turn allowing us to build sourcekit-lsp using SwiftPM on Windows
/// and run its tests.
var buildDynamicSwiftSyntaxLibrary: Bool {
hasEnvironmentVariable("SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY")
}

// MARK: - Dependencies

var dependencies: [Package.Dependency] {
if omitExternalDependencies {
if buildOnlyTests {
return []
} else if useLocalDependencies {
return [
Expand Down
Loading