SwiftPM 依赖图谱透视:`swift package show-dependencies` 命令全解析
2026/9/24 15:13:10 网站建设 项目流程
  • 开发工具
  • 构建工具

【免费下载链接】swift-package-manager

The Package Manager for the Swift Programming Language

项目地址:https://gitcode.com/gh_mirrors/sw/swift-package-manager
点击查看免费下载

swift package show-dependencies是 Swift Package Manager(SwiftPM)提供的依赖可视化命令,用于将解析完成(resolved)的依赖图以文本、JSON、Graphviz DOT 或扁平列表形式打印出来。在排查依赖版本冲突、确认产物来源、生成 CI 审计报告或绘制依赖关系图等场景中,它是开发者的第一视角工具。读完本文,你将掌握该命令的全部输出格式、每个命令行选项的含义与适用场景,并了解它在 SwiftPM 源码中的底层实现与对应测试。

命令概览:它做什么,从哪里来

命令的全量语法如下(选项按原样继承自 命令参考文档):

package show-dependencies [--package-path=<package-path>] [--cache-path=<cache-path>] [--config-path=<config-path>] [--security-path=<security-path>] [--scratch-path=<scratch-path>] [--swift-sdks-path=<swift-sdks-path>] [--toolset=<toolset>...] [--pkg-config-path=<pkg-config-path>...] [--enable-dependency-cache] [--disable-dependency-cache] [--enable-build-manifest-caching] [--disable-build-manifest-caching] [--manifest-cache=<manifest-cache>] [--enable-experimental-prebuilts] [--disable-experimental-prebuilts] [--verbose] [--very-verbose|vv] [--quiet] [--color-diagnostics] [--no-color-diagnostics] [--disable-sandbox] [--netrc] [--enable-netrc] [--disable-netrc] [--netrc-file=<netrc-file>] [--enable-keychain] [--disable-keychain] [--resolver-fingerprint-checking=<resolver-fingerprint-checking>] [--resolver-signing-entity-checking=<resolver-signing-entity-checking>] [--enable-signature-validation] [--disable-signature-validation] [--enable-prefetching] [--disable-prefetching] [--force-resolved-versions|disable-automatic-resolution|only-use-versions-from-resolved-file] [--skip-update] [--disable-scm-to-registry-transformation] [--use-registry-identity-for-scm] [--replace-scm-with-registry] [--default-registry-url=<default-registry-url>] [--configuration=<configuration>] [--=<Xcc>...] [--=<Xswiftc>...] [--=<Xlinker>...] [--=<Xcxx>...] [--triple=<triple>] [--sdk=<sdk>] [--toolchain=<toolchain>] [--swift-sdk=<swift-sdk>] [--sanitize=<sanitize>...] [--auto-index-store] [--enable-index-store] [--disable-index-store] [--enable-parseable-module-interfaces] [--jobs=<jobs>] [--use-integrated-swift-driver] [--explicit-target-dependency-import-check=<explicit-target-dependency-import-check>] [--build-system=<build-system>] [--=<debug-info-format>] [--enable-dead-strip] [--disable-dead-strip] [--disable-local-rpath] [--format=<format>] [--output-path=<output-path>] [--version] [--help]

在 SwiftPM 源码中,该子命令在 SwiftPackageCommand.swift 中通过ShowDependencies.self注册为swift package的顶级子命令,其核心实现位于 ShowDependencies.swift。命令声明为:

struct ShowDependencies: AsyncSwiftCommand { static let configuration = CommandConfiguration( abstract: "Print the resolved dependency graph.", ... ) }

其执行流程非常简单直接:run(_:)中先调用swiftCommandState.loadPackageGraph()加载并解析出完整的依赖图ModulesGraph,随后根据--format选择对应的 dumper,把以根包为起点的依赖树写入标准输出(或--output-path指定的文件)。这意味着它打印的永远是解析后的依赖状态——版本锁定结果来自Package.resolved与依赖解析器的共同作用。

四种输出格式:text / json / dot / flatlist

--format=<format>决定输出格式,默认值为text。格式类型定义于 ShowDependencies.swift 的ShowDependenciesMode枚举,支持textdotjsonflatlist四种取值(不区分大小写)。四种格式分别由 DependenciesSerializer.swift 中的四个 dumper 实现。

text(默认)

PlainTextDumper输出一棵使用 Unicode 树形连线符绘制的依赖树。根包自身以.表示,每个依赖节点格式为:

identity<packageLocation@version>(traits: ...)
  • identity:包的标识(identity);
  • packageLocation:包的来源地址(Git URL 或本地路径);
  • version:解析到的版本号,若没有版本信息(例如本地路径依赖)则显示unspecified
  • 括号中的traits部分仅在包启用了 traits 时才出现。

当根包没有任何外部依赖时,输出No external dependencies found。连线规则与常见树形工具一致:父节点非最后一个子节点用├──,最后一个子节点用└──与空格缩进。

json

JSONDumper输出一个嵌套的 JSON 对象(默认 pretty-print 缩进),每个包节点包含以下字段:

字段含义
identity包的标识字符串
name包的显示名(manifest 中的名称)
url包来源地址
version解析到的版本,无版本信息时为unspecified
path包在本地文件系统中的绝对路径
traits该包启用的 traits 数组
dependencies递归嵌套的依赖数组

JSON 输出从根包开始完整递归,非常适合程序化消费(例如在 CI 中做依赖审计)。

dot

DotDumper输出 Graphviz DOT 语言描述的依赖图,可以直接交给dot命令渲染成可视化图片。输出以digraph DependenciesGraph {开头、以}结尾,节点统一为shape = box。每个节点标签包含三行:identity、来源 URL、版本号;每条边以"rootURL" -> "dependencyURL"形式描述。dumper 内部用两个集合分别对已打印节点与已打印边做去重,保证同一依赖只出现一次。若没有外部依赖,同样输出No external dependencies found

flatlist

FlatListDumper输出最简形式:逐行打印依赖的 identity,并递归展开其直接依赖,不做树形连线、不显示版本与 URL。适合快速核对“当前到底引入了哪些包”。

把结果写入文件:--output-path

