Skip to content

--skip-build without --index-store-path fails to find Xcode's index store #1082

@ky1ejs

Description

@ky1ejs

Summary

When using --skip-build without --index-store-path, periphery looks for the index store inside its own custom DerivedData directory (~/Library/Caches/com.github.peripheryapp/DerivedData-<hashes>) rather than falling back to Xcode's standard DerivedData location (~/Library/Developer/Xcode/DerivedData/).

Since the build was skipped, periphery's custom DerivedData directory was never created, and the scan fails with:

Error: Failed to find index datastore at path: ~/Library/Caches/com.github.peripheryapp/DerivedData-<hashes>

Steps to Reproduce

  1. Build the project with Xcode (or xcodebuild) — this creates the index store in Xcode's default DerivedData location
  2. Run periphery scan --skip-build --strict
  3. Periphery fails because it looks in its own cache path, not Xcode's DerivedData

Expected Behavior

When --skip-build is used without --index-store-path, periphery should fall back to searching Xcode's default DerivedData location (~/Library/Developer/Xcode/DerivedData/) for the index store, since the user is indicating that a build already exists elsewhere.

Actual Behavior

Periphery only checks its own custom DerivedData path (~/Library/Caches/com.github.peripheryapp/DerivedData-*) and fails with indexStoreNotFound.

Root Cause

In Sources/XcodeSupport/Xcodebuild.swift, indexStorePath() always computes the path via derivedDataPath(), which returns periphery's own cache directory. When --skip-build is used, this directory was never populated:

public func indexStorePath(project: XcodeProjectlike, schemes: [String]) throws -> FilePath {
    let derivedDataPath = try derivedDataPath(for: project, schemes: schemes)
    let pathsToTry = ["Index.noindex/DataStore", "Index/DataStore"]
        .map { derivedDataPath.appending($0) }
    guard let path = pathsToTry.first(where: { $0.exists }) else {
        throw PeripheryError.indexStoreNotFound(derivedDataPath: derivedDataPath.string)
    }
    return path
}

There is no fallback to Xcode's default DerivedData path.

Workaround

Explicitly pass --index-store-path pointing to Xcode's index store:

INDEX_STORE_PATH=$(find ~/Library/Developer/Xcode/DerivedData -path "*/Index.noindex/DataStore" -type d 2>/dev/null | head -1)
periphery scan --skip-build --index-store-path "$INDEX_STORE_PATH" --strict

Suggested Fix

When --skip-build is used and the index store is not found in periphery's own DerivedData directory, fall back to searching Xcode's default DerivedData location (~/Library/Developer/Xcode/DerivedData/<Project>-*/Index.noindex/DataStore).

Environment

  • Periphery 3.6.0 (via Homebrew)
  • Xcode 26.2
  • macOS (GitHub Actions, macos-26 runner)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions