-
Notifications
You must be signed in to change notification settings - Fork 87
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
Only consider sdks from before the runtime #106
Only consider sdks from before the runtime #106
Conversation
if (!int.TryParse(versionMatch.Groups[1].Value, out int major) || | ||
!int.TryParse(versionMatch.Groups[2].Value, out int minor) || | ||
!int.TryParse(versionMatch.Groups[3].Value, out int patch)) | ||
if (!Version.TryParse(File.ReadAllText(versionPath), out Version version) || version > Environment.Version) |
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.
Environment.Version
is a strange beast. It's always 4.0.30319.42000
for .NET 4.6 and higher and for .NET Core 1.0-3.1. Starting with .NET 5.0, it returns a value more like you'd probably expect: dotnet/coreclr#22664.
FORTUNATELY, since this PR is mostly about blocking out 5.0 versions from 3.1 hosts (since people mostly didn't complain about 3.1 versions for 2.1 hosts) this simple call should still work. And keep working into the future for 6.0/7.0 on 5.0 and so on.
@@ -14,7 +14,6 @@ namespace Microsoft.Build.Locator | |||
internal static class DotNetSdkLocationHelper | |||
{ | |||
private static readonly Regex DotNetBasePathRegex = new Regex("Base Path:(.*)$", RegexOptions.Multiline); | |||
private static readonly Regex VersionRegex = new Regex(@"^(\d+)\.(\d+)\.(\d+)", RegexOptions.Multiline); |
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.
Have you tried your new code against a preview SDK? I think the additional complexity here over just using Version.TryParse
is to handle a semver version like 6.0.100-alpha.234622
.
…front of the list
string parseableVersion = File.ReadAllText(versionPath); | ||
int indexOfHyphen = parseableVersion.IndexOf('-'); | ||
parseableVersion = indexOfHyphen >= 0 ? parseableVersion.Substring(0, indexOfHyphen) : parseableVersion; | ||
if (!Version.TryParse(parseableVersion, out Version version) || version > Environment.Version) |
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 first merge #79 and then move the version filtering to RegisterDefaults
? I.e. the default behavior would be to pick the latest SDK not newer than the currently running runtime but the developer can implement their own policy if they choose so? There are legitimate use cases where the developer wants to know about all instances even if they are not compatible with the current process -- they might want to launch MSBuild out-of-proc for example.
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'd like to get a minimal 5.0 fix out ASAP but I think this is a good way to go long-term.
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 made a change that I think implements this. I tested it with 5.0 and 3.1 runtimes, and they correctly identified 5.0 and 3.1 as the SDKs to use respectively, both ignoring my 2.2 SDK.
…b.com/kurtcodemander/MSBuildLocator into assemblies-older-than-runtime-only
src/MSBuildLocator/MSBuildLocator.cs
Outdated
VisualStudioInstance instance = instances.Where( | ||
inst => inst.Version.Major < Environment.Version.Major || (inst.Version.Major == Environment.Version.Major && inst.Version.Minor <= Environment.Version.Minor) | ||
).FirstOrDefault() ?? | ||
instances.FirstOrDefault(); |
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.
Do you think I should keep this as a fallback? It only ever would return an SDK from after the runtime, but "No instances of MSBuild could be detected" would be misleading. I could also add another error message for "We found MSBuild, but please update the runtime before using it."
src/MSBuildLocator/MSBuildLocator.cs
Outdated
VisualStudioInstance instance = instances.Where( | ||
inst => inst.Version.Major < Environment.Version.Major || (inst.Version.Major == Environment.Version.Major && inst.Version.Minor <= Environment.Version.Minor) | ||
).FirstOrDefault() ?? | ||
instances.FirstOrDefault(); |
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 don't think this filtering makes sense for the .NET Framework/desktop MSBuild/VS case. Instead, it should be restricted to the .NET Core/5.0 case.
@@ -93,7 +93,11 @@ public static IEnumerable<VisualStudioInstance> QueryVisualStudioInstances() | |||
/// <returns>Instance of Visual Studio found and registered.</returns> | |||
public static VisualStudioInstance RegisterDefaults() |
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.
Why does RegisterDefaults
need to change at all? I would expect the change to be entirely in the list returned by GetInstances
. I can see from the commit history that you implemented it that way and then changed it, but not why.
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 was trying to implement #106 (comment)
Is that wrong?
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.
Ah. Yes, I now think it's not the right design. We could potentially add another overload that takes a bool to "give me everything, I don't care" but I don't think we should filter in RegisterDefaults and I do think we should present only usable instances in the list by default.
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.
Reverted to filtering in DotNetSdkLocationHelper.cs.
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 a little resistant to add an overload for "give me everything" without anyone explicitly asking for it. I'm guessing most people who use MSBuildLocator use it for relatively straightforward purposes, and it would make it a little harder to pull in my unit testing PR when that comes along.
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.
How would this affect a unit testing PR?
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.
Two reasons: it would add something else I'd probably want to test, and since I'm already planning to add an overload to this, I'd have to split my overload into "give me everything" and "don't give me everything" cases. Not a huge deal, though.
} | ||
|
||
if (!int.TryParse(versionMatch.Groups[1].Value, out int major) || | ||
if (!versionMatch.Success || |
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 prefer the original flow here because the failure conditions are much more obvious in separate if
s:
- The version regex didn't match.
- We can't parse a version out.
- the version doesn't match
Here all together it's hard to see that there are separate failure cases.
major > Environment.Version.Major || | ||
(major == Environment.Version.Major && minor > Environment.Version.Minor)) |
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 definitely needs a comment! Describe all the things you've learned about why we care about the current runtime version relative to the SDK version, and the SDK policy as we currently understand it.
@@ -93,7 +93,11 @@ public static IEnumerable<VisualStudioInstance> QueryVisualStudioInstances() | |||
/// <returns>Instance of Visual Studio found and registered.</returns> | |||
public static VisualStudioInstance RegisterDefaults() |
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.
How would this affect a unit testing PR?
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.
LGTM. Let's get it out!
|
||
// Components of the SDK often have dependencies on the runtime they shipped with, including that several tasks that shipped | ||
// in the .NET 5 SDK rely on the .NET 5.0 runtime. Assuming the runtime that shipped with a particular SDK has the same version, | ||
// this ensures that we don't choose an SDK that doesn't work with the chosen runtime. This is not guaranteed to always work but |
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 ensures that we don't choose an SDK that doesn't work with the chosen runtime. This is not guaranteed to always work but | |
// this ensures that we don't choose an SDK that doesn't work with the runtime of the current application. This is not guaranteed to always work but |
?
Suggestion from @rainersigwald
Fixes #92
This is now based on #79.