默认情况下,命令结果输出到 stdout。通过--output-path=<output-path>可以指定一个绝对或相对路径,将依赖图写入该文件;同时它还提供了短选项-o(见 ShowDependencies.swift 中@Option(name: [.long, .customShort("o")]的定义)。源码中输出流的选择逻辑为:

let stream: OutputByteStream = try outputPath.map { try LocalFileOutputByteStream($0) } ?? TSCBasic.stdoutStream

即传了--output-path就写入文件,否则写 stdout。这在 PackageCommandTests.swift 中有对应测试:show-dependencies --format json --output-path result.json会生成result.json文件,且内容中namerootdependencies[0].namedep

全量选项参考

原命令文档对每个选项都有说明,下面按功能域归类整理,并补充源码层面的佐证。

工作目录与路径定位

  • --package-path=<package-path>:指定要操作的包路径,默认是当前目录。该选项会先于任何其他操作改变工作目录,即先切到目标包目录再执行解析。
  • --cache-path=<cache-path>:指定共享缓存目录路径(依赖缓存、manifest 缓存等统一存放的位置)。
  • --config-path=<config-path>:指定共享配置目录路径。
  • --security-path=<security-path>:指定共享安全目录路径(存放指纹、签名等安全相关数据)。
  • --scratch-path=<scratch-path>:指定自定义的 scratch(构建中间产物)目录,默认是.build
  • --swift-sdks-path=<swift-sdks-path>:指向存放已安装 Swift SDK 的目录。

工具链与编译环境

  • --toolset=<toolset>:指定构建目标平台时要使用的 toolset JSON 文件。该选项可多次使用以指定多个 toolset,它们会按指定顺序合并为一个最终 toolset 用于当前构建。
  • --pkg-config-path=<pkg-config-path>:指定额外的 pkg-config.pc文件搜索路径,可多次使用以指定多个路径。
  • --triple=<triple>:目标平台三元组(如x86_64-unknown-linux-gnuarm64-apple-macosx)。原文档未给出详细描述,从其命名可以推断用于覆盖默认目标平台。
  • --sdk=<sdk>:指定使用的 SDK。原文档未给出描述,用途可从命名推断为覆盖系统默认 SDK。
  • --toolchain=<toolchain>:指定使用的工具链。原文档未给出描述,用途可从命名推断为覆盖系统默认工具链。
  • --swift-sdk=<swift-sdk>:过滤器,用于选择构建时使用的特定 Swift SDK。
  • --jobs=<jobs>:构建过程中并行派生的任务(job)数量。

依赖缓存与清单缓存

  • --enable-dependency-cache|--disable-dependency-cache:拉取依赖时是否使用共享缓存(对 fetch 依赖启用的开关)。
  • --enable-build-manifest-caching|--disable-build-manifest-caching:构建 manifest(构建清单)缓存的启用/禁用开关。原文档未给出描述,从其命名可推断为控制构建清单缓存行为。
  • --manifest-cache=<manifest-cache>:Package.swift 清单的缓存模式,合法取值为shared(共享缓存)、local(包的构建目录内)、none(禁用)。

宏预编译(实验性)

  • --enable-experimental-prebuilts|--disable-experimental-prebuilts:是否使用预编译的 swift-syntax 库来构建宏(macro)。这是实验性特性,对应--experimental-prebuilts实验标记。

沙箱与网络凭证

  • --disable-sandbox:执行子进程时禁用沙箱。
  • --netrc:即使在其他凭证存储更优先的情况下也使用 netrc 文件。
  • --enable-netrc|--disable-netrc:是否从 netrc 文件加载凭证。
  • --netrc-file=<netrc-file>:指定 netrc 文件路径。
  • --enable-keychain|--disable-keychain:是否在 macOS keychain 中搜索凭证。

安全校验(解析器级)

  • --resolver-fingerprint-checking=<resolver-fingerprint-checking>:原文档未给出详细描述;从其命名可以推断为控制依赖解析器对包指纹(fingerprint)的校验策略级别。
  • --resolver-signing-entity-checking=<resolver-signing-entity-checking>:原文档未给出详细描述;从其命名可以推断为控制依赖解析器对包签名实体(signing entity)的校验策略级别。
  • --enable-signature-validation|--disable-signature-validation:是否校验从注册表(registry)下载的已签名包 release 的签名。

依赖解析与版本锁定

  • --enable-prefetching|--disable-prefetching:原文档未给出描述;从其命名可推断为控制依赖解析过程中是否启用预取(prefetch)以加速解析。
  • --force-resolved-versions|--disable-automatic-resolution|--only-use-versions-from-resolved-file只使用Package.resolved文件中的版本,若该文件已过期(out-of-date)则解析失败。这是--disable-automatic-resolution的增强别名,常用于保证可复现构建。
  • --skip-update:解析过程中跳过从远端更新依赖。
  • --disable-scm-to-registry-transformation:禁用源码控制(SCM)到注册表(registry)的转换。
  • --use-registry-identity-for-scm:在注册表中查找源码控制依赖,尽可能使用其注册表身份,帮助跨两种来源去重。
  • --replace-scm-with-registry:在注册表中查找源码控制依赖,尽可能用注册表而非源码控制来获取它们。
  • --default-registry-url=<default-registry-url>:使用默认注册表 URL,替代registries.json配置文件。

构建参数透传

  • --configuration=<configuration>:以指定的构建配置(如debugrelease)构建。
  • --=<Xcc>...:把标志透传给所有 C 编译器调用。
  • --=<Xswiftc>...:把标志透传给所有 Swift 编译器调用。
  • --=<Xlinker>...:把标志透传给所有链接器调用。
  • --=<Xcxx>...:把标志透传给所有 C++ 编译器调用。
  • --=<debug-info-format>:指定使用的调试信息格式(Debug Information Format)。
  • --sanitize=<sanitize>:开启针对错误行为的运行时检查,可选值为addressthreadundefinedscudo
  • --enable-dead-strip|--disable-dead-strip:启用/禁用链接器的死代码剥离(dead code stripping)。
  • --disable-local-rpath:禁用默认添加$ORIGIN/@loader_path到 rpath。
  • --auto-index-store|--enable-index-store|--disable-index-store:启用/禁用边构建边索引(indexing-while-building)功能。
  • --enable-parseable-module-interfaces:原文档未给出描述;从 SwiftPM 的既有能力可推断为生成可解析的模块接口(.swiftinterface)以支持跨模块增量编译。
  • --use-integrated-swift-driver:原文档未给出描述;从 SwiftPM 的既有能力可推断为使用集成的 Swift 驱动(integrated driver)而非外部 driver。
  • --explicit-target-dependency-import-check=<...>:指示本次构建检查目标是否只 import 其显式声明的依赖。
  • --build-system=<build-system>:原文档未给出描述;从 SwiftPM 的BuildSystemProvider可推断为选择构建系统(native / swiftbuild / xcode)。

日志与输出控制

  • --verbose:提高输出冗余度,包含信息级(informational)输出。
  • --very-verbose(别名--vv):提高输出冗余度到调试级(debug)输出。
  • --quiet:降低输出冗余度,仅包含错误级输出。
  • --color-diagnostics|--no-color-diagnostics:启用/禁用打印到 TTY 时的彩色诊断。默认行为:连接 TTY 时启用彩色诊断,否则禁用。
  • --format=<format>:设置输出格式(见上文四种格式)。
  • --output-path=<output-path>:将依赖图输出到指定绝对/相对路径(短选项-o)。
  • --version:显示版本。
  • --help:显示帮助信息。

源码级实现原理

输出管线

从源码看,命令实现非常简洁,输出职责完全委托给 dumper:

switch mode { case .text: dumper = PlainTextDumper() case .dot: dumper = DotDumper() case .json: dumper = JSONDumper() case .flatlist: dumper = FlatListDumper() } dumper.dump(graph: graph, dependenciesOf: rootPackage, on: stream) stream.flush()

其中rootPackagegraph.rootPackages的第一个元素,graph.directDependencies(for:)用于逐层获取每个包的直接依赖,ModulesGraph则承载了完整的解析结果。

JSON 字段的来源

JSON dumper 中每个字段都能回溯到ResolvedPackage的 manifest 信息:identity来自package.identityurl来自package.manifest.packageLocationversion来自package.manifest.version(无版本时为unspecified),path来自package.path.pathStringtraits来自package.enabledTraits。这意味着 JSON 输出同时包含了逻辑身份(identity)、来源(url)与物理位置(path)三重信息,便于审计脚本对齐其他工具(如swift package dump-package)的输出。

与 traits 的联动

从 PackageCommandTests.swift 的测试可以看出,show-dependencies 的输出会反映 traits 的启用状态:

  • 启用 traits 时,text 输出中会出现(traits: Package3Trait3)这样的后缀;JSON 的traits数组会列出所有启用的 trait;
  • 使用--disable-default-traits且没有其他 trait 被启用时,输出变为No external dependencies found
  • 使用--traits EnablePackage2Dep切换 trait 后,输出中的依赖集合随之改变;
  • 使用--enable-all-traits时,所有 trait 及其依赖全部出现。

这说明 show-dependencies 展示的是当前 trait 配置生效后的解析结果,是验证 traits 与条件依赖(.when(platforms:...)/.when(usage:...))是否正确生效的快捷方式。

与依赖解析状态的强绑定

命令内部通过loadPackageGraph()走完整解析流程,因此它的输出必然受解析器行为影响:--force-resolved-versions(仅用Package.resolved中的版本且过期即失败)、--skip-update(不从远端更新)、--use-registry-identity-for-scm/--replace-scm-with-registry(SCM 与注册表身份互操作)等解析器级选项都会反映到最终的图中。

测试验证:命令行为有据可查

除上文提到的 traits 测试与--output-path测试外,PackageCommandTests.swift 中的showDependencies测试使用Fixtures/DependencyResolution/External/Complex夹具(示例包)验证:

  • text 输出中包含FisherYates@1.2.3(即 identity + 版本号格式正确);
  • JSON 输出可被解析为字典,顶层nameDealerpath解析后与包根目录一致。

在 DependencyResolutionTests.swift 中还有使用show-dependencies -v的端到端依赖解析验证。这些测试共同锁定了命令的输出契约,也意味着你在本地可以用同一夹具复现:

# 在仓库内查看示例包的依赖 swift package --package-path Fixtures/DependencyResolution/External/Complex/app show-dependencies

实战要点小结

  1. 快速排障swift package show-dependencies直接展示“实际生效”的依赖版本,排查版本漂移时优先使用它而不是读Package.resolved
  2. 可复现构建:配合--force-resolved-versions(等价于--only-use-versions-from-resolved-file)可强制只使用已锁定版本,Package.resolved过期即报错。
  3. CI 审计:用--format json --output-path dep.json将依赖快照落盘,供后续 diff 或合规扫描。
  4. 可视化--format dot生成的 DOT 文件可直接交给 Graphviz 渲染依赖关系图。
  5. 离线/受限网络:按需组合--skip-update--disable-sandbox--netrc-file--default-registry-url等选项,控制依赖获取来源与凭证方式。
  6. 注意输出对象的粒度:show-dependencies 输出的是包级依赖图,而非 target/module 级依赖;查看模块级依赖关系需借助其他工具(如swift build --show-dependencies或 PIF 相关命令)。
  • 开发工具
  • 构建工具

【免费下载链接】swift-package-manager

The Package Manager for the Swift Programming Language

项目地址:https://gitcode.com/gh_mirrors/sw/swift-package-manager
点击查看免费下载
上一篇:地理热力图终极指南:5分钟快速掌握空间数据可视化
下一篇:Pythia-160M-deduped-openmind部署实战:生产环境最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询