Coder Social home page Coder Social logo

bloomberg / xcdiff Goto Github PK

View Code? Open in Web Editor NEW
904.0 18.0 45.0 920 KB

A tool which helps you diff xcodeproj files.

License: Apache License 2.0

Swift 95.95% Objective-C 1.40% C 0.84% Python 0.80% Shell 0.16% Makefile 0.26% Ruby 0.58%
swift xcodeproj xcode xcodeproject diff

xcdiff's Introduction

xcdiff logo

Build Status Coverage Status

xcdiff is an extensible tool that finds differences between two .xcodeproj project files. It can be thought of as git diff for .xcodeproj files, which can be used directly from the command line as well as a library supporting your own set of tools.

How to use xcdiff

Running the command xcdiff in your project directory will search for two .xcodeproj files in this directory and use all of xcdiff's comparators on the projects (e.g. targets, sources and headers).

You can also specify two particular projects for xcdiff to compare.

xcdiff -p1 OriginalProject.xcodeproj -p2 GeneratedProject.xcodeproj

Here is an example output:

xcdiff demo

To see a detailed report of differences you can specify the --verbose (-v) option.

xcdiff -p1 OriginalProject.xcodeproj -p2 GeneratedProject.xcodeproj -v

xcdiff demo -v

Use Cases

  • When adopting project generation (e.g. using tools like XcodeGen or Tuist), comparing the generated xcodeproj files against the original ones can help boost confidence in the migration process.
  • Probably a few more we haven't thought of yet!...

Installation

Documentation

Contributions

All improvements to xcdiff are very welcome!

If you see an issue that you would like to see fixed, the best way to make it happen is to help out by submitting a Pull Request implementing it. Before sending a Pull Request, please make sure you read our Contribution Guidelines. Information in Development Documentation can help you to set up your local development environment.

We also welcome Issue Reports. Be sure to choose the proper issue template for your issue, so that all necessary details are provided.

Attributions

We would like to thank the authors and contributors of the following projects:

Code of Conduct

This project has adopted a Code of Conduct. If you have any concerns about the Code, or behavior which you have experienced in the project, please contact us at [email protected].

Security Vulnerability Reporting

If you believe you have identified a security vulnerability in this project, please send email to the project team at [email protected], detailing the suspected issue and any methods you've found to reproduce it.

Please do NOT open an issue in the GitHub repository, as we'd prefer to keep vulnerability reports private until we've had an opportunity to review and address them.

License

xcdiff is released under version 2.0 of the Apache License.

xcdiff's People

Contributors

adamkhazi avatar avbangar avatar dmytro-anokhin avatar kennethshackleton avatar kishikawakatsumi avatar kwridan avatar lakpa avatar marciniwanicki avatar michaelmcguire avatar natanrolnik avatar ntduyet avatar skofgar avatar tbrachkov avatar technocidal avatar thermogl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xcdiff's Issues

Leverage `xcodebuild -showBuildSettings -json` to obtain the resolved build settings

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

xcdiff currently leverages xcodebuild -showBuildSettings to obtain the resolved build settings for a specified Xcode project. It then performs some custom parsing on the raw command output to process the results.

Describe the solution you'd like

There is a -json flag available on xcodebuild that can be used to obtain a json output that is simpler to parse and deal with.

e.g.

xcodebuild -showBuildSettings -json

It would be great to evaluate the feasibility of using this approach and migrating to it if possible.

Add homebrew formula

Is your feature request related to a problem? Please describe.
To ease the process of installing xcdiff, it would be great to add homebrew support such that it can be installed via:

brew install xcdiff

Describe the solution you'd like
Add a homebrew formula for xcdiff.

Same target attributes but triggers value mismatch

Describe the bug
For my project file, I've added several SystemCapabilities attributes to the project file (shown in the screenshot). However, when running xcdiff between the project file and its exact duplicate, the tool picks up on these attribute differences and triggers a Value Mismatch. The attributes are still the same even in the diff log, just listed in different orders.
Additionally, every time xcdiff is run on the same 2 project files, the SystemCapabilities attribute order for both of them changes, without changing the project file itself.

I would appreciate any help with this bug!! Thank you!

To Reproduce
Steps to reproduce the behavior:

  1. Add multiple SystemCapabilities attributes to a target in the project file
  2. Duplicate the project file
  3. Run xcdiff on the project file and its duplicate
  4. See error

Expected behavior
xcdiff should not pick up on differences between the project files because their attributes are the same. The order of the attributes should not matter.

Screenshots
Screen Shot 2022-12-19 at 2 52 52 PM
Screen Shot 2022-12-19 at 2 56 06 PM

Environment (please complete the following information):

  • Operating System and Version: macOS 12.6.1

Additional context
I am using XcodeGen to generate the project file. However, it generates the same attributes in the same order every time.

xcdiff --list could show which tags are enabled/disabled by default

When I wanted to "filter" some tags while using xcdiff, I used xcdiff --list to print the tags. I removed 2 of them, and, to my surprise, diffing jumped from a few seconds to around 30.

I messaged @kwridan in the Tuist Slack, and he pointed me to this file: Comparators.md. Kas explained (as written in the mentioned md file) that the RESOLVED_SETTINGS tag depends on xcodebuild under the hood, and this is why this tag is disabled by default.

Ideally, listing the tags should inform the user which tags are enabled/disabled by default, so mimicking the default behavior is easier.

An example of this is the SwiftLint's rules command, which prints much more information:

SwiftLintRules

For xcdiff, a table with the tags, description, and enabled by default would be even better.

Shorthand Optional Binding

Summary:

Shorthand optional binding arrived in Swift 5.7. Making use of this shorthand will increase the readability of the codebase and may also encourage the use of (longer) more meaningful variable names.

Example:

let offer: Offer? = ...

if let offer = offer {
    ...
}

Can now be shortened to:

let offer: Offer? = ...

if let offer {
    ...
}

This also works for guard let, if var, etc.

Additionally there is a shorthand_optional_binding rule for Swift Lint rules. This can be added to the rule set to prevent further additions of the long form.

Add project and target attributes comparator

Overview

Xcode projects have additional attributes at the project and targets levels. When adopting new Xcode versions, it's often handy to sanity check if there are any new attributes being added to ensure any existing project generation workflows continue to be compatible.

Those include items like organization name, Last Swift Update Check for the project and Host Target IDs for test targets.

Here's an example from the raw .pbxproj

/* Begin PBXProject section */
2E36BF3C22C5FEB3002DF525 /* Project object */ = {
    isa = PBXProject;
    attributes = {
        LastSwiftUpdateCheck = 1020;
        LastUpgradeCheck = 1020;
        ORGANIZATIONNAME = "My Organization Name";
        TargetAttributes = {
            2E36BF4322C5FEB3002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
            };
            2E36BF5722C5FEB4002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
                TestTargetID = 2E36BF4322C5FEB3002DF525;
            };
            2E36BF6222C5FEB4002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
                TestTargetID = 2E36BF4322C5FEB3002DF525;
            };
            2E36BF7922C5FEE6002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
            };
            2E36BF8122C5FEE6002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
                TestTargetID = 2E36BF4322C5FEB3002DF525;
            };
            2E36BF9C22C5FF02002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
            };
            2E36BFA422C5FF02002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
                TestTargetID = 2E36BF4322C5FEB3002DF525;
            };
            2E36BFBF22C5FF3B002DF525 = {
                CreatedOnToolsVersion = 10.2.1;
            };
        };
    };

Describe the solution you'd like

Add a new attributes comparator to show the diff results for those attributes.

Additional context

Seeing those results can be quite noisy and likely to change quite frequently between Xcode versions (e.g. the last upgrade check), I propose we make this comparator disabled by default (like the resolved setting comparator), so it would require explicitly specifying its tag to retrieve its results.

Shell Script Build Phases are not properly compared

Describe the bug
Comparisons of build phases does not compare all properties for script actions.

To Reproduce
Steps to reproduce the behavior:

  1. Clone the repo
  2. cd Fixtures
  3. open Project1.xcodeproj
  4. Add "New Run Script Phase" with an empty script.
  5. swift run xcdiff --target Project --tag BUILD_PHASES -v shows difference:
❌ BUILD_PHASES > "Project" target

⚠️  Only in first (1):

  • ShellScript (runScript)
  1. open Project2.xcodeproj
  2. Add "New Run Script Phase" with an empty script.
  3. swift run xcdiff --target Project --tag BUILD_PHASES -v outputs:
✅ BUILD_PHASES > "Project" target
  1. Add a new default "Input File Lists" item to Project1: $(SRCROOT)/newInputFile.xcfilelist
  2. swift run xcdiff --target Project --tag BUILD_PHASES -v shows difference:
❌ BUILD_PHASES > "Project" target

⚠️  Value mismatch (1):

  • Different properties in "ShellScript (runScript)"
    ◦ inputFileListPaths = ["$(SRCROOT)/newInputFile.xcfilelist"]
    ◦ inputFileListPaths = []
  1. Remove $(SRCROOT)/newInputFile.xcfilelist from "Input File Lists" in Project1 and try a different setting like "Input Files" or "Show environment variables in build log". Changing other properties in the build phase results in:
✅ BUILD_PHASES > "Project" target

Expected behavior
Display the differences in the build phase beyond the "Input File Lists"

Screenshots
image

Environment (please complete the following information):

  • Operating System and Version: macOS 12.4
  • xcdiff version: main

Additional context
Most of the settings in a ShellScript/Run Script action are not compared when running xcdiff. Looking at the properties compared, it looks as if only the base, abstract class PBXBuildPhase is being used for building the descriptor. The actual type that's returned back for script phases is PBXShellScriptBuildPhase and it contains all of the properties for script phases.

I'm working on a fix for this, but wanted to verify that 1. this is considered a bug, and 2. showing these differences in the BUILD_PHASES section is appropriate. I'm planning on looking at the type returned for each PBXTarget.buildPhases and if I see a PBXShellScriptBuildPhase, comparing all of the properties there as well.

Thanks for this amazing tool! It's been very helpful.

Platform filters are not taken into account when diffing projects

Describe the bug
For multi platform projects, platform filters can be used to specify if certain files or linked frameworks should be applicable to certain platforms (for example ARKit isn't supported on tvOS).

To Reproduce

  • Create a multi-platform app (i.e. one with multiple destinations, e.g. iPhone, iPad and Apple TV)
  • Link against ARKit
  • Apply a platform filter for iOS only
  • Duplicate the project
  • Change the platform filter to permit any platform
  • Run xcdiff against both projects
  • Notice: no diffs are flagged

Expected behavior
A diff should be flagged for any mismatching attributes.

Screenshots
Screenshot 2023-11-06 at 11 04 32

Additional context

  • platform filters can also be applied to other build files (e.g. source files)

Include element parsing errors in final diff results instead of failing

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

Recently working with @natanrolnik we noticed running xcdiff fails due to an incorrect path in one of the projects, thanks to #64 the source of the error was identified, however sadly as it wasn't immediately actionable it resulted in the inability to see the diff results for the remaining elements which were needed.

Describe the solution you'd like

Potentially log errors or collect errors and post them in the final diff result while continuing to perform a diff on other elements. This allows users to see a best effort diff while clearly seeing some of the elements which could not be diffed.

Describe alternatives you've considered

  • Ignore errors, however this could yield false results (e.g. no diff if all elements fail to parse for any reason) as such is probably not a suitable alternative.

Add Swift Package comparator

Is your feature request related to a problem? Please describe.
As of Xcode 11, Xcode projects can now specify Swift Package dependencies for its targets.

Describe the solution you'd like
Add a comparator that can diff any declared Swift Packages, including version rules.

For example, given the following 2 projects:

Project 1:

Screenshot 2019-11-14 at 08 04 39

Project 2:

Screenshot 2019-11-14 at 08 03 42

Running xcdiff -v could produce results that look like:

❌ SWIFT_PACKAGES

⚠️  Only in second (1):

  • Swifter (https://github.com/httpswift/swifter)

⚠️  Value mismatch (1):

  • SQLite.swift - Version Rules
    ◦ Next Major From: 0.12.2
    ◦ Next Minor From: 0.12.2

Expose structured diff results (from `XCDiffCore`)

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

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

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

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()

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 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.

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.

Update command tests generator for Xcode 12.5

Describe the bug
The generate_tests_commands_files.py script generates all the command tests for xcdiff. It does so by running xcdiff against the specified fixtures and capturing its output.

The mechanism used to run xcdiff is via swift run xcdiff <arguments>, one of xcdiff's arguments is the -v (verbose) flag, which as of Xcode 12.5 (Swift 5.4) is shadowed by swift run itself which now also respects that flag to produce more verbose output on what is being run. This results in xcdiff not receiving this flag (producing the wrong results) and pollutes the output that is captured for the command tests.

e.g.

# when using Xcode 12.5
$ swift build
$ cd Fixtures
$ swift run xcdiff -v
/usr/bin/xcrun --sdk macosx --show-sdk-platform-path
/Applications/Xcode12.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -print-target-info
/usr/bin/xcrun --sdk macosx --find xctest
/Applications/Xcode12.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -print-target-info
/usr/bin/xcrun --sdk macosx --show-sdk-platform-path
/usr/bin/xcrun vtool -show-build /Applications/Xcode12.5.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/XCTest
/usr/bin/xcrun --sdk iphoneos --show-sdk-platform-path
/usr/bin/xcrun vtool -show-build /Applications/Xcode12.5.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/XCTest
/usr/bin/xcrun --sdk appletvos --show-sdk-platform-path
/usr/bin/xcrun vtool -show-build /Applications/Xcode12.5.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/Library/Frameworks/XCTest.framework/XCTest
/usr/bin/xcrun --sdk watchos --show-sdk-platform-path
/usr/bin/xcrun vtool -show-build /Applications/Xcode12.5.app/Contents/Developer/Platforms/WatchOS.platform/Developer/Library/Frameworks/XCTest.framework/XCTest
❌ FILE_REFERENCES
❌ BUILD_PHASES > "MismatchingLibrary" target
...

To Reproduce

  1. Switch your system default Xcode to 12.5
  2. run make regenerate_command_snapshots
  3. Notice the generated markdown test files now contain additional swift run output
  4. Notice the generated markdown test files do not contain the correct verbose output

Expected behavior
The generated markdown files should only contain xcdiff's output.

Additional context
We can address this via changing the generate script slightly such that it no longer leverages swift run, instead:

  • Determine the directory the built xcdiff binary is placed in via swift build --show-bin-path
  • Invoking the built xcdiff binary directly $(swift build --show-bin-path)/xcdiff

Comparing embedded frameworks with different `codeSignOnCopy` yields inaccurate results

Describe the bug
Comparing two projects that have embedded frameworks with different code sign settings can yield results that state the frameworks with the code sign setting unchecked as missing!

To Reproduce
Steps to reproduce the behavior:

  1. Open Fixtures/Project2.xcodeproj
  2. Uncheck the Code Sign on Copy setting for ProjectFramework (note: may need to tweak the project.pbxproj manually to remove the attributes completely to reproduce this issue)

Screen Shot 2019-11-28 at 4 03 28 PM

  1. Run xcdiff within the Fixtures folder
  2. Notice the results state:
❌ DEPENDENCIES > "Project" target > Embedded Frameworks

⚠️  Only in first (1):

  • ProjectFramework.framework

Expected behavior

The ProjectFramework.framework is actually present in both projects however it's code sign attribute is different

⚠️  Value mismatch (1):

  • ProjectFramework.framework Code Sign on Copy
    ◦ true
    ◦ false

Additional context
I believe this is occurring due to skipping embedded frameworks build files with nil settings.

Update checked in tooling brew formulas (e.g. swiftformat and swiftlint)

Describe the bug

It appears the pinned versions of the brew formulas no longer work and require an update. This is currently used by Travis as part of the build process and blocks new PRs from being submitted.

To Reproduce

  • Run ./Scripts/brew.sh

See #88

Expected behavior

Brew formulas should get installed successfully.

Notes

A few options we can try:

  • Obtain new formulas and check if they still work with the pinning technique previously used
  • Experiment with using Mint for pinning swiftlint and swiftformat

I suspect Mint will be more stable going forward as we wouldn't need to pin Mint itself via homebrew and then rely on Mint to pin swiftlint and swiftformat which is a workflow it supports really well. The one downside is, with homebrew formulas that have bottles (i.e. prebuilt binaries) they are much faster to install than building from source which would be the workflow with Mint.

Scheme comparison

Is your feature request related to a problem? Please describe.
Compare Xcode project scheme's

Describe the solution you'd like
I would like to compare an Xcode project with a modified version, to see whether the schemes are identical or not.
It looks like the current version of xcdiff does not do this?

Describe alternatives you've considered
I have not considered any alternatives yet. I imagine I could just to a diff, but it would be nice if it was part of xcdiff

Additional context
n/a

Update GitHub Actions workflow to use Xcode 13.3

Is your feature request related to a problem? Please describe.
Currently the project uses Xcode 12.5.1. To keep it up to date we should update it to the latest version of Xcode.

Describe the solution you'd like
Update GitHub Actions to use Xcode 13.3 and macOS 12 (as it is required by Xcode 13.3).

Question on CopyFilesComparator

I'm using CopyFilesComparator as a base while working on #110 and was confused by quite a few the unit tests. As an example, the test testCompare_whenCopyFilesBuildPhaseOnlyInFirst_noDifference:

    func testCompare_whenCopyFilesBuildPhaseOnlyInFirst_noDifference() throws {
        // Given
        let first = project()
            .addTarget(name: "Target1", productType: .application) { target in
                target.addBuildPhase(.copyFiles(.frameworks)) { _ in }
            }
            .projectDescriptor()
        let second = project()
            .addTarget(name: "Target1", productType: .application) { _ in }
            .projectDescriptor()

        // When
        let actual = try subject.compare(first, second, parameters: .all)

        // Then
        XCTAssertEqual(actual, [.init(tag: "copy_files", context: ["\"Target1\" target"])])
    }

(Note: there are many like this where no difference is expected even though the copy files phases are different)

Why would a project that has the copy files build phase not fail if the second one did not? Is it because you assume the BuildPhaseComparator will pick up the differences? Should I be doing the same for the enhancement to Run / Shell scripts comparisons?

Add projects paths to the compare result

As pointed by @kwridan in #56 (review), it might be useful to have paths to -p1, -p2 projects in the result type. The paths could be included in supported formats (not only HTML).

I wonder if there is anything else we could add to the header section, i.e.

  • date of the generation
  • total number of detected differences

Update CI configuration to build with Xcode 13.1

Is your feature request related to a problem? Please describe.
The CI only builds the project with Xcode 12.5.1 as such we might not catch issues when building with the latest version of Xcode 13.

Describe the solution you'd like
We can either update the CI configuration (soon GitHub Actions) to build with both Xcode 12 and 13 or only build with 13.
Might be worth waiting for #93 to avoid conflicts.

Allow to parse a single project - no comparison

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

I often want to quickly find out "what are the dependencies of this project" or "what are the build settings of this project". However, opening Xcode and navigating the UI can be slow and cumbersome. xcdiff might provide a quick way to get at this info.

Describe the solution you'd like

It might be nice if you could invoke xcdiff to just parse and print these values without any comparison against another project

Remove SPMUtility dependency

Is your feature request related to a problem? Please describe.
I appreciate the SPMUtility and the ArgumentParser does a great job, however if we remove the dependency of SPMUtility and use some other framework like: kylef/Commander we could then revise the closed issue: Add podspec #14.

Describe the solution you'd like
Remove the SPMUtility dependency from the Package.swift for both XCDiffCore and XCDiffCommand. In XCDiffCore we need to write an alternative implementaion for line.spm_split(around: "="). It does not look like there are any other uses of the SPMUtility in the code.

Describe alternatives you've considered
We can use other dependency like: Carthage/Commandant
Instead of using a dependency to parse the command line arguments we can just implement our own module doing so as part of the tool.

Additional context
If we remove the SPMUtility then we can allow support for CocoaPods and Carthage.

Print out usage description when no projects are detected

Is your feature request related to a problem? Please describe.
When running xcdiff in a directory that doesn't contain two projects we currently print out an error.

ERROR: Could not find 2 projects in the current directory

Describe the solution you'd like
We could display a more helpful error message such as:

Could not find 2 projects in the current directory, use `-p1` and `-p2` to specify the projects paths to compare

Alternatively, the usage instructions could be displayed.

Lenient comparison between empty and nil arrays in build phases

Describe the bug
When comparing build phases, I believe xcdiff could be more lenient when comparing the arrays of input files. For example, if one project's build phase has nil as inputFileListPaths or outputFileListPaths, and another project has an empty array, it triggers an error in the Build Phases section. Obviously, this is a diff, and if this is a bug or expected behavior is debatable. But in practical terms, they are identical.

To Reproduce
Steps to reproduce the behavior:

  1. Create an Xcode project manually with no inputFileListPaths
  2. Create another project generated by Tuist
  3. xcdiff between the two
  4. See the error below in the screenshot.

Expected behavior
A comparison between nil and empty array should not be considered an error.

Screenshots
EmptyVsNilBuildPhaseInput

Environment (please complete the following information):

  • macOS 10.15

Add app extensions comparator

Is your feature request related to a problem? Please describe.
Mac & iOS Applications may bundle additional extensions (e.g. Today Extension, Action Extension, etc...). Currently xcdiff doesn't compare the bundled extensions for application targets.

Describe the solution you'd like

Add an extensions comparator, or possible a more generalised build phase comparator.

Additional context

A host application for those extensions typically copies them to its Plugins directory within a build phase called "Embed App Extensions".

Settings that appear in only one of the projects should inform their current value

When working with Tuist and using xcdiff to get to the "ideal" Project.swift file, xcdiff is very valuable, especially in the Settings section. Not only xcdiff shows which values differ, but also which values are present only in one of them:

XcdiffSettings

It would be even better for the workflow, if xcdiff also printed the current value after the setting key. In the current workflow, I need to open such project, go to the right target, open the settings tab, look for the key, and then copy the value. Xcdiff has this data easily availble and could print it right away 😄

Extend xcdiff to become a git difftool for Xcode Projects

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

xcdiff can diff two standalone Xcode Projects. An interesting use case that can be extended from this is using xcdiff as a git difftool to allow comparing an Xcode project against itself within source control.

Describe the solution you'd like

There a few bits needed to make this work:

  • Support diffing .pbxproj files directly (not just .xcodeproj)

    • Difftools are passed two files to diff, in for Xcode project files this will be the underlying .pbxproj files
  • Add a new renderer that uses terms like "Removed" / "Added" rather than "Only in first" / "Only in second"

    • Optionally this renderer could use terminal colors, green text for added items, red for removed, yellow for modified
  • Update documentation with instructions on how to add xcdiff as a diff tool

e.g.

git config --local difftool.xcdiff.cmd 'xcdiff -p1 $(dirname "$LOCAL") -p2 $(dirname "$REMOTE") -d -v
git diff --tool xcdiff

There might be a way to make git automatically select a diff tool for certain file extensions which we could leverage as well (needs more research).

Describe alternatives you've considered

Instead of extending xcdiff itself, we can leverage a bash script to marshal the .pbxproj files to the desired format that enables xcdiff to read it.

e.g.

#!/bin/bash
tmp_dir_1="$(mktemp -d -t xcdif)"
cp "$1" $tmp_dir_1/project.pbxproj

tmp_dir_2="$(mktemp -d -t xcdiff)"
cp "$2" $tmp_dir_2/project.pbxproj

xcdiff -p1 "$tmp_dir_1" -p2 "$tmp_dir_2" -d -v

Another alternative could be to add an additional executable target xcgitdiff that manages some of this under the hood and uses a special renderer that is more suitable for this use case.

Additional context

I have a prototype of a custom renderer that replaces terms:

  • "Only in first" > "Removed"
  • "Only in second" > "Added"
  • "Value mismatch" > "Modified" or "Changed"

xcdiff --format git

Not sure how useful this feature is, but posting here to collect ideas and see if there's interest to pursue this further.

Extend dependencies comparator to include target dependencies

Is your feature request related to a problem? Please describe.
The current dependencies comparison highlights differences in linked frameworks however doesn't take into account the target dependencies ("Dependencies" build phase).

Screenshot 2020-01-14 at 10 14 20

Describe the solution you'd like
We can rename the existing "Dependencies" comparator to "Linked Dependencies" and create a new dependencies comparator that compares the "Dependencies" build phase.

Describe alternatives you've considered
An alternate would be to extend the existing dependencies comparator to include differences for the dependencies build phase along side the linked dependencies.

Add install action in Makefile

Is your feature request related to a problem? Please describe.
We don't have an install action in the Makefile.

Describe the solution you'd like
Add an install action to Makefile. This action will create folder and copy the products of the build action so the tool could be installed to usr/local/bin/xcdiff.

Describe alternatives you've considered
Provide package installer on the GitHub repo.

Additional context
This install action will be used by the Homebrew formula to install the tool.

Replace the Swift Package Manager dependency with Swift Tools Support

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

Swift Package Manager is currently used as dependency to leverage some of the components and types within its utility libraries (e.g. ArgumentParser and AbsolutePath).

Recently those utility libraries have been extracted to their own package Swift Tools Support.

Describe the solution you'd like

To reduce the dependency footprint of xcdiff, we can replace the Swift PM dependency with SwiftToolSupport - as it only contains those utilities which xcdiff needs.

Project can't be build using the latest Xcode

Describe the bug
The project doesn't build using the latest Xcode version due to swift-tools-support-core being outdated.

To Reproduce

  • Open project in Xcode or terminal
  • Try to build using xcode or swift build

Expected behavior

  • Project gets build successfully

Screenshots

  • Not applicable

Environment (please complete the following information):

  • Operating System and Version: macOS Ventura 13.1 Beta 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.