URLs as Swift Package Identifiers

@johannesweiss @tachyonics I think you both identify some important points. However, we appear to be reaching different conclusions, and I'm not sure if it's due to disagreement or misunderstanding on one or more points.

To help identify where we disagree, here's my understanding of your concerns and my responses to them. Please tell me if I've mischaracterized your positions or if you have any objections / questions to my points:

"What if a mirror redirects github.com to mailicio.us?"

Swift Package Manager lets you override the location of packages with mirrors (SE-0219). This allows developers to point external dependencies to forks across the dependency graph. As you've identified, the trade-off is that it introduces context for understanding where a dependency is located.

Our proposal associates SHA256 checksums to versioned source archives in Package.resolved. If you do a fresh build of your project (such as in a CI) and a host tries to send you something else, Swift Package Manager would raise an error. This is an improvement over current behavior, which can't protect against external dependency code changing over time (whether because it's hosted elsewhere, or the version was re-tagged in the original repository).

As we write in the Security section of our proposal, and previously discussed in a separate thread:

Package.resolved provides a Trust on first use (TOFU) security model that can offer strong guarantees about the integrity of dependencies over time. A registry can further improve on this model by implementing a transparent log or some comparable, tamper-proof system for associating artifacts with valid checksums.

As I said in a previous reply, tooling — whether that's a new subcommand or making the output of build and resolve more verbose — could go a long way to helping us understand what's being downloaded from where.

"What if I'm on a corporate network and can't access the Internet?"

We've pitched an enhancement that allows users to configure an intermediate registry proxy. Whereas a mirror lets you redirect a single dependency, an intermediate proxy would route all packages directly. A corporate CI server, for example, could configure an intermediate proxy to an internal package registry to serve cached versions of external packages.

If you're concerned about downloading code at all as part of the build process, the alternative is to vendor all of your external dependencies. This is currently a manual process, but we could add functionality to do this automatically (for example, a swift package vendor subcommand that resolves and downloads dependencies to Vendor/Sources/ and rewrites Package.swift to declare dependencies using local paths).

"Why github.com/mona/LinkedList and not 'mona/Linked, hosted on GitHub?'"

For example, what @tachyonics described as:

It's tempting to treat GitHub and GitLab as interchangeable, but they're not. To use an analogy: we can't assume mona/LinkedList is the same on GitHub and GitLab, much the same as we can't assume that @mona on Twitter is the same person on Instagram. (To extend the analogy: our proposal is more like Mastodon than Twitter)

Packaging systems in other languages demonstrate that there's more than one way to solve the problem of external dependency resolution. A lot of things would be easier if all identifiers went through a central registry, but that's not how things work currently, and I don't think that's how things should work going forward. The decisions we made in our proposal were informed by facts specific to Swift and Swift Package Manager; given an alternative set of requirements, we might make different decisions.

Or, as @Jon_Shier put it:

4 Likes