Support for rewriting package urls?

Hi,
I am working for government and we cannot use GitHub. In order to use SPM I wrote a script that mirrors git repositories from GitHub into our internal bitbucket server. There, I can only use a single space "Vendors" so I have to change the name from i.e. "apple/swift-syntax" to "Vendor/apple.swift-syntax".

While this works for a single package, it won't work for dependencies. I found no way to add some kind of rewrite mechanism to SPM so the next best thing was for me to rewrite the git repositories (EXT -> rewrite -> INT-READONLY). While this works it is very cumbersome and I have to constantly update my binary project that does the rewriting. At least I found a reasonable approach by appending some swift code to the end of each Package*.swift file in each commit in each branch of a repository.

The question I have is:

  • Am I missing something here? Is there a way to use Xcode, or swift package on a development machine that has no access to the internet?

  • If not, what is the best way to suggest a feature request and to whom should I send it?

Thanks
Andreas Pardeike
Swedish Police IT Department

1 Like

I haven’t used it personally, but I believe SPM’s dependency mirroring will accomplish what you’re looking for.

It is my understanding that this works on the package level only. How would I tell our app developers to use a common package (like pointfreeco/swift-composable-architecture) in their Xcode projects?

Again, without having ever actually used the feature, I believe the workflow looks like:

  1. You mirror https://github.com/pointfreeco/swift-composable-architecture to, say, https://internal-bitbucket-server/pointfreeco-swift-composable-architecture
  2. Your developer runs the following command on their workstation (probably as part of a setup script for the app):
swift package config set-mirror \
    --package-url https://github.com/pointfreeco/swift-composable-architecture \
    --mirror-url https://internal-bitbucket-server/pointfreeco-swift-composable-architecture
  1. Your developers add https://github.com/pointfreeco/swift-composable-architecture to their Package.swift like normal
  2. When they build their app, Xcode/SPM instead reach out to https://internal-bitbucket-server/pointfreeco-swift-composable-architecture

Note that you'll also have to repeat steps 1 and 2 for every single dependency for https://github.com/pointfreeco/swift-composable-architecture, but the mirroring configuration is on the top level for the app they're building and should apply to all parts of the builds kicked off from that context.

As I said earlier, this only works if you use SPM. When running swift package config set-mirror it will tell you:

error: Could not find Package.swift in this directory or any of its parent directories

which is to be expected since a normal Xcode project does not have a Package.swift.

This is difficult, as Xcode doesn't support mirroring. You'll need to break all of your app's dependencies into a separate Package.swift and then use that file as a package in your app. You'd do all the mirroring in that file.

This is trivial in VSCode.

It does, but not in a very user friendly way.

If you place a mirror config in xcshareddata/swiftpm/configuration of the project/workspace in use, it'll be picked up and applied by libSwiftPM. This should work in pretty much any Xcode version for any dependency declared by a package, so any transitive dependencies.

There was an issue applying them to dependencies declared in Xcode projects specifically which has been fixed a few months ago in https://github.com/apple/swift-package-manager/pull/6765, but I am not 100% sure if that has made it into any Xcode releases, yet.

1 Like

This here is the information I was looking for. Thank you, I will try to write some helper binary/script that makes it easier is necessary.

I’ll see if this way actually works.

Btw this stackoverflow topic adds some more information to the details: xcode - Check in xcworkspace for swiftpm to git? - Stack Overflow

Hi again,
I now had time to test this but I cannot get it to work. Here is what I tried so far: created a new spm package and added the mirror there, in this case using GitHub - apple/swift-argument-parser: Straightforward, type-safe argument parsing for Swift

I then created a new app project in Xcode and copied mirrors.json from the spm package over, resulting in this file structure:

β”œβ”€β”€ test
β”‚   β”œβ”€β”€ Assets.xcassets
β”‚   β”‚   └── Contents.json
β”‚   β”œβ”€β”€ ContentView.swift
β”‚   β”œβ”€β”€ Preview Content
β”‚   β”‚   └── Preview Assets.xcassets
β”‚   β”‚       └── Contents.json
β”‚   └── testApp.swift
└── test.xcodeproj
    β”œβ”€β”€ project.pbxproj
    β”œβ”€β”€ project.xcworkspace
    β”‚   β”œβ”€β”€ contents.xcworkspacedata
    β”‚   β”œβ”€β”€ xcshareddata
    β”‚   β”‚   β”œβ”€β”€ IDEWorkspaceChecks.plist
    β”‚   β”‚   └── swiftpm
    β”‚   β”‚       └── configuration
    β”‚   β”‚           └── mirrors.json
    β”‚   └── xcuserdata
    β”‚       └── u0035718.xcuserdatad
    β”‚           └── UserInterfaceState.xcuserstate
    └── xcuserdata
        └── u0035718.xcuserdatad
            └── xcschemes
                └── xcschememanagement.plist

I then opened the Xcode project and used File > Add Package Dependencies... to add https://github.com/apple/swift-argument-parser.git but Xcode just asks me to log into GitHub (which via a proxy will fail). So it looks like the mirror is not used.

In contrast, if I go into Package.swift in the spm package project and add the dependency to https://github.com/apple/swift-argument-parser.git then it will successfully use our internal mirror from the command line:

> swift package update
Fetching ssh://git@internal.bitbucket.redacted.se:1234/vendor/apple.swift-argument-parser.git from cache

but not if I use Xcode to edit Package.swift:

Conclusion: To me this still looks like Xcode does its very own thing and I cannot use mirroring to solve my proxy problem.

1 Like

Note the second part of the answer:

2 Likes