FelixHerrmann / swift-package-list

A command-line tool to get all used SPM-dependencies of an Xcode project or workspace.
MIT License
120 stars 16 forks source link

Package identity in name field #117

Open martinK-7 opened 3 weeks ago

martinK-7 commented 3 weeks ago

Hey, first thanks for creating this great tool!

We are using it in our pipelines to generate license information for the packages of our Xcode project. We noticed that sometimes it happens that the package identity is also in the generated name field which leads to non-user-friendly outputs. For example the json output for abseil:

{
    "identity" : "abseil-cpp-binary",
    "license" : "...",
    "name" : "abseil-cpp-binary",
    "repositoryURL" : "https:\/\/github.com\/google\/abseil-cpp-binary.git",
    "revision" : "748c7837511d0e6a507737353af268484e1745e2",
    "version" : "1.2024011601.1"
  }

Name should actually be "abseil" here.

As I understood, you get this information from "workspace-state" in derivedData. There it also looks like this:

{
        "basedOn" : null,
        "packageRef" : {
          "identity" : "abseil-cpp-binary",
          "kind" : "remoteSourceControl",
          "location" : "https://github.com/google/abseil-cpp-binary.git",
          "name" : "abseil-cpp-binary"
        },
        "state" : {
          "checkoutState" : {
            "revision" : "748c7837511d0e6a507737353af268484e1745e2",
            "version" : "1.2024011601.1"
          },
          "name" : "sourceControlCheckout"
        },
        "subpath" : "abseil-cpp-binary"
      },

It seems like an issue with Xcode itself, unfortunately I cannot really tell how to reproduce it. We found that in our case it happens only when originHash in Package.resolved changes, for example after updating some package. After reverting only the change in the hash it starts working as expected again (🤷).

To avoid these random Xcode issues, would it be an option to get package names directly from "Package.swift" in checkouts? Or maybe you have some other ideas.

Setup: Xcode 15.4 swift-package-list 4.1.0 Input Parameters: .../x.xcworkspace --output-path '.' --custom-file-name 'tmpDeps' --output-type 'json' --custom-derived-data-path '/Users/x/Library/Developer/Xcode/DerivedData'

Please let me know if you need more information. Thanks in advance.

FelixHerrmann commented 3 weeks ago

Hey, thanks for reaching out! If you say pipeline does it mean you only experience this during a CI job? I feel like it could have something to do with timing, so when it is invoked during your build process. The not so user-friendly repo-name is the fallback until the dependency is fully fetched and loaded, see swift-package-manager for reference; you can actually see that happening in Xcode when SPM is in progress.

To avoid these random Xcode issues, would it be an option to get package names directly from "Package.swift" in checkouts? Or maybe you have some other ideas.

I've intentionally avoided that in #72 because this either requires a error-prone string lookup or an actual compilation step of the Package.swift which also requires the PackageDescription module from https://github.com/apple/swift-package-manager.

martinK-7 commented 3 weeks ago

Thanks for the detailed answer.

If you say pipeline does it mean you only experience this during a CI job? I feel like it could have something to do with timing, so when it is invoked during your build process.

We are only using your tool in our CI jobs, so usually we don't check the "workspace-state" file. What happens on CI is that the repo is checked-out from scratch and we build the project using gym (xcodebuild). After that, we run swift-package-list. I tried that flow locally and it leads to the same issue. From that point, I could not find a way to recover it, even opening Xcode does not change anything.

I could also reproduce it with a test package. If you want to try it, you can find it here: https://github.com/martinK-7/PackageDependenciesTest My steps were basically:

It actually also happens when you open the Package with Xcode and wait for packages to be resolved. It seems, Xcode only generates this file properly if you change dependencies while having it opened. I tried with different packages as well. On our CI, sometimes it works just fine, unfortunately I cannot tell in which exact cases.

FelixHerrmann commented 3 weeks ago

Thanks for all the details, that is very helpful. I could produce it with the xcodebuild CLI on my side too, will do a more detailed investigation when I find some time!