-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add PackageIdentity type #3057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PackageIdentity type #3057
Conversation
Rename PackageIdentityTests to LegacyPackageIdentityTests
import TSCBasic | ||
import TSCUtility | ||
|
||
//@warn_unqualified_access |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside: I wish @warn_unqualified_access
was available for top-level variable declarations (not just functions).
This comment has been minimized.
This comment has been minimized.
} | ||
} | ||
|
||
internal protocol PackageIdentityProvider: LosslessStringConvertible { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the identity provider also has to provide equality for package identities, not just an initializer. For the "real" new implementation of identity we will need a staggered comparison that's not just comparing strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we require PackageIdentityProvider
to be Equatable
, then it can only be used as a generic constraint, because it has Self
requirements in ==
. Can you think of a reasonable / non-terrible way to work around this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just add a comparison function that's unrelated to Equatable
. I think what we want to be able to do is compare two PackageIdentity
instances using a comparison operation vended by PackageIdentityProvider
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks great!
I would just make the identity provider a bit more powerful as mentioned.
/// in a process called package resolution. | ||
/// | ||
/// External package dependencies are located by a URL | ||
/// (which may be an implicit `file://` URL in the form of a file path). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this description also mention path-based external dependencies? They do not use file://
, which is only used when the local path contains an actual local Git repository and not just an unversioned package. Or is package identity only a thing for actual remote packages (not root or local)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was trying to get at — my conceit here is that a file path is actually a file:///
URL with an implicit scheme. Any package dependency, local or remote, is described by a URL: local use file:///
URLs and remote use any other scheme. CanonicalPackageIdentity
distinguishes between local from remote by preserving a leading slash (for example, you couldn't shadow a remote URL by having a root directory named /github.com/
). Does that all make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood, but I think that's too subtle and confusing of a way to represent it. And checking the file system for whether a particular path has a .git isn't a good way to do it either. I think there should be a clear way to represent that a package is either an unversioned take-it-as-given path in the file system or a repository that just happens to be in the local file system. Historically there has been value in using no scheme for the former and file: for the latter. I think it would be a mistake to conflate them, even it's through an extra slash character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks great, thanks @mattt
there are two question @abertelrud brought up that should be answered but I hope they are straight forward by exposing the identity on the ref
Right, I don't think they are significant issues (since local packages are supported via scheme-less URLs and are distinct from |
@swift-ci please smoke test |
Distinguish between path and URL initializers at call sites
@abertelrud @tomerd @neonichu Thanks for reviewing my changes. I just pushed 766ea50, which is responsive to this discussion thread. This commit takes the additional step to distinguish between Does this seem like the right change for this PR? |
@swift-ci please smoke test |
Thanks, @mattt! I'll take a look at the new diffs right away, but that sounds like the right API from a client's perspective. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mattt, this looks good to me know. I realize that separate URL and AbsolutePath initializers for package identity are maybe tedious, but I think it will really help clients keep things straight. In one client I worked on, this confusion, where everything was just a string, was a source of at least one bug.
Thanks again for these diffs, @mattt. I'm adapting some of the downstream dependencies to it and will do some testing to avoid regressions. I plan to wrap that up by tonight. Are you OK with holding off until tomorrow to merge? |
Absolutely. Thanks for taking a look at the downstream consumers. Let me know if anything comes up in your review. |
Great, thanks @mattt. The changes that are technically needed to keep compiling turn out to be fairly minimal, and similar to unit test changes in this PR... the later changes to adapt to the change in package identity will be more interesting (but of course very useful!). But that's for after this PR lands. |
@mattt this seems to work fine downstream, after adapting some of the client code. All ready to merge as far as you're concerned? |
@abertelrud I just gave everything another once-over, and I think this is ready to merge. Feel free to do that whenever you're ready. I'd like to continue our conversation from https://github.com/apple/swift-package-manager/pull/3057/files#r525394175, but that's not a blocker here. |
Great, thanks! Merging. |
🥳 🎊 |
* Replace PackageReference.PackageIdentity with top-level PackageIdentity type * Change access level of PackageReference.computeDefaultName to internal * Extract testPackageReference into new PackageIdentityTests file * Allow package identity to be configurable via dependency injection Rename PackageIdentityTests to LegacyPackageIdentityTests * Revert change to access level of computeDefaultName, making it public * Remove LosslessStringConvertible conformance * Add documentation comment for provider type property * Add initializer that takes an AbsolutePath parameter * Remove commented @warn_unqualified_access attribute * Add argument label to public PackageIdentity initializers Distinguish between path and URL initializers at call sites
Motivation:
See #3032
Modifications:
PackageReference.PackageIdentity
with top-levelPackageIdentity
typePackageReference.computeIdentity
to initialization of newPackageIdentity
type.PackageReference.computeDefaultName
tointernal
, limiting its use outside ofPackageModel
module.testPackageReference
into new, separate test case_useLegacyIdentities
variable. This acts as a setter for astatic internal
property onPackageIdentity
that configures how package identity is calculated via dependency injection.Result:
This PR shouldn't affect current behavior. Rather, it serves to codify existing determinations of package identity and to tee up subsequent PRs to accommodate the new package identity semantics required for package registry support.