-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Manifest source generation should encode platform versions using their symbolic forms when possible #3707
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
base: main
Are you sure you want to change the base?
Manifest source generation should encode platform versions using their symbolic forms when possible #3707
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,22 +100,32 @@ fileprivate extension SourceCodeFragment { | |
|
||
/// Instantiates a SourceCodeFragment to represent a single platform. | ||
init(from platform: PlatformDescription) { | ||
// NOTE: This could be cleaned up to use the nicer version accessors. | ||
switch platform.platformName { | ||
case "macos": | ||
self.init(enum: "macOS", string: platform.version) | ||
case "maccatalyst": | ||
self.init(enum: "macCatalyst", string: platform.version) | ||
case "ios": | ||
self.init(enum: "iOS", string: platform.version) | ||
case "tvos": | ||
self.init(enum: "tvOS", string: platform.version) | ||
case "watchos": | ||
self.init(enum: "watchOS", string: platform.version) | ||
case "driverkit": | ||
self.init(enum: "DriverKit", string: platform.version) | ||
default: | ||
self.init(enum: platform.platformName, string: platform.version) | ||
// Provides knowledge about what the current version of PackageDescription provides. | ||
struct PlatformManifestRepresentation { | ||
var manifestName: String | ||
var knownVersions: Set<String> | ||
} | ||
let platformManifestReps = [ | ||
"macos": PlatformManifestRepresentation(manifestName: "macOS", knownVersions: ["10.10", "10.11", "10.12", "10.13", "10.14", "10.15", "11", "12"]), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually had it that way to start with but I dislike having to add a type to the collection more than I do spelling out the type. But I can change it, I don't feel superstrongly. |
||
"maccatalyst": PlatformManifestRepresentation(manifestName: "macCatalyst", knownVersions: ["13", "14", "15"]), | ||
"ios": PlatformManifestRepresentation(manifestName: "iOS", knownVersions: ["8", "9", "10", "11", "12", "13", "14", "15"]), | ||
"tvos": PlatformManifestRepresentation(manifestName: "tvOS", knownVersions: ["9", "10", "11", "12", "13", "14", "15"]), | ||
"watchos": PlatformManifestRepresentation(manifestName: "watchOS", knownVersions: ["2", "3", "4", "5", "6", "7", "8"]), | ||
"driverkit": PlatformManifestRepresentation(manifestName: "driverKit", knownVersions: ["19", "20", "21"]), | ||
] | ||
|
||
// See if we have a versioned platform manifest representation for this platform. | ||
if let platformManifestRep = platformManifestReps[platform.platformName] { | ||
let simplifiedVersion = platform.version.spm_dropSuffix(".0") | ||
let versionSubnode = platformManifestRep.knownVersions.contains(simplifiedVersion) | ||
? SourceCodeFragment(enum: "v" + simplifiedVersion.replacingOccurrences(of: ".", with: "_")) | ||
: SourceCodeFragment(string: platform.version) | ||
self.init(enum: platformManifestRep.manifestName, subnodes: [versionSubnode]) | ||
} | ||
else { | ||
// We don't have a versioned platform, so emit the platform without version numbers. But in debug builds we assert. | ||
assert(false, "unhandled plaform \(platform.platformName) in manifest source generation") | ||
self.init(enum: platform.platformName) | ||
} | ||
} | ||
|
||
|
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.
is this information not also found anywhere else? does it make sense to make it more generally available?
Uh oh!
There was an error while loading. Please reload this page.
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.
Unfortunately it isn't. There is no sharing of state today between what is defined in PackageDescription and what libSwiftPM knows to be defined in PackageDescription.
There are a lot of cases where this would be useful, in particular to share the Codable struct definitions for the stuff that is gets as JSON from the PackageDescription library to SwiftPM proper. Perhaps the best way would be to be able to share source files between PackageDescription and PackageModel, and have the same types be available in both. In that case there might be some kind of a runtime CaseIterable thing that we could do here.
There's no doubt that this is a really unfortunate thing to have to have here. I hope that if we have good mechanical editing we might perhaps be able to sunset the source generation in the future, though that's not imminent.
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.
But to your point, I think perhaps we can figure out something involving a custom source path that reaches into PackageDescription and includes one of its source files where the types are defined. That would be generally useful and maybe this is a good time to spend that effort rather than add more data like 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.
side note: today we don't allow overlapping source files between targets (but IIRC it's a restriction we have previously talked about lifting), so we would likely need to use symlinks for now
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 see — I thought
sources
allowed it and it was just targets directories that couldn't intersect (thepath
parameter). There seem to be some rather arbitrary rules for what can and cannot be in a target, and I think SwiftPM would do well to relax them. That's obvious a separate discussion.I'll see what I can do with a symlink here.