-
Notifications
You must be signed in to change notification settings - Fork 402
Add SDK version utilities and GlobalJson parsing #2550
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?
Conversation
Add new utilities for SDK version parsing and comparison: - parseSdkVersion: Parse SDK version string into components - isCompatibleSdkVersion: Check version compatibility with rollForward policy - getCompatibleSdkVersions: Filter versions by compatibility - compareSdkVersions: Compare two SDK versions - isNewerSdkVersion: Check if one version is newer than another - isValidNumber: Exported helper for number validation Add GlobalJson parsing utilities: - GlobalJson, GlobalJsonSdk, GlobalJsonRequirements interfaces - parseGlobalJsonContent: Parse global.json content - getRequirementsFromGlobalJson: Extract SDK requirements - parseGlobalJsonRequirements: Combined parse and extract - getEffectiveRollForward: Get effective roll-forward policy - getEffectiveAllowPrerelease: Get effective prerelease setting Register VS Code commands for external extension consumption: - dotnet.parseSdkVersion - dotnet.isCompatibleSdkVersion - dotnet.getCompatibleSdkVersions - dotnet.compareSdkVersions - dotnet.isNewerSdkVersion - dotnet.parseGlobalJson Add unit tests for all new SDK version utilities.
| return requirements.rollForward; | ||
| } | ||
| // Default is 'latestPatch' when version is specified, 'latestMajor' otherwise | ||
| return requirements.sdkVersion ? 'latestPatch' : 'latestMajor'; |
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 we support more than latestPatch and latestMajor?
| return requirements.rollForward; | ||
| } | ||
| // Default is 'latestPatch' when version is specified, 'latestMajor' otherwise | ||
| return requirements.sdkVersion ? 'latestPatch' : 'latestMajor'; |
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'm wondering if we should store these as static constant strings instead of having them coded here.
| test('parseSdkVersion parses SDK versions correctly', async () => | ||
| { | ||
| const v1 = resolver.parseSdkVersion('8.0.308'); | ||
| assert.equal(v1.major, 8); |
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 like the conciseness of the tests here!
| * @param rollForward The rollForward policy (defaults to 'latestPatch' if not specified) | ||
| * @returns true if the installed SDK satisfies the requirement | ||
| */ | ||
| export function isCompatibleSdkVersion(installedVersion: string, requiredVersion: string, rollForward: RollForwardPolicy = 'latestPatch'): boolean |
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.
stringVersionMeetsRequirement already exists as a method to compare strings against rollforward values. Perhaps it should be moved here and utilized as such.
| * The rollForward policy from global.json that determines SDK version selection behavior. | ||
| * Reference: https://learn.microsoft.com/en-us/dotnet/core/tools/global-json | ||
| */ | ||
| export type RollForwardPolicy = 'disable' | 'patch' | 'latestPatch' | 'feature' | 'latestFeature' | 'minor' | 'latestMinor' | 'major' | 'latestMajor'; |
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 like the docstring here and the name makes more sense to me, but these exist to some degree already in simplifiedVersionSpec - we should consolidate them.
| * @param version The SDK version string | ||
| * @returns Parsed version components | ||
| */ | ||
| export function parseSdkVersion(version: string): ParsedSdkVersion |
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 this is a clean approach to have a class like this but it is not the most performant approach since it parses many parts multiple times. The logic that compares versions already in the code short-circuits the evaluations of the string and prevents duplicated splits.
| * Gets the full patch field from an SDK version string (e.g., 308 from "8.0.308"). | ||
| * @returns The full patch number, or undefined if it cannot be extracted | ||
| */ | ||
| function getFullPatchFromVersionSimple(version: string): number | undefined |
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 seems similar to getSDKFeatureBandOrPatchFromFullySpecifiedVersion (albeit a less verbose name) - I'm thinking many of these functions are not necessary.
| open(url).catch(() => {}); | ||
| }); | ||
|
|
||
| const compareSdkVersionsRegistration = vscode.commands.registerCommand(`${commandPrefix}.${commandKeys.compareSdkVersions}`, |
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.
The most important feedback I have here:
I think it's wise for this logic to live here, and we shouldn't reimplement what's done in recommendedVersion and listVersions. Although I think the overhead of the vscode command calls is quite high. The fact that the codebase parses versions as strings instead of a type is definitely a regret and hard to change from the initial design, which is why we haven't replaced it with something like semver. For new code, this makes me think the version parsing/compare could live in CDK instead if there was a smarter type around it, for the sake of not repeating a bad pattern.
If we continue with this, really the best approach would be for some of the version utilities ( and our types) to be put on npm as a library dependency, considering there's no shared caching/persistent data. I have avoided doing that as there's never been a big drive to do so - (although it hurts seeing others have to copy our type files instead of using @types/.)
I understand doing so would:
A - create a new work item
B - create a new maintenance point (which we could hopefully automate the release of alongside new extension releases)
C - delay the progress of your feature
I'm curious on your opinion w.r.t this - it may be best to have it live in CDK for now.
Add new utilities for SDK version parsing and comparison:
Add GlobalJson parsing utilities:
Register VS Code commands for external extension consumption:
Add unit tests for all new SDK version utilities.