如何以编程方式加载 Swift 包配置?



我正在尝试使用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 PackageDescriptionn ^", diagnosticFile: nil)失败,因为我的Package.swift文件按预期以import PackageDescription开头。

也许这里发生了什么事。

您应该使用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({ $0.name }).joined(separator: ", ")
print("Products:", products)
let targets = manifest.targets.map({ $0.name }).joined(separator: ", ")
print("Targets:", targets)

// Package
let executables = loadedPackage.targets.filter({ $0.type == .executable }).map({ $0.name })
print("Executable targets:", executables)

// PackageGraph
let numberOfFiles = graph.reachableTargets.reduce(0, { $0 + $1.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

你让我很好奇,我快速环顾四周。

也许你会在 swift-package-manager 存储库中找到更多信息: https://github.com/apple/swift-package-manager

我会考虑这些选项,以实现:

  • 查找"包.swift",如果提供了文件夹,请使用其他路径。
  • 您需要将文件加载到解释器中,以便访问let package定义。
  • 实现的另一种解决方案可能是将 swift 文件解析为结构实例,存储库可能会告诉。

有了这些,您可以访问整个包定义, 我建议研究: https://github.com/apple/swift-package-manager/tree/main/Sources/PackageLoading

希望这能对某些方法有所帮助。

编辑:.
找到了一个更完整的示例来使用您已经引用的链接。

检查:https://github.com/apple/swift-package-manager/blob/main/Examples/package-info/Sources/package-info/main.swift

它解释了如何具有最小配置来加载包文件。

最新更新