如何以编程方式加载 Swift 包配置?
How can I load a Swift package configuration programmatically?
我正在尝试使用 SwiftPM
来分析本地 Package.swift
文件。我找不到任何关于如何这样做的文档。理想情况下,我会调用
import PackageDescription
let package = try Package(at: "pathToFile/Package.swift")
print(package.dependencies) ...
我试过使用
let package = try PackageBuilder.loadPackage(
packagePath: .init(absolutePath),
swiftCompiler: .init("/usr/bin/swift"),
swiftCompilerFlags: [],
diagnostics: .init())
但这失败了 error: no such module \'PackageDescription\'\nimport PackageDescription\n ^", diagnosticFile: nil)
,因为我的 Package.swift
文件按预期以 import PackageDescription
开头。
也许有什么事发生 here。
你让我很好奇,我快速浏览了一下。
也许您会在 swift-package-manager 存储库中找到更多信息:
https://github.com/apple/swift-package-manager
我会考虑这些选项,以便实施:
- 寻找 'Package.swift',如果提供了文件夹,请使用其他路径。
- 您需要将文件加载到解释器中,以便访问
let package
定义。
- 实施的另一个解决方案可能是将 swift 文件解析为结构实例,存储库可能会告诉。
通过这些你可以访问整个包定义,
我建议调查:
https://github.com/apple/swift-package-manager/tree/main/Sources/PackageLoading
希望这对某些方面有所帮助。
编辑:.
找到一个更完整的示例来使用您已经引用的链接。
它解释了如何使用最小配置来加载包文件。
您应该使用 swiftCompiler
参数提供编译器的完整路径以避免您的问题,例如:
import PackageModel
import PackageLoading
import PackageGraph
import Workspace
let swiftCompiler: AbsolutePath = {
let string: String
#if os(macOS)
string = try! Process.checkNonZeroExit(args: "xcrun", "--sdk", "macosx", "-f", "swiftc").spm_chomp()
#else
string = try! Process.checkNonZeroExit(args: "which", "swiftc").spm_chomp()
#endif
return AbsolutePath(string)
}()
let package = AbsolutePath(".../swift-package-manager")
let diagnostics = DiagnosticsEngine()
do {
let manifest = try ManifestLoader.loadManifest(packagePath: package, swiftCompiler: swiftCompiler, packageKind: .local)
let loadedPackage = try PackageBuilder.loadPackage(packagePath: package, swiftCompiler: swiftCompiler, diagnostics: diagnostics)
let graph = try Workspace.loadGraph(packagePath: package, swiftCompiler: swiftCompiler, diagnostics: diagnostics)
// Manifest
let products = manifest.products.map({ [=10=].name }).joined(separator: ", ")
print("Products:", products)
let targets = manifest.targets.map({ [=10=].name }).joined(separator: ", ")
print("Targets:", targets)
// Package
let executables = loadedPackage.targets.filter({ [=10=].type == .executable }).map({ [=10=].name })
print("Executable targets:", executables)
// PackageGraph
let numberOfFiles = graph.reachableTargets.reduce(0, { [=10=] + .sources.paths.count })
print("Total number of source files (including dependencies):", numberOfFiles)
}
catch {
print(error)
}
输出:
Products: SwiftPM, SwiftPM-auto, PackageDescription
Targets: PackageDescription, LLBuildManifest, SourceControl, SPMLLBuild, PackageModel, PackageLoading, PackageGraph, Build, Xcodeproj, Workspace, Commands, swift-package, swift-build, swift-test, swift-run, swiftpm-xctest-helper, SPMTestSupport, BuildTests, CommandsTests, WorkspaceTests, FunctionalTests, FunctionalPerformanceTests, PackageDescription4Tests, PackageLoadingTests, PackageLoadingPerformanceTests, PackageModelTests, PackageGraphTests, PackageGraphPerformanceTests, SourceControlTests, XcodeprojTests
Executable targets: ["swift-run", "swift-build", "swift-package", "swiftpm-xctest-helper", "swift-test"]
Total number of source files (including dependencies): 344
我正在尝试使用 SwiftPM
来分析本地 Package.swift
文件。我找不到任何关于如何这样做的文档。理想情况下,我会调用
import PackageDescription
let package = try Package(at: "pathToFile/Package.swift")
print(package.dependencies) ...
我试过使用
let package = try PackageBuilder.loadPackage(
packagePath: .init(absolutePath),
swiftCompiler: .init("/usr/bin/swift"),
swiftCompilerFlags: [],
diagnostics: .init())
但这失败了 error: no such module \'PackageDescription\'\nimport PackageDescription\n ^", diagnosticFile: nil)
,因为我的 Package.swift
文件按预期以 import PackageDescription
开头。
也许有什么事发生 here。
你让我很好奇,我快速浏览了一下。
也许您会在 swift-package-manager 存储库中找到更多信息: https://github.com/apple/swift-package-manager
我会考虑这些选项,以便实施:
- 寻找 'Package.swift',如果提供了文件夹,请使用其他路径。
- 您需要将文件加载到解释器中,以便访问
let package
定义。 - 实施的另一个解决方案可能是将 swift 文件解析为结构实例,存储库可能会告诉。
通过这些你可以访问整个包定义, 我建议调查: https://github.com/apple/swift-package-manager/tree/main/Sources/PackageLoading
希望这对某些方面有所帮助。
编辑:.
找到一个更完整的示例来使用您已经引用的链接。
它解释了如何使用最小配置来加载包文件。
您应该使用 swiftCompiler
参数提供编译器的完整路径以避免您的问题,例如:
import PackageModel
import PackageLoading
import PackageGraph
import Workspace
let swiftCompiler: AbsolutePath = {
let string: String
#if os(macOS)
string = try! Process.checkNonZeroExit(args: "xcrun", "--sdk", "macosx", "-f", "swiftc").spm_chomp()
#else
string = try! Process.checkNonZeroExit(args: "which", "swiftc").spm_chomp()
#endif
return AbsolutePath(string)
}()
let package = AbsolutePath(".../swift-package-manager")
let diagnostics = DiagnosticsEngine()
do {
let manifest = try ManifestLoader.loadManifest(packagePath: package, swiftCompiler: swiftCompiler, packageKind: .local)
let loadedPackage = try PackageBuilder.loadPackage(packagePath: package, swiftCompiler: swiftCompiler, diagnostics: diagnostics)
let graph = try Workspace.loadGraph(packagePath: package, swiftCompiler: swiftCompiler, diagnostics: diagnostics)
// Manifest
let products = manifest.products.map({ [=10=].name }).joined(separator: ", ")
print("Products:", products)
let targets = manifest.targets.map({ [=10=].name }).joined(separator: ", ")
print("Targets:", targets)
// Package
let executables = loadedPackage.targets.filter({ [=10=].type == .executable }).map({ [=10=].name })
print("Executable targets:", executables)
// PackageGraph
let numberOfFiles = graph.reachableTargets.reduce(0, { [=10=] + .sources.paths.count })
print("Total number of source files (including dependencies):", numberOfFiles)
}
catch {
print(error)
}
输出:
Products: SwiftPM, SwiftPM-auto, PackageDescription
Targets: PackageDescription, LLBuildManifest, SourceControl, SPMLLBuild, PackageModel, PackageLoading, PackageGraph, Build, Xcodeproj, Workspace, Commands, swift-package, swift-build, swift-test, swift-run, swiftpm-xctest-helper, SPMTestSupport, BuildTests, CommandsTests, WorkspaceTests, FunctionalTests, FunctionalPerformanceTests, PackageDescription4Tests, PackageLoadingTests, PackageLoadingPerformanceTests, PackageModelTests, PackageGraphTests, PackageGraphPerformanceTests, SourceControlTests, XcodeprojTests
Executable targets: ["swift-run", "swift-build", "swift-package", "swiftpm-xctest-helper", "swift-test"]
Total number of source files (including dependencies): 344