- 开发工具
- 构建工具
【免费下载链接】swift-package-manager
The Package Manager for the Swift Programming Language
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枚举,支持text、dot、json、flatlist四种取值(不区分大小写)。四种格式分别由 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文件,且内容中name为root、dependencies[0].name为dep。
全量选项参考
原命令文档对每个选项都有说明,下面按功能域归类整理,并补充源码层面的佐证。
工作目录与路径定位
--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-gnu、arm64-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>:以指定的构建配置(如debug、release)构建。--=<Xcc>...:把标志透传给所有 C 编译器调用。--=<Xswiftc>...:把标志透传给所有 Swift 编译器调用。--=<Xlinker>...:把标志透传给所有链接器调用。--=<Xcxx>...:把标志透传给所有 C++ 编译器调用。--=<debug-info-format>:指定使用的调试信息格式(Debug Information Format)。--sanitize=<sanitize>:开启针对错误行为的运行时检查,可选值为address、thread、undefined、scudo。--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()其中rootPackage取graph.rootPackages的第一个元素,graph.directDependencies(for:)用于逐层获取每个包的直接依赖,ModulesGraph则承载了完整的解析结果。
JSON 字段的来源
JSON dumper 中每个字段都能回溯到ResolvedPackage的 manifest 信息:identity来自package.identity,url来自package.manifest.packageLocation,version来自package.manifest.version(无版本时为unspecified),path来自package.path.pathString,traits来自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 输出可被解析为字典,顶层
name为Dealer,path解析后与包根目录一致。
在 DependencyResolutionTests.swift 中还有使用show-dependencies -v的端到端依赖解析验证。这些测试共同锁定了命令的输出契约,也意味着你在本地可以用同一夹具复现:
# 在仓库内查看示例包的依赖 swift package --package-path Fixtures/DependencyResolution/External/Complex/app show-dependencies实战要点小结
- 快速排障:
swift package show-dependencies直接展示“实际生效”的依赖版本,排查版本漂移时优先使用它而不是读Package.resolved。 - 可复现构建:配合
--force-resolved-versions(等价于--only-use-versions-from-resolved-file)可强制只使用已锁定版本,Package.resolved过期即报错。 - CI 审计:用
--format json --output-path dep.json将依赖快照落盘,供后续 diff 或合规扫描。 - 可视化:
--format dot生成的 DOT 文件可直接交给 Graphviz 渲染依赖关系图。 - 离线/受限网络:按需组合
--skip-update、--disable-sandbox、--netrc-file与--default-registry-url等选项,控制依赖获取来源与凭证方式。 - 注意输出对象的粒度:show-dependencies 输出的是包级依赖图,而非 target/module 级依赖;查看模块级依赖关系需借助其他工具(如
swift build --show-dependencies或 PIF 相关命令)。
- 开发工具
- 构建工具
【免费下载链接】swift-package-manager
The Package Manager for the Swift Programming Language
相关推荐
SwiftPM `swift package resolve` 命令完全指南:依赖解析、Package.resolved 与安全校验
SwiftPM swift package resolve 命令完全指南:依赖解析、Package.resolved 与安全校验 swift package r
开发工具构建工具SwiftPM 包集合(Package Collections)完全指南:`swift package-collection` 命令详解
SwiftPM 包集合(Package Collections)完全指南: swift package collection 命令详解 swift packag
开发工具构建工具SwiftPM `swift package show-executables` 命令完全指南:列出包内所有可执行产物
SwiftPM swift package show executables 命令完全指南:列出包内所有可执行产物 导读 swift package show
开发工具构建工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考