Skip to content

Conversation

@nagilson
Copy link
Member

@nagilson nagilson commented Sep 18, 2024

Helps resolve:
microsoft/vscode-dotnettools#1466
microsoft/vscode-dotnettools#1243
microsoft/vscode-dotnettools#1094

(CDK and C# will need to adopt this API.)

Adds the command dotnet.findPath to return the path to a dotnet executable or dotnet file to run that is set on the system. This will only be returned if it meets the requirement. This API is meant to search for machine install or runtimes set via environment variables such as PATH or DOTNET_ROOT.

This API takes in a IDotnetFindPathContext which has an Acquire Context. This allows us to edit this API without having to change the acquire API, which uses the IDotnetAcquireContext. This has-a approach is very common in .js.

Callers will add the 'requirement' which allows a .NET version that is 'greater_than_or_equal', 'equal', or 'less_than_or_equal' for major.minor versions that they request.

Here is the algorithm / control flow for the PATH lookup that we decided on with partners. Hopefully this helps explain the code behavior and what it should do.

This will also fix the issue where the vscode path setting dotnet.existingDotnetPath is used by the extensions which will call into this API as they previously had their own path lookup logic which ignored our setting.

image

  • The architecture search is not implemented any longer because it is not possible to do it correctly with the existing dotnet host information. We will need to talk to them about this.

I've tested this with various installs, such as snap installs. These installs have a 'polymorphic executable', which means the realpath of which dotnet is actually the snap executable, so the realpath doesn't work. However, there are installs such as the microsoft packages install which installs a symlink path, and that path doesn't work until the realpath is called. This is why we have various path lookup mechanisms, as various installs use different mechanisms.

nagilson and others added 27 commits September 10, 2024 16:42
…d installation docs, and only in the last resort mention PATH munging.
C# DevKit never uses the path returned by our installation. This means users would think this path would change the sdk that this extension uses but that is not the case. This path to dotnet.exe is meant to be the path for the runtime for extensions to run on, and not the SDK path. It's confusing that the setting was used for both and a misstep in a way. DevKit is the main caller of this API so we think we can change this with minimal breakage.
The setting must be accessed earlier. This means vscode will need to be restarted. We also update the readme and messaging a bit so its more publicly clear in all places what the setting is for.
dotnet --list-runtimes and more need to be called in more places. This is a separate task so it should be done. I did not change the code in any way except for adding the requirement clause type.
@nagilson nagilson requested a review from a team September 27, 2024 17:40
private async getHostArchitecture(hostPath : string) : Promise<string>
{
return '';
/* The host architecture can be inaccurate. Imagine a local runtime install with no host. There is no way to tell the architecture of that runtime,
Copy link
Member

Choose a reason for hiding this comment

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

the host is always included with the runtime, doesn't that make the installation incomplete and therefore invalid?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's true, this comment (the one in the code) is wrong. However, the host can be there but not return an architecture if it's just a local runtime and a host. I should update this comment.

@joeloff
Copy link
Member

joeloff commented Sep 27, 2024

You could probably read the machine type information from the host (COFF or ELF depending on the OS). For the runtimes themselves, reading the COFF header of the DLLs should be sufficient.

I wouldn't use the .version file because not everyone writes the same information. Microsoft.NETCore.App doesn't write architecture information, but the SDK does, so it's not reliable

@nagilson
Copy link
Member Author

The architecture suggestion is a good one -- we should add this in the next release along with improvements to parsing the PATH with chinese characters due to a nodejs bug.

Resolves dotnet#1958

The old application insights key was created by @LakshanF, when we migrated to the new vscode-extension-telemetry service, their API had a breaking change to require a connection string instead of an insights key. dotnet#1948

The connection key can be public and is hard coded. Our existing key has been in our open source, source code for many years. Here is what their guidance says: https://www.npmjs.com/package/@vscode/extension-telemetry

> Follow guide to set up Application Insights in Azure and get your connection string. Don't worry about hardcoding it, it is not sensitive.
Comment on lines 196 to 198
placeHolder: '8.0',
value: '8.0',
prompt: 'The .NET runtime version.',
Copy link
Member

Choose a reason for hiding this comment

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

nit: extra indentation

Comment on lines 481 to 501
const dotnetsOnPATH = await finder.findRawPathEnvironmentSetting();
for(const dotnetPath of dotnetsOnPATH ?? [])
{
const validatedPATH = await getPathIfValid(dotnetPath, validator, commandContext);
if(validatedPATH)
{
outputChannel.show(true);
return validatedPATH;
}
}

const dotnetOnRealPATH = await finder.findRealPathEnvironmentSetting();
for(const dotnetPath of dotnetsOnPATH ?? [])
{
const validatedRealPATH = await getPathIfValid(dotnetPath, validator, commandContext);
if(validatedRealPATH)
{
outputChannel.show(true);
return validatedRealPATH;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

These both have the same for-loop with only a const named differently. But the calls above the for-loops to findRawPathEnvironmentSetting and findRealPathEnvironmentSetting don't seem to directly influence the loop. Is there something I'm missing?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ooo youre right, that's a very subtle bug. :) This is why redundant code is bad but it didn't feel like enough to make its own function. Will fix. Thank you.

if(shouldFind)
{
assert.exists(result, 'find path command returned a result');
assert.equal(result, installPath, 'The path returned by findPath is correct');
Copy link
Member

Choose a reason for hiding this comment

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

nit: extra space after the comma

Comment on lines +322 to +337
/*
test('Find dotnet PATH Command Unmet Arch Condition', async () => {
// look for a different architecture of 3.1
if(os.platform() !== 'darwin')
{
// The CI Machines are running on ARM64 for OS X.
// They also have an x64 HOST. We can't set DOTNET_MULTILEVEL_LOOKUP to 0 because it will break the ability to find the host on --info
// As our runtime installs have no host. So the architecture will read as x64 even though it's not.
//
// This is not fixable until the runtime team releases a better way to get the architecture of a particular dotnet installation.
await findPathWithRequirementAndInstall('3.1', 'runtime', os.arch() == 'arm64' ? 'x64' : os.arch(), 'greater_than_or_equal', false,
{version : '3.1', mode : 'runtime', architecture : 'arm64', requestingExtensionId : requestingExtensionId}
);
}
}).timeout(standardTimeoutTime);
*/
Copy link
Member

Choose a reason for hiding this comment

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

Commented out test...?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. This test will work and should be re-added when architecture check is added.

... as the Host will not print its architecture in dotnet info.
Return '' for now to pass all arch checks.
Need to get an issue from the runtime team. See https://github.com/dotnet/sdk/issues/33697 and https://github.com/dotnet/runtime/issues/98735*/
Copy link
Member

Choose a reason for hiding this comment

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

nit: the second link has a * in it, which makes it invalid

@nagilson nagilson enabled auto-merge (squash) September 30, 2024 22:19
@nagilson nagilson merged commit 40d1a8b into dotnet:main Sep 30, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants