diff --git a/Package.swift b/Package.swift index baef8b0a..ea2accbc 100644 --- a/Package.swift +++ b/Package.swift @@ -413,6 +413,13 @@ let package = Package( verb: "cmake-smoke-test", description: "Build Swift Build using CMake for validation purposes" )) + ), + .plugin( + name: "generate-windows-installer-component-groups", + capability: .command(intent: .custom( + verb: "generate-windows-installer-component-groups", + description: "Generate XML fragments for cli.wxs in swift-installer-scripts" + )) ) ], swiftLanguageModes: [.v5, .v6], diff --git a/Plugins/generate-windows-installer-component-groups/generate-windows-installer-component-groups.swift b/Plugins/generate-windows-installer-component-groups/generate-windows-installer-component-groups.swift new file mode 100644 index 00000000..398b9341 --- /dev/null +++ b/Plugins/generate-windows-installer-component-groups/generate-windows-installer-component-groups.swift @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import PackagePlugin +import Foundation + +@main +struct GenerateWindowsInstallerComponentGroups: CommandPlugin { + func performCommand(context: PluginContext, arguments: [String]) async throws { + var librariesComponent = #" \#n"# + var resourcesComponents = "" + var groupRefs = #" \#n"# + var directories = #" \#n"# + for target in context.package.targets.sorted(by: { $0.name < $1.name }).filter({ !["SWBTestSupport", "SwiftBuildTestSupport"].contains($0.name) }) { + guard let sourceModule = target.sourceModule, sourceModule.kind == .generic else { + continue + } + librariesComponent += #""" + + + + + """# + + let resources = sourceModule.sourceFiles.filter { resource in resource.type == .resource && ["xcspec", "xcbuildrule"].contains(resource.url.pathExtension) } + if !resources.isEmpty { + groupRefs += #" \#n"# + directories += #" \#n"# + resourcesComponents += #" \#n"# + for resource in resources { + resourcesComponents += #""" + + + + + """# + } + resourcesComponents += " \n" + } + } + librariesComponent += " \n" + directories += " \n" + + print("Component Groups") + print(String(repeating: "-", count: 80)) + print(librariesComponent) + print(resourcesComponents) + print("Group Refs") + print(String(repeating: "-", count: 80)) + print(groupRefs) + print("Directories") + print(String(repeating: "-", count: 80)) + print(directories) + } +}