
Spm Build Analysis
- 2.8k installs
- 1.2k repo stars
- Updated April 15, 2026
- avdlee/xcode-build-optimization-agent-skill
spm-build-analysis is an Xcode skill that audits Swift Package Manager dependencies, plugins, and module variants slowing clean and incremental builds.
About
SPM Build Analysis is an Xcode optimization skill for when package structure, plugins, or dependency configuration likely hurt build performance. It treats analysis as evidence gathering first and forbids rewriting Package.swift without explicit approval. Inspect Package.swift, Package.resolved, local versus remote packages, build-tool plugins, binary targets, layering, and cycles plus timing logs showing package work. Before recommending local packages, verify XCLocalSwiftPackageReference and XCSwiftPackageProductDependency entries in project.pbxproj so unlinked Vendor folders are excluded. Branch-pinned dependencies scan via scripts/check_spm_pins.py for taggable versions or commit pins. Focus areas span plugin overhead, configuration drift forcing duplicate module builds, circular dependencies, oversized 200+ file modules, umbrella @_exported import chains, test targets depending on app targets, Swift macro rebuild cascades, swift-syntax universal builds, and multi-platform multiplication such as watchOS variants. Modular SDK migrations may increase SwiftCompile task counts, so benchmark before recommending speed gains. Findings report evidence, affected package, clean versus i.
- Evidence-first SPM audit without rewriting manifests without explicit approval.
- Verifies local packages are actually linked via pbxproj references before recommending.
- Covers plugin overhead, macro cascades, swift-syntax builds, and multi-platform multiplication.
- Flags oversized modules, circular deps, umbrella @_exported imports, and test-target coupling.
- Modular SDK migrations require before/after SwiftCompile benchmarks; speed gains are not automatic.
Spm Build Analysis by the numbers
- 2,809 all-time installs (skills.sh)
- +63 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #62 of 1,048 Mobile Development skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
spm-build-analysis capabilities & compatibility
- Capabilities
- package.swift and package.resolved graph inspect · local package linkage verification via pbxproj r · branch pin tag scanning via check_spm_pins.py he · plugin, macro cascade, and multi platform build · structured findings with clean, incremental, and
- Use cases
- devops · ci cd · debugging
- Platforms
- macOS
What spm-build-analysis says it does
Treat package analysis as evidence gathering first, not a mandate to replace dependencies
npx skills add https://github.com/avdlee/xcode-build-optimization-agent-skill --skill spm-build-analysisAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.8k |
|---|---|
| repo stars | ★ 1.2k |
| Security audit | 2 / 3 scanners passed |
| Last updated | April 15, 2026 |
| Repository | avdlee/xcode-build-optimization-agent-skill ↗ |
Why are my Xcode builds slow when Swift packages, plugins, or SPM graph shape seem to be the bottleneck?
Analyze Swift Package Manager graphs, plugins, module variants, and CI overhead that slow Xcode clean and incremental builds.
Who is it for?
iOS developers investigating SPM slowness, package resolution time, plugin overhead, or duplicate module builds from configuration drift.
Skip if: Skip when the primary bottleneck is project settings unrelated to packages; hand off to xcode-project-analyzer instead.
When should I use this skill?
User mentions SPM slowness, package plugins, circular module dependencies, swift-syntax overhead, or modular SDK migration build impact.
What you get
Evidence-backed findings per package with clean versus incremental impact, CI notes, estimated impact, and approval requirements.
- package impact findings with evidence
- pin recommendations for branch-tracked deps
By the numbers
- [object Object]
- [object Object]
Files
SPM Build Analysis
Use this skill when package structure, plugins, or dependency configuration are likely contributing to slow Xcode builds.
Core Rules
- Treat package analysis as evidence gathering first, not a mandate to replace dependencies.
- Separate package-graph issues from project-setting issues.
- Do not rewrite package manifests or dependency sources without explicit approval.
What To Inspect
Package.swiftandPackage.resolved- local packages vs remote packages
- package plugin and build-tool usage
- binary target footprint
- dependency layering, repeated imports, and potential cycles
- build logs or timing summaries that show package-related work
Verification Before Recommending
Before including any local package in a recommendation, verify that it is actually part of the project's dependency graph. A Vendor/ directory may contain packages that are not linked to any target.
- Check
project.pbxprojforXCLocalSwiftPackageReferenceentries that reference the package path. - Check
XCSwiftPackageProductDependencyentries to confirm the package's product is linked to at least one target. - If a local package exists on disk but is not referenced in the project, do not include it in build-time recommendations.
When recommending version pins for branch-tracked dependencies:
- Use the helper script to scan all branch-pinned dependencies at once:
python3 scripts/check_spm_pins.py --project App.xcodeprojThis checks git ls-remote --tags for each branch-pinned package and reports which have tags available for pinning.
- If no tags exist, recommend pinning to a specific commit revision hash for determinism instead.
- Note which packages are branch-pinned because the upstream simply has no tags, versus packages that have tags but are intentionally tracking a branch.
Focus Areas
- package graph shape and how much work changes trigger downstream
- plugin overhead during local development and CI
- checkout or fetch cost signals that show up in clean environments
- configuration drift that forces duplicate module builds
- risks from package targets that use different macros or options while sharing dependencies
- dependency direction violations (features depending on each other instead of shared lower layers)
- circular dependencies between modules (extract shared contracts into a protocol module)
- oversized modules (200+ files) that widen incremental rebuild scope
- umbrella modules using
@_exported importthat create hidden dependency chains - missing interface/implementation separation that blocks build parallelism
- test targets depending on the app target instead of the module under test
- Swift macro rebuild cascading: heavy use of Swift macros (e.g., TCA, swift-syntax-based libraries) can cause a trivial source change to cascade into near-full rebuilds because macro expansion invalidates downstream modules
swift-syntaxbuilding universally (all architectures) when no prebuilt binary is available, adding significant clean-build overhead- multi-platform build multiplication: adding a secondary platform target (e.g., watchOS) can cause shared SPM packages to build multiple times (e.g., iOS arm64, iOS x86_64, watchOS arm64), multiplying
SwiftCompile,SwiftEmitModule, andScanDependenciestasks
Modular SDK Migration Caveat
Migrating a dependency from a monolithic target to a modular multi-target SDK (e.g., replacing one umbrella library with separate Core, RUM, Logs, Trace modules) does not automatically reduce build time. Modular targets increase the number of SwiftCompile, SwiftEmitModule, and ScanDependencies tasks because each target must be compiled, scanned, and emit its module independently. The build-time trade-off depends on the project's parallelism headroom and how many of the modular targets are actually needed.
When considering a modular SDK migration:
- Compare the total
SwiftCompiletask count before and after. - Benchmark both configurations before recommending the migration for build speed.
- If the motivation is API surface reduction (importing only what you use), note that build time may stay flat or increase while import hygiene improves.
- Only recommend modular SDK migration for build speed when the project currently compiles large portions of the monolithic SDK that it does not use, and the modular alternative lets it skip those unused portions entirely.
Explicit Module Dependency Angle
When the same module appears multiple times in timing output, investigate whether different package or target options are forcing extra module variants. Uniform options often matter more than shaving a small amount of source code.
Reporting Format
For each finding, include:
- evidence
- affected package or plugin
- likely clean-build vs incremental-build impact
- CI impact if relevant
- estimated impact
- approval requirement
If the main problem is not package-related, hand off to `xcode-project-analyzer` or `xcode-compilation-analyzer` by reading the target skill's SKILL.md and applying its workflow to the same project context.
Additional Resources
- For the detailed audit checklist, see references/spm-analysis-checks.md
- For the shared recommendation structure, see references/recommendation-format.md
- For source citations, see references/build-optimization-sources.md
Build Optimization Sources
This file stores the external sources that the README and skill docs should cite consistently.
Apple: Improving the speed of incremental builds
Source:
- <https://developer.apple.com/documentation/xcode/improving-the-speed-of-incremental-builds>
Key takeaways:
- Measure first with
Build With Timing Summaryorxcodebuild -showBuildTimingSummary. - Accurate target dependencies improve correctness and parallelism.
- Run scripts should declare inputs and outputs so Xcode can skip unnecessary work.
.xcfilelistfiles are appropriate when scripts have many inputs or outputs.- Custom frameworks and libraries benefit from module maps, typically by enabling
DEFINES_MODULE. - Module reuse is strongest when related sources compile with consistent options.
- Breaking monolithic targets into better-scoped modules can reduce unnecessary rebuilds.
Apple: Improving build efficiency with good coding practices
Source:
- <https://developer.apple.com/documentation/xcode/improving-build-efficiency-with-good-coding-practices>
Key takeaways:
- Use framework-qualified imports when module maps are available.
- Keep Objective-C bridging surfaces narrow.
- Prefer explicit type information when inference becomes expensive.
- Use explicit delegate protocols instead of overly generic delegate types.
- Simplify complex expressions that are hard for the compiler to type-check.
Apple: Building your project with explicit module dependencies
Source:
- <https://developer.apple.com/documentation/xcode/building-your-project-with-explicit-module-dependencies>
Key takeaways:
- Explicit module builds make module work visible in the build log and improve scheduling.
- Repeated builds of the same module often point to avoidable module variants.
- Inconsistent build options across targets can force duplicate module builds.
- Timing summaries can reveal option drift that prevents module reuse.
SwiftLee: Build performance analysis for speeding up Xcode builds
Source:
- <https://www.avanderlee.com/optimization/analysing-build-performance-xcode/>
Key takeaways:
- Clean and incremental builds should both be measured because they reveal different problems.
- Build Timeline and Build Timing Summary are practical starting points for build optimization.
- Build scripts often produce large incremental-build wins when guarded correctly.
-warn-long-function-bodiesand-warn-long-expression-type-checkinghelp surface compile hotspots.- Typical debug and release build setting mismatches are worth auditing, especially in older projects.
Apple: Xcode Release Notes -- Compilation Caching
Source:
- Xcode Release Notes (149700201)
Key takeaways:
- Compilation caching is an opt-in feature for Swift and C-family languages.
- It caches prior compilation results and reuses them when the same source inputs are recompiled.
- Branch switching and clean builds benefit the most.
- Can be enabled via the "Enable Compilation Caching" build setting or per-user project settings.
Apple: Demystify explicitly built modules (WWDC24)
Source:
- <https://developer.apple.com/videos/play/wwdc2024/10171/>
Key takeaways:
- Explains how explicitly built modules divide compilation into scan, module build, and source compile stages.
- Unrelated modules build in parallel, improving CPU utilization.
- Module variant duplication is a key bottleneck -- uniform compiler options across targets prevent it.
- The build log shows each module as a discrete task, making it easier to diagnose scheduling issues.
Swift Compile-Time Best Practices
Well-known Swift language patterns that reduce type-checker workload during compilation:
- Mark classes
finalwhen they are not intended for subclassing. This eliminates dynamic dispatch overhead and allows the compiler to de-virtualize method calls. - Restrict access control to the narrowest useful scope (
private,fileprivate). Fewer visible symbols reduce the compiler's search space during type resolution. - Prefer value types (
struct,enum) overclasswhen reference semantics are not needed. Value types are simpler for the compiler to reason about. - Break long method chains (
.map().flatMap().filter()) into intermediateletbindings with explicit type annotations. Even simple-looking chains can take seconds to type-check. - Provide explicit return types on closures passed to generic functions, especially in SwiftUI result-builder contexts.
- Decompose large SwiftUI
bodyproperties into smaller extracted subviews. Each subview narrows the scope of the result-builder expression the type-checker must resolve.
Bitrise: Demystifying Explicitly Built Modules for Xcode
Source:
- <https://bitrise.io/blog/post/demystifying-explicitly-built-modules-for-xcode>
Key takeaways:
- Explicit module builds give
xcodebuildvisibility into smaller compilation tasks for better parallelism. - Enabled by default for C/Objective-C in Xcode 16+; experimental for Swift.
- Minimizing module variants by aligning build options is the primary optimization lever.
- Some projects see regressions from dependency scanning overhead -- benchmark before and after.
Bitrise: Xcode Compilation Cache FAQ
Source:
- <https://docs.bitrise.io/en/bitrise-build-cache/build-cache-for-xcode/xcode-compilation-cache-faq.html>
Key takeaways:
- Granular caching is controlled by
SWIFT_ENABLE_COMPILE_CACHEandCLANG_ENABLE_COMPILE_CACHE, under the umbrellaCOMPILATION_CACHE_ENABLE_CACHINGsetting. - Non-cacheable tasks include
CompileStoryboard,CompileXIB,CompileAssetCatalogVariant,PhaseScriptExecution,DataModelCompile,CopyPNGFile,GenerateDSYMFile, andLd. - SPM dependencies are not yet cacheable as of Xcode 26 beta.
RocketSim Docs: Build Insights
Sources:
- <https://www.rocketsim.app/docs/features/build-insights/build-insights/>
- <https://www.rocketsim.app/docs/features/build-insights/team-build-insights/>
Key takeaways:
- RocketSim automatically tracks clean vs incremental builds over time without build scripts.
- It reports build counts, duration trends, and percentile-based metrics such as p75 and p95.
- Team Build Insights adds machine, Xcode, and macOS comparisons for cross-team visibility.
- This repository is best positioned as the point-in-time analyze-and-improve toolkit, while RocketSim is the monitor-over-time companion.
Swift Forums: Slow incremental builds because of planning swift module
Source:
- <https://forums.swift.org/t/slow-incremental-builds-because-of-planning-swift-module/84803>
Key takeaways:
- "Planning Swift module" can dominate incremental builds (up to 30s per module), sometimes exceeding clean build time.
- Replanning every module without scheduling compiles is a sign that build inputs are being modified unexpectedly (e.g., a misconfigured linter touching file timestamps).
- Enable Task Backtraces (Xcode 16.4+: Scheme Editor > Build > Build Debugging) to see why each task re-ran in an incremental build.
- Heavy Swift macro usage (e.g., TCA / swift-syntax) can cause trivial changes to cascade into near-full rebuilds.
swift-syntaxbuilds universally (all architectures) when no prebuilt binary is available, adding significant overhead.SwiftEmitModulecan take 60s+ after a single-line change in large modules.- Asset catalog compilation is single-threaded per target; splitting assets into separate bundles across targets enables parallel compilation.
- Multi-platform targets (e.g., adding watchOS) can cause SPM packages to build 3x (iOS arm64, iOS x86_64, watchOS arm64).
- Zero-change incremental builds still incur ~10s of fixed overhead: compute dependencies, send project description, create build description, script phases, codesigning, and validation.
- Codesigning and validation run even when output has not changed.
Recommendation Format
All optimization skills should report recommendations in a shared structure so the orchestrator can merge and prioritize them cleanly.
Required Fields
Each recommendation should include:
titlewait_time_impact-- plain-language statement of expected wall-clock impact, e.g. "Expected to reduce your clean build by ~3s", "Reduces parallel compile work but unlikely to reduce build wait time", or "Impact on wait time is uncertain -- re-benchmark to confirm"actionability-- classifies how fixable the issue is from the project (see values below)categoryobserved_evidenceestimated_impactconfidenceapproval_requiredbenchmark_verification_status
Actionability Values
Every recommendation must include an actionability classification:
repo-local-- Fix lives entirely in project files, source code, or local configuration. The developer can apply it without side effects outside the repo.package-manager-- Requires CocoaPods or SPM configuration changes that may have broad side effects (e.g., linkage mode, dependency restructuring). These should be benchmarked before and after.xcode-behavior-- Observed cost is driven by Xcode internals and is not suppressible from the project. Report the finding for awareness but do not promise a fix.upstream-- Requires changes in a third-party dependency or external tool. The developer cannot fix it locally.
Suggested Optional Fields
scopeaffected_filesaffected_targetsaffected_packagesimplementation_notesrisk_level
JSON Example
{
"recommendations": [
{
"title": "Guard a release-only symbol upload script",
"wait_time_impact": "Expected to reduce your incremental build by approximately 6 seconds.",
"actionability": "repo-local",
"category": "project",
"observed_evidence": [
"Incremental builds spend 6.3 seconds in a run script phase.",
"The script runs for Debug builds even though the output is only needed in Release."
],
"estimated_impact": "High incremental-build improvement",
"confidence": "High",
"approval_required": true,
"benchmark_verification_status": "Not yet verified",
"scope": "Target build phase",
"risk_level": "Low"
}
]
}Markdown Rendering Guidance
When rendering for human review, preserve the same field order:
1. title 2. wait-time impact 3. actionability 4. observed evidence 5. estimated impact 6. confidence 7. approval required 8. benchmark verification status
That makes it easier for the developer to approve or reject specific items quickly.
Verification Status Values
Recommended values:
Not yet verifiedQueued for verificationVerified improvementNo measurable improvementInconclusive due to benchmark noise
SPM Analysis Checks
Use this reference when package dependencies or package plugins are suspected build bottlenecks.
Package Graph Checks
- Identify large umbrella packages that trigger widespread rebuilds.
- Look for dependency layering that forces many downstream targets to recompile.
- Flag local package arrangements that cause broad invalidation after small edits.
Package Plugin Checks
- List build-tool and command plugins involved in the build.
- Measure whether plugins run during incremental builds even when no relevant input changed.
- Call out plugins that return quickly but still add fixed overhead to every build.
Package Reference Verification
- Before including any local package in a build-time recommendation, confirm it appears in the project's
XCLocalSwiftPackageReferencesection ofproject.pbxproj. - A package existing under
Vendor/or as a directory in the repo does not mean it is linked. Only referenced packages affect build time. - For remote packages, confirm the
XCRemoteSwiftPackageReferenceentry exists and at least oneXCSwiftPackageProductDependencylinks its product to a target.
Version Pin Feasibility
- When recommending a switch from
branch:to a tagged version, verify tags exist viagit ls-remote --tags <url>. - If no tags exist, recommend pinning to a specific
revision:hash for deterministic resolution. - Note the distinction: branch pins force network checks on every fresh resolve; revision pins are fully deterministic but do not benefit from semver range resolution.
Binary And Remote Dependency Checks
- Note binary target size and extraction overhead for clean environments.
- Highlight remote checkout or fetch costs that matter for CI or fresh machines.
- Compare remote vs local package tradeoffs when iteration speed matters more than distribution convenience.
Module Variant Checks
- Look for the same dependency module being built with different options.
- Compare macros, language mode, and configuration-sensitive options across dependents.
- Prefer configuration alignment when it reduces repeated module builds safely.
Layered Architecture Validation
- Enforce a clear dependency direction: Common/Core --> Services/Domain --> Features/UI. Dependencies must flow in one direction only (inward/downward).
- Features should never depend on each other directly. If two features share types, move those types to a lower-layer module.
- Validate that
Package.swifttarget dependency lists match the intended layer hierarchy.
Circular Dependency Detection
- SPM supports cyclic package dependencies (since May 2024) but not cyclic target dependencies.
- Circular module dependencies should always be refactored: extract the shared contract (protocols, DTOs) into a separate module that both sides depend on.
- Check for hidden cycles through transitive dependencies by tracing the full dependency graph.
Module Sizing Guidance
- Modules larger than roughly 200 files increase incremental build scope unnecessarily -- a single file change recompiles more than needed.
- Recommend splitting oversized modules by feature area or responsibility.
- Each module should have a clear, single-purpose responsibility. If a module's name requires "And" or "Utils" to describe, it likely needs splitting.
Transitive Dependency Minimization
- Each module should depend only on what it directly uses. Unnecessary transitive dependencies widen the rebuild surface.
- Avoid "umbrella" modules that re-export everything via
@_exported import-- they create hidden dependency chains where a change in any re-exported module triggers rebuilds in all importers. - Use
@_exported importsparingly and only for genuine convenience wrappers.
Interface/Implementation Separation
- Define protocols and public types in lightweight "interface" modules (e.g.,
NetworkingInterface). - Put implementations in separate modules (e.g.,
NetworkingImpl). - Feature modules compile against the interface without waiting for the full implementation to build, improving parallelism.
- This pattern is most valuable when the implementation module has many files or heavy dependencies that would block downstream compilation.
Test Target Isolation
- Test targets should depend on the module under test, not the entire app target. Depending on the app target forces a full app build before tests can compile.
- Shared test utilities (mocks, fixtures, helpers) belong in a dedicated
TestHelpersmodule rather than being duplicated across test targets. - Keep test-only dependencies out of production target dependency lists.
Swift Macro Rebuild Impact
- Projects that heavily use Swift macros (e.g., TCA, swift-syntax-based libraries) are susceptible to incremental build cascading where a trivial change rebuilds most of the app.
- Macro expansion can invalidate downstream modules even when the expanded output has not changed, because the build system treats the macro input as a dependency.
- Check whether
swift-syntaxis building universally (all architectures) when no prebuilt binary is available. This adds significant overhead to clean builds and CI. Verify with the build log whether theswift-syntaxtarget compiles for more architectures thanONLY_ACTIVE_ARCHwould suggest. - If macro-heavy packages dominate incremental build time, consider whether the macro-using code can be isolated into fewer, more stable modules to limit the invalidation blast radius.
Multi-Platform Build Multiplication
- Adding a secondary platform target (e.g., watchOS, macOS Catalyst) can cause shared SPM packages to build multiple times -- once per platform and architecture combination.
- A project with iOS and watchOS targets may build shared packages 3x: iOS arm64, iOS x86_64 (simulator), and watchOS arm64.
- Check the build log for duplicate
SwiftCompile,SwiftEmitModule, andScanDependenciestasks for the same package across different platform/architecture slices. - If multi-platform multiplication is a significant contributor, consider whether secondary platform targets can use a subset of shared packages, or whether packages can be prebuilt as binary targets for secondary platforms.
CI-Specific Checks
- Fresh checkout cost
- plugin invocation cost
- cache hit sensitivity
- redundant package resolution work
Recommendation Prioritization
Qualify every estimated impact with wall-clock framing. High-priority items should be those likely to reduce the developer's actual wait time, not just cumulative task totals. If the impact on wait time is uncertain, say so.
- High: package plugins or graph structure repeatedly inflating incremental builds, circular dependencies, umbrella re-exports causing cascading rebuilds, Swift macro cascading that causes near-full rebuilds from trivial changes.
- Medium: configuration drift that causes duplicate module variants, oversized modules, missing interface/implementation separation, multi-platform build multiplication,
swift-syntaxbuilding universally without prebuilt binary. - Low: clean-environment checkout costs that barely affect local iteration, minor transitive dependency cleanup.
#!/usr/bin/env python3
"""Scan a project.pbxproj for branch-pinned SPM dependencies and check tag availability."""
import argparse
import json
import re
import subprocess
import sys
from pathlib import Path
from typing import Dict, List, Optional
_PKG_REF_RE = re.compile(
r"(/\*\s*XCRemoteSwiftPackageReference\s+\"(?P<name>[^\"]+)\"\s*\*/\s*=\s*\{[^}]*?"
r"repositoryURL\s*=\s*\"(?P<url>[^\"]+)\"[^}]*?"
r"requirement\s*=\s*\{(?P<req>[^}]*)\})",
re.DOTALL,
)
_KIND_RE = re.compile(r"kind\s*=\s*(\w+)\s*;")
_BRANCH_RE = re.compile(r"branch\s*=\s*(\w+)\s*;")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Check branch-pinned SPM dependencies for available tags."
)
parser.add_argument(
"--project",
required=True,
help="Path to the .xcodeproj directory",
)
parser.add_argument(
"--json",
action="store_true",
help="Output results as JSON",
)
return parser.parse_args()
def find_branch_pins(pbxproj: str) -> List[Dict[str, str]]:
results: List[Dict[str, str]] = []
for match in _PKG_REF_RE.finditer(pbxproj):
name = match.group("name")
url = match.group("url")
req = match.group("req")
kind_match = _KIND_RE.search(req)
if not kind_match:
continue
kind = kind_match.group(1)
if kind != "branch":
continue
branch_match = _BRANCH_RE.search(req)
branch = branch_match.group(1) if branch_match else "unknown"
results.append({"name": name, "url": url, "branch": branch})
return results
def check_tags(url: str) -> List[str]:
try:
result = subprocess.run(
["git", "ls-remote", "--tags", url],
capture_output=True,
text=True,
timeout=15,
)
if result.returncode != 0:
return []
tags: List[str] = []
for line in result.stdout.strip().splitlines():
ref = line.split("\t")[-1] if "\t" in line else ""
if ref.startswith("refs/tags/") and not ref.endswith("^{}"):
tags.append(ref.replace("refs/tags/", ""))
return tags
except (subprocess.TimeoutExpired, FileNotFoundError):
return []
def main() -> int:
args = parse_args()
pbxproj_path = Path(args.project) / "project.pbxproj"
if not pbxproj_path.exists():
sys.stderr.write(f"Not found: {pbxproj_path}\n")
return 1
pbxproj = pbxproj_path.read_text()
pins = find_branch_pins(pbxproj)
if not pins:
print("No branch-pinned SPM dependencies found.")
return 0
results: List[Dict] = []
for pin in pins:
tags = check_tags(pin["url"])
entry = {
"name": pin["name"],
"url": pin["url"],
"branch": pin["branch"],
"tags_available": len(tags) > 0,
"latest_tags": tags[-5:] if tags else [],
}
results.append(entry)
if args.json:
print(json.dumps(results, indent=2))
else:
for r in results:
status = "tags available" if r["tags_available"] else "no tags (pin to revision)"
latest = f" (latest: {', '.join(r['latest_tags'])})" if r["latest_tags"] else ""
print(f" {r['name']}: branch={r['branch']} -> {status}{latest}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
Related skills
How it compares
Pair spm-build-analysis with xcode-build-benchmark when you need both Apple-guided remediation and persisted before/after timing artifacts.
FAQ
Will the skill rewrite my Package.swift?
No. It gathers evidence first and does not rewrite manifests or dependency sources without explicit approval.
How do I verify a local Vendor package matters?
Check project.pbxproj for XCLocalSwiftPackageReference and XCSwiftPackageProductDependency linking the product to a target.
Does modular SDK migration always speed up builds?
No. More modular targets can increase SwiftCompile tasks; benchmark both configurations before recommending migration for speed.
Is Spm Build Analysis safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.