Skip to content

identity improvements #3323

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

Merged
merged 4 commits into from
Mar 10, 2021
Merged

identity improvements #3323

merged 4 commits into from
Mar 10, 2021

Conversation

tomerd
Copy link
Contributor

@tomerd tomerd commented Mar 5, 2021

motivation: improve correctness by using identity more broadly throughout the codebase

changes:

  • expose identity on Package, ResolvedPackage and GraphLoadingNode
  • reduce calls to identityResolver.resolveIdentity since we now have identity more broadly available (also improves performance)
  • ManifestLoader now take PackageIdentity to reduce calls to identityResolver.resolveIdentity when the identity is already known
  • introduce PackageIdentity.root as a utility for root packages, since their identity is straight-forward
  • adjust call-sites
  • adjust tests

@tomerd tomerd marked this pull request as draft March 5, 2021 07:33
@tomerd tomerd force-pushed the refactor/identity-04 branch 3 times, most recently from 6f8717c to fe396d1 Compare March 6, 2021 04:46
@tomerd
Copy link
Contributor Author

tomerd commented Mar 6, 2021

@swift-ci please smoke test

@tomerd tomerd self-assigned this Mar 6, 2021
@tomerd tomerd added the ready Author believes the PR is ready to be merged & any feedback has been addressed label Mar 6, 2021
@tomerd tomerd marked this pull request as ready for review March 6, 2021 04:47
@tomerd
Copy link
Contributor Author

tomerd commented Mar 6, 2021

@swift-ci please smoke test

Copy link
Contributor

@abertelrud abertelrud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! I think we'll have a lot of cases where we'll need to present the identity to the user, which means we'll probably want to get rid of the name in the manifest to reduce ambiguity. Will it be readable enough to use in schemes etc though?

@@ -55,7 +55,7 @@ fileprivate struct DescribedPackage: Encodable {
let swiftLanguagesVersions: [String]?

init(from package: Package) {
self.name = package.name
self.name = package.manifestName // TODO: rename property to manifestName?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about that — it doesn't seem clear to end users if there is both a package name and a manifest name. Or am I misunderstanding the question?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, per the comment below, maybe this should be the identity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -582,7 +591,7 @@ extension SwiftPackageTool {
destination = output
} else {
let graph = try swiftTool.loadPackageGraph()
let packageName = graph.rootPackages[0].name
let packageName = graph.rootPackages[0].manifestName // TODO: use identity instead?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This depends on what we want to do with name moving forward. If identity is an opaque string, it might make sense to have a canonical display form of it. Or should this intentionally be exactly the same string as one would put in the manifest when specifying the package in the registry?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the other changes here, it seems that we'll need to use the identity string instead of the name (which isn't necessarily wrong). That might be a good thing to move to across-the-board. I wonder if IDEs should also show that in their user interface — there has been this unfortunate ambiguity between the name of the package directory vs the name declared in the manifest.

I had been thinking of the identity as opaque but it probably is the right thing to use in diagnostics and descriptions after all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried to keep the changes to behavior minimal in this PR -- a follow up PR to clean up the remain usage of manifestName and eventually remove name from the manifest are next on my list

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds great! Thanks for taking this on!

@@ -360,7 +372,7 @@ public struct SwiftTestTool: SwiftCommand {
// Export the codecov data as JSON.
let jsonPath = codeCovAsJSONPath(
buildParameters: buildParameters,
packageName: product.packageName)
packageName: rootManifest.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would then presumably also be the identity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let rootManifestsMap = root.packages.mapValues { $0.manifest }
let externalManifestsMap = externalManifests.map{ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) }
let manifestMap = rootManifestsMap.merging(externalManifestsMap, uniquingKeysWith: { lhs, rhs in
return rhs // 👀 this was not possible before (the dictionary creation would crash), is preferring external correct?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that preferring roots over externals would be preferable, since that would preserve the current overriding semantics.

Copy link
Contributor Author

@tomerd tomerd Mar 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to lhs

self.manifests = manifests
public init(input: PackageGraphRootInput, manifests: [Manifest], explicitProduct: String? = nil) throws {
self.packages = try input.packages.reduce(into: .init(), { partial, inputPath in
let manifestPath = inputPath.basename == Manifest.filename ? inputPath : inputPath.appending(component: Manifest.filename)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to take into account versioned package manifests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is mostly in place for testing -- some test pass the full manifest path and some just the directory. I would like to remove this crutch and clean up the tests

@@ -17,19 +17,31 @@ public final class ResolvedPackage: ObjectIdentifierProtocol {
/// The underlying package reference.
public let underlyingPackage: Package

// The identity of the package.
public var identity: PackageIdentity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay! This is going to help higher-level code a lot!


/// The name of the package as entered in the manifest.
/// This should rarely be used beyond presentation purposes
public var manifestName: String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something we'll be able to move toward getting rid of once we have a strong notion of identity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private func diagnosticLocation() -> DiagnosticLocation {
return PackageLocation.Local(name: manifest.name, packagePath: packagePath)
private var diagnosticLocation: DiagnosticLocation {
return PackageLocation.Local(name: self.manifest.name, packagePath: self.packagePath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually we probably want the identity in the diagnostic, but that can be a future change.

@@ -61,7 +61,7 @@ extension PackageGraph {
var evalResults: [PluginInvocationResult] = []
for pluginTarget in pluginTargets {
// Give each invocation of an extension a separate output directory.
let extOutputDir = outputDir.appending(components: package.name, target.name, pluginTarget.name)
let extOutputDir = outputDir.appending(components: package.manifestName, target.name, pluginTarget.name) // TODO: use identity instead?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think this should be identity.

@@ -86,7 +86,7 @@ public final class SchemesGenerator {
}
})
schemes.append(Scheme(
name: rootPackage.name + "-Package",
name: rootPackage.manifestName + "-Package", // TODO: use identity instead?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, probably everywhere name is used we should start using identity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomerd
Copy link
Contributor Author

tomerd commented Mar 7, 2021

I think we'll have a lot of cases where we'll need to present the identity to the user, which means we'll probably want to get rid of the name in the manifest to reduce ambiguity. Will it be readable enough to use in schemes etc though?

This is a good point @abertelrud, in this PR tried to keep things mostly the same on that regards with a few exceptions to diagnostics about dependencies.

in general, i think there are two main cases to consider in this context given the current state of things:

  1. the display name of the dependencies, where imo using the dependency's identity makes more sense than using it's manifest name, given that the user is exposed to the former and not to the latter.
  2. the display name of the "root" package (ie the one the user is working on) in which the manifest name makes more sense (if/while we keep that manifest attribute) given that the package identity is fairly arbitrary (directory name).

i do think we should seriously consider removing the name attribute from the manifest, but we will need to come up with something better for root package identity than the directory name. there is also the concept of multiple root packages we need to consider in this context which we may want to address differently than how its done today

@tomerd tomerd force-pushed the refactor/identity-04 branch from ebdd69a to 89e801c Compare March 8, 2021 23:56
@tomerd
Copy link
Contributor Author

tomerd commented Mar 8, 2021

@swift-ci please smoke test

tomerd added 4 commits March 8, 2021 17:40
motivation: improve correctness by using identity more broadly throughout the codebase

changes:
* expose identity on Package, ResolvedPackage and GraphLoadingNode
* reduce calls to identityResolver.resolveIdentity since we now have identity more broadly available (also improves performance)
* ManifestLoader now take PackageIdentity to reduce calls to identityResolver.resolveIdentity when the identity is already known
* introduce PackageIdentity.root as a utility for root packages, since their identity is straight-forward
* adjust call-sites
* adjust tests
@tomerd tomerd force-pushed the refactor/identity-04 branch from 89e801c to a253072 Compare March 9, 2021 01:40
@tomerd
Copy link
Contributor Author

tomerd commented Mar 9, 2021

@swift-ci please smoke test

2 similar comments
@tomerd
Copy link
Contributor Author

tomerd commented Mar 9, 2021

@swift-ci please smoke test

@tomerd
Copy link
Contributor Author

tomerd commented Mar 9, 2021

@swift-ci please smoke test

@tomerd
Copy link
Contributor Author

tomerd commented Mar 9, 2021

@swift-ci please smoke test linux

@tomerd tomerd merged commit 953f368 into swiftlang:main Mar 10, 2021
tomerd added a commit that referenced this pull request Mar 10, 2021
abertelrud pushed a commit that referenced this pull request Mar 10, 2021
tomerd added a commit that referenced this pull request Mar 10, 2021
tomerd added a commit that referenced this pull request Mar 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready Author believes the PR is ready to be merged & any feedback has been addressed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants