Closed rcdailey closed 2 years ago
Tagging subscribers to this area: @agocke, @vitek-karas, @vsadov See info in area-owners.md if you want to be subscribed.
Author: | rcdailey |
---|---|
Assignees: | - |
Labels: | `area-Single-File`, `untriaged` |
Milestone: | - |
This is the request for this bug (copied from the discussion):
I think that, if possible, dotnet runtime should do more to abstract these nitty-gritty details away from me. For example I find it weird that even though $HOME
is set, $XDG_CONFIG_HOME
is still required, According to the XDG spec page I read, it should fall back to $HOME
. I'm not sure if that's a linux responsibility or an application one. But I don't think it's unreasonable for dotnet runtime to use $HOME
(which I explicitly set, even before I started this discussion thread).
For the record, the specification I read states:
$XDG_CONFIG_HOME defines the base directory relative to which user-specific configuration files should be stored. If
$XDG_CONFIG_HOME
is either not set or empty, a default equal to$HOME/.config
should be used.
This is what the dotnet runtime should be doing, IMHO.
More broadly, even though this is specifically about XDG_CONFIG_HOME
, I think for .NET 7.0, the entire XDG specification should be implemented and respected equally on all Linux platforms (Alpine, unRAID, Debian, etc).
Ultimately I want to be confident that "Linux" support, broadly speaking, is simple and consistently supported for my .NET application. If I'm getting different behavior on different distros and having to, due to trial & error, set various arguably implementation-detail environment variables to get my app to behave consistently, that to me is a fatal design flaw.
I sadly am not sure how easy or hard what I'm asking for is. So the best I can offer is my opinion in broad brush strokes.
Tagging subscribers to this area: @dotnet/area-system-io See info in area-owners.md if you want to be subscribed.
Author: | rcdailey |
---|---|
Assignees: | - |
Labels: | `area-System.IO`, `area-Single-File` |
Milestone: | 7.0.0 |
Not quite sure where to triage this one -- it's about System.Environment.SpecialFolder, so I put it in System.IO.
ApplicationData
follows the XDG spec.
GetFolderPath
returns an empty string when the folder doesn't exist, which is probably what is happening here.
You can use the overload with SpecialFolderOption.DoNotVerify
to skip the exists check.
Or with SpecialFolderOption.Create
to create it when it doesn't exist.
I tested creating the directory as well, it still returned a blank string. Again, with $HOME
set, and $HOME/.config
created: I get a blank string. Only worked when I explicitly set the XDG variable as explained previously.
I cannot reproduce that.
I run these commands to install dotnet
in the alpine
image:
cd
apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib
export DOTNET_ROOT=$(pwd)/.dotnet
wget https://download.visualstudio.microsoft.com/download/pr/108663ba-7326-432d-97c6-d3925e9990cc/dd9876b6a0fc0cdae66006747cb3dda0/dotnet-sdk-6.0.300-linux-musl-x64.tar.gz
DOTNET_FILE=dotnet-sdk-6.0.300-linux-musl-x64.tar.gz
mkdir -p "$DOTNET_ROOT" && tar zxf "$DOTNET_FILE" -C "$DOTNET_ROOT"
export PATH=$PATH:$DOTNET_ROOT
Then create a .NET app to print ApplicationData
:
~ # dotnet new console -o console
Welcome to .NET 6.0!
---------------------
SDK Version: 6.0.300
Telemetry
---------
The .NET tools collect usage data in order to help us improve your experience. It is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.
Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry
----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
The template "Console App" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /root/console/console.csproj...
Determining projects to restore...
Restored /root/console/console.csproj (in 121 ms).
Restore succeeded.
~ # cd console/
~/console # cat >Program.cs <<EOF
> Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.DoNotVerify));
> EOF
~/console # dotnet run
/root/.config
This prints the expected value.
In the container, XDG_CONFIG_HOME
is not set, and the ~/.config
dir doesn't exist:
~/console # stat /root/.config
stat: can't stat '/root/.config': No such file or directory
~/console # echo $XDG_CONFIG_HOME
If I leave out Environment.SpecialFolderOption.DoNotVerify
, it does the same thing as your reproducer: print an empty line.
Your use case isn't exactly the same as mine (although I'm not certain the differences matter):
$HOME
directory to something (e.g. /config
)$HOME/.config
Does it still work for you?
Does it still work for you?
Yes, this works fine.
$ ./console
/home/tmds/.config
$ HOME=/tmp/foo ./console
/tmp/foo/.config
$ mkdir -p /tmp/foo/.config
$ HOME=/tmp/foo ./console
/tmp/foo/.config
with Program.cs
:
Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.DoNotVerify));
Ok I played with this a bunch more and I must have done something weird earlier. I apologize for the mess; this is a tough problem to wrap my head around so I probably messed up somewhere.
When I just define HOME
and explicitly create $HOME/.config
, it's working now. I could have sworn I did this before and it wasn't working. So maybe I broke my own use case somewhere along the line.
So I think ultimately this comes down to what you were saying: That the directories have to exist or else it returns a blank string. I think that the directory should be created automatically if it does not exist. I'm not sure if this is the responsibility of .NET, though, since that gets into OS environment issues too.
Thank you for taking the time to reproduce this with me.
I think that the directory should be created automatically if it does not exist.
ApplicationData
follows the XDG spec.
GetFolderPath
returns an empty string when the folder doesn't exist, which is probably what is happening here. You can use the overload withSpecialFolderOption.DoNotVerify
to skip the exists check. Or withSpecialFolderOption.Create
to create it when it doesn't exist.
I forgot you said this before. Thank you for the reminder. I'll close this issue. Thanks again to everyone that helped.
Discussed in https://github.com/dotnet/runtime/discussions/69362