dotnet/sdk

dotnet-sdk installs bogus `~/.dotnet/tools` entry as `/etc/paths.d/dotnet-cli-tools`

jsoref opened this issue ยท 8 comments

We installed dotnet-sdk using brew today and the /etc/paths.d/dotnet-cli-tools it created injected a bogus ~ into the system PATH variable which results in kubectl getting upset.

The /etc/paths.d directory (managed by /usr/libexec/path_helper) takes static files and literally inlines their contents into a produced PATH env string.

This PATH env string is not later evaluated, which means that a ~ in a file in /etc/paths.d, as in:
/etc/paths.d/dotnet-cli-tools:

~/.dotnet/tools

Will not get converted into the equivalent of $HOME/.dot/tools.

This gets reported by victims in issues such as kubernetes/kubectl#574.

I think that this is caused by:

?? @"/etc/paths.d/dotnet-cli-tools";
public OsxBashEnvironmentPath(
BashPathUnderHomeDirectory executablePath,
IReporter reporter,
IEnvironmentProvider environmentProvider,
IFile fileSystem
)
{
_packageExecutablePath = executablePath;
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_environmentProvider
= environmentProvider ?? throw new ArgumentNullException(nameof(environmentProvider));
_reporter
= reporter ?? throw new ArgumentNullException(nameof(reporter));
}
public void AddPackageExecutablePathToUserPath()
{
if (PackageExecutablePathExists())
{
return;
}
_fileSystem.WriteAllText(DotnetCliToolsPathsDPath, _packageExecutablePath.PathWithTilde);
}
private bool PackageExecutablePathExists()
{
var value = _environmentProvider.GetEnvironmentVariable(PathName);
if (value == null)
{
return false;
}
return value
.Split(':')
.Any(p => p == _packageExecutablePath.Path || p == _packageExecutablePath.PathWithTilde);
}
public void PrintAddPathInstructionIfPathDoesNotExist()
{
if (!PackageExecutablePathExists())
{
if (_fileSystem.Exists(DotnetCliToolsPathsDPath))
{
_reporter.WriteLine(
CommonLocalizableStrings.EnvironmentPathOSXNeedReopen);
}
else
{
// similar to https://code.visualstudio.com/docs/setup/mac
_reporter.WriteLine(
string.Format(
CommonLocalizableStrings.EnvironmentPathOSXBashManualInstructions,
_packageExecutablePath.Path));

Homebrew/homebrew-cask#112988

@marcpopMSFT this issue is about the casked brew installer, ie the brew installer does whatever the MS pkg installer does. This issue belongs in dotnet/installer I believe. (The non-cask brew installer is the source-built one.)

@dleeapho are you saying that this would repro with our MS pkg as well? I know nothing about casked brew.

Brew just downloads a package from here and asks the installer to run it.

https://github.com/Homebrew/homebrew-cask/blob/master/Casks/dotnet-sdk.rb#L5

are you saying that this would repro with our MS pkg as well?

I think trying to repro with the MS pkg would be a good start. I'm no expert on Casks either so I cannot discount Cask interaction though my understanding is as @jsoref stated.

@dleeapho are you saying that this would repro with our MS pkg as well? I know nothing about casked brew.

@marcpopMSFT I am able to reproduce this issue on a vanilla macOS 12 and vs for mac 2019 8.10.13.2 pkg installer (no brew cask involved) directly from https://visualstudio.microsoft.com/vs/mac/ The installer is adding ~/.dotnet/tools to $PATH which won't expanded the ~ automatically. The current workaround is for every VS for mac dotnet developer to add export PATH=$HOME/.dotnet/tools:$PATH manually in their .rc or .profile shells to invoke a global tool.

All the following issues are related to the ~ not being expanded in PATH
#22588
#9415
#13308
#10177
#2998

I don't fully know what the right solution here is but this is leading to a poor developer experience because every new developer trying to install critical tools like (dotnet-ef, dotnet-format, etc) will have to do an unnecessary manual workaround that the pkg installer should have done in the first place.

I'd half argue in favor of adding a /usr/local/bin/.dotnet-tools instead and making that a symlink to $HOME/.dotnet/tools.

I have reproduced the issue with the Microsoft installer package from https://dotnet.microsoft.com/en-us/download.

Please, add env variable to define path to tools!
It's all kind a mess with different paths of tools, datas, etc. - best way is make dotnet follow XDG spec in all platforms according to this or similar