bloomberg / bloomberg/xcdiff

Expose structured diff results (from `XCDiffCore`)

Open
#85 2 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Swift
Stars
962
Forks
46
PR merge metrics
No merged PRs in 30d

Description

**Is your feature request related to a problem? Please describe.**

Using `XCDiffCore` as library enables other tools and application to leverage xcdiff programatically to perform project comparisons and retrieve their results. This however is limited to textual results only rather than the structured results.

e.g. The main entry point is `ProjectComparator`

```swift
public protocol ProjectComparator {
func compare(_ firstPath: Path,
_ secondPath: Path,
parameters: ComparatorParameters) throws -> Result
}
```

This returns `Result` which exposes the results as a raw `String`:

```swift
public struct Result {
public let success: Bool
public let output: String
}
```

**Describe the solution you'd like**

Expose another method or component that can return the underlying `ProjectCompareResult` (which is structured).

One option could be to add another method on `ProjectComparator` :

e.g. `structuredCompare()`

```swift
public protocol ProjectComparator {
func compare(
_ firstPath: Path,
_ secondPath: Path,
parameters: ComparatorParameters
) throws -> Result

func structuredCompare(
_ firstPath: Path,
_ secondPath: Path,
parameters: ComparatorParameters
) throws -> ProjectCompareResult
}
```

This however makes the API a little awkward as a `ProjectComparator` is obtained via `ProjectComparatorFactory ` which requires specifying the list of comparators along with a [`Mode`](https://github.com/bloomberg/xcdiff/blob/main/Sources/XCDiffCore/ProjectComparator.swift#L28) which specifies the output `format` that is not applicable when dealing with structured results.

Another option could be extend `ProjectComparatorFactory` to return a new type `StructuredProjectComparator`, the factory however will not require specifying `Mode`

e.g.

```swift
public protocol StructuredProjectComparator {
func compare(
_ firstPath: Path,
_ secondPath: Path,
parameters: ComparatorParameters
) throws -> ProjectCompareResult
}

public final class ProjectComparatorFactory {
public static func create(
comparators: [ComparatorType] = .allAvailableComparators,
mode: Mode = .default
) -> ProjectComparator {
// ...
}

public static func createStructuredComparator(
comparators: [ComparatorType] = .allAvailableComparators,
verbose: Bool = false,
differencesOnly: Bool = false
) -> StructuredProjectComparator {
// ...
}
}
```

**Describe alternatives you've considered**

- An alternative could be to leverage json formatted results and manually re-create the `ProjectCompareResult` structure that is capable of decoding the raw json back into something more structured. This feels unnecessary seeing the `ProjectCompareResult` is already public (just not `Decodable`).
- Another could be to manually write a custom `StructuredProjectComparator` outside of `XCDiffCore`, this is a little challenging as there isn't any public mechanisms to create the built in comparators. Furthermore, requires clients to deal `XCDiffCore` dependencies _(`XcodeProj` loading and `PathKit`)_ to recreate the project comparator.

Contributor guide

Open the contributing guide

Research direction

Start with Sources/XCDiffCore/ProjectComparator.swift and the ProjectComparatorFactory and ProjectCompareResult entry points named in the issue. Review how comparator creation currently depends on Mode and output format, then determine a public path for returning structured results without requiring textual output settings. Done means library clients can retrieve ProjectCompareResult while the existing textual compare API remains usable.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.