Skip to content
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

dotnet list package fails when current directory path contains # character #19654

Closed
allanrodriguez opened this issue Aug 11, 2021 · 11 comments · Fixed by #20449
Closed

dotnet list package fails when current directory path contains # character #19654

allanrodriguez opened this issue Aug 11, 2021 · 11 comments · Fixed by #20449
Labels
Area-NuGet untriaged Request triage from a team member

Comments

@allanrodriguez
Copy link
Contributor

When running dotnet list package while in the directory of a project with a # character in its path, I get the following error:

% pwd
/Users/allan/C#
% dotnet list package
Could not find file or directory '/Users/allan/C'.
...

This works fine when the path doesn't contain a # character, or if I specify the project name in the command:

% dotnet list Test.csproj package
Project 'Test' has the following package references
   [net5.0]: No packages were found for this framework.

Steps to reproduce

  1. Create a folder called C# and cd into it.
  2. Create a new project (e.g. dotnet new console -n Test -o .)
  3. Run dotnet list package and observe the issue described above.

Other observations

  • dotnet list reference doesn't seem to have this issue.
  • Paths with other special characters may also be affected.

Environment

% dotnet --info
.NET SDK (reflecting any global.json):
 Version:   5.0.302
 Commit:    c005824e35

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  11.0
 OS Platform: Darwin
 RID:         osx.11.0-x64
 Base Path:   /usr/local/share/dotnet/sdk/5.0.302/

Host (useful for support):
  Version: 5.0.8
  Commit:  35964c9215

.NET SDKs installed:
  3.1.403 [/usr/local/share/dotnet/sdk]
  3.1.404 [/usr/local/share/dotnet/sdk]
  3.1.406 [/usr/local/share/dotnet/sdk]
  3.1.407 [/usr/local/share/dotnet/sdk]
  3.1.408 [/usr/local/share/dotnet/sdk]
  3.1.409 [/usr/local/share/dotnet/sdk]
  3.1.410 [/usr/local/share/dotnet/sdk]
  3.1.411 [/usr/local/share/dotnet/sdk]
  5.0.100 [/usr/local/share/dotnet/sdk]
  5.0.101 [/usr/local/share/dotnet/sdk]
  5.0.103 [/usr/local/share/dotnet/sdk]
  5.0.201 [/usr/local/share/dotnet/sdk]
  5.0.202 [/usr/local/share/dotnet/sdk]
  5.0.203 [/usr/local/share/dotnet/sdk]
  5.0.301 [/usr/local/share/dotnet/sdk]
  5.0.302 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.9 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.12 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.14 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.15 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.16 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.17 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.8 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.9 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.12 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.13 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.14 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.16 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.17 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.8 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-NuGet untriaged Request triage from a team member labels Aug 11, 2021
@KalleOlaviNiemitalo
Copy link

dotnet/msbuild#2178 and linked issues likewise describe problems with special characters. But the documentation that was added in dotnet/docs#22517 does not cover #.

@erdembayar
Copy link
Contributor

erdembayar commented Aug 12, 2021

@allanrodriguez
In your repro steps you didn't add any packages. If you do dotnet add package Elmah between step 2 and 3 then you'll see following.

C:\NuGetProj\IssueRepro\11136\C#> dotnet list package
Project 'Test' has the following package references
   [net6.0]:
   Top-level Package      Requested   Resolved
   > Elmah                1.2.2       1.2.2

@allanrodriguez
Copy link
Contributor Author

@KalleOlaviNiemitalo I think my issue is a little different; most dotnet commands work with paths that contain #, including dotnet list ./Test.csproj package. It's specifically dotnet list package that has this issue when running it in the same directory as Test.csproj.

@erdembayar I get the same results as you on my Windows machine, even without adding a package. It's when using my macOS machine that I see this issue.

This is the full output of my repro steps on macOS, including adding a package before running dotnet list package:

allan@Allans-MBP Desktop % mkdir C#
allan@Allans-MBP Desktop % cd C\# 
allan@Allans-MBP C# % dotnet new console -n Test -o .
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /Users/allan/Desktop/C#/Test.csproj...
  Determining projects to restore...
  Restored /Users/allan/Desktop/C#/Test.csproj (in 73 ms).
Restore succeeded.

allan@Allans-MBP C# % dotnet add package Elmah
  Determining projects to restore...
  Writing /var/folders/b1/pf0rgq213214nxr4mcknhwzm0000gn/T/tmpiAPlbc.tmp
info : Adding PackageReference for package 'Elmah' into project '/Users/allan/Desktop/C#/Test.csproj'.
info :   CACHE https://api.nuget.org/v3/registration5-gz-semver2/elmah/index.json
info : Restoring packages for /Users/allan/Desktop/C#/Test.csproj...
warn : NU1701: Package 'elmah.corelibrary 1.2.2' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.
info : Package 'Elmah' is compatible with all the specified frameworks in project '/Users/allan/Desktop/C#/Test.csproj'.
info : PackageReference for package 'Elmah' version '1.2.2' added to file '/Users/allan/Desktop/C#/Test.csproj'.
info : Committing restore...
info : Writing assets file to disk. Path: /Users/allan/Desktop/C#/obj/project.assets.json
log  : Restored /Users/allan/Desktop/C#/Test.csproj (in 89 ms).
allan@Allans-MBP C# % dotnet list package
Could not find file or directory '/Users/allan/Desktop/C'.
package
  List all package references of the project or solution.

Usage:
  dotnet [options] list [<PROJECT | SOLUTION>] package

Arguments:
  <PROJECT | SOLUTION>  The project or solution file to operate on. If a file is not specified, the command will search the current directory for one. [default: /Users/allan/Desktop/C#/]

Options:
  -v, --verbosity <d|detailed|diag|diagnostic|m|minimal|n|normal|q|quiet>  Set the MSBuild verbosity level. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].
  --outdated                                                               Lists packages that have newer versions. Cannot be combined with '--deprecated' or '--vulnerable' options.
  --deprecated                                                             Lists packages that have been deprecated. Cannot be combined with '--vulnerable' or '--outdated' options.
  --vulnerable                                                             Lists packages that have known vulnerabilities. Cannot be combined with '--deprecated' or '--outdated' options.
  --framework <FRAMEWORK | FRAMEWORK\RID>                                  Chooses a framework to show its packages. Use the option multiple times for multiple frameworks.
  --include-transitive                                                     Lists transitive and top-level packages.
  --include-prerelease                                                     Consider packages with prerelease versions when searching for newer packages. Requires the '--outdated' option.
  --highest-patch                                                          Consider only the packages with a matching major and minor version numbers when searching for newer packages. Requires the 
                                                                           '--outdated' option.
  --highest-minor                                                          Consider only the packages with a matching major version number when searching for newer packages. Requires the '--outdated' 
                                                                           option.
  --config <CONFIG_FILE>                                                   The path to the NuGet config file to use. Requires the '--outdated', '--deprecated' or '--vulnerable' option.
  --source <SOURCE>                                                        The NuGet sources to use when searching for newer packages. Requires the '--outdated', '--deprecated' or '--vulnerable' option.
  --interactive                                                            Allows the command to stop and wait for user input or action (for example to complete authentication).
  -?, -h, --help                                                           Show help and usage information

Specifying the project file in the command works fine though:

allan@Allans-MBP C# % dotnet list Test.csproj package
Project 'Test' has the following package references
   [net6.0]: 
   Top-level Package      Requested   Resolved
   > Elmah                1.2.2       1.2.2   

@erdembayar
Copy link
Contributor

I can repro this sdk 5.0.203 on MAC, it looks subtle bug.

@erdembayar
Copy link
Contributor

@allanrodriguez
Could you be able to create issue on nuget.client repository? https://github.com/nuget/nuget.client/issues/new
Somehow I was not able to transfer to nuget.client repository.

@allanrodriguez
Copy link
Contributor Author

@erdembayar I can create an issue in the nuget repo, but first I wanted to confirm that the issue isn't in this repo. I ask because the error message returned from dotnet list package closely matches one in this repo:

throw new GracefulException(LocalizableStrings.FileNotFound, resultPath);

<data name="FileNotFound" xml:space="preserve">
<value>Could not find file or directory '{0}'.</value>
</data>

@KalleOlaviNiemitalo
Copy link

KalleOlaviNiemitalo commented Aug 15, 2021

I suspect the bug is in PathUtility.GetAbsolutePath, which uses the Uri class even though the input is not URI-encoded:

Uri resultUri = new Uri(new Uri(basePath), new Uri(relativePath, UriKind.Relative));
return resultUri.LocalPath;

It is called from the ListPackageReferencesCommand constructor:

_fileOrDirectory = PathUtility.GetAbsolutePath(PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()),
appliedCommand.Arguments.Single());

@erdembayar
Copy link
Contributor

@erdembayar I can create an issue in the nuget repo, but first I wanted to confirm that the issue isn't in this repo. I ask because the error message returned from dotnet list package closely matches one in this repo:

throw new GracefulException(LocalizableStrings.FileNotFound, resultPath);

<data name="FileNotFound" xml:space="preserve">
<value>Could not find file or directory '{0}'.</value>
</data>

I'm not sure, but in our repo we already have unit test for dotnet list package so that means very high probability it's connected to our repo.

@allanrodriguez
Copy link
Contributor Author

I can confirm @KalleOlaviNiemitalo's findings. After copying the PathUtility.GetAbsolutePath method into a sample project and passing it the same parameters as dotnet list package, I get back a path without the #.

using System;

namespace Test
{
    class Program
    {
        static void Main()
        {
            // Outputs '/Users/allan/Desktop/C'
            Console.WriteLine(PathUtility.GetAbsolutePath("/Users/allan/Desktop/C#/", "/Users/allan/Desktop/C#/"));
        }
    }

    public static class PathUtility
    {
        public static string GetAbsolutePath(string basePath, string relativePath)
        {
            if (basePath == null)
            {
                throw new ArgumentNullException(nameof(basePath));
            }

            if (relativePath == null)
            {
                throw new ArgumentNullException(nameof(relativePath));
            }

            Uri resultUri = new Uri(new Uri(basePath), new Uri(relativePath, UriKind.Relative));
            return resultUri.LocalPath;
        }
    }
}

Maybe using Path.GetFullPath would work better here?

@KalleOlaviNiemitalo
Copy link

According to https://github.com/dotnet/sdk/search?q=GetAbsolutePath, PathUtility.GetAbsolutePath does not seem to be used elsewhere in this repository. Unfortunately, it has already been shipped in the Microsoft.DotNet.Cli.Utils 2.0.0 NuGet package, so I guess it will need to be fixed even if ListPackageReferencesCommand is changed to use Path.GetFullPath instead.

@ghost
Copy link

ghost commented Apr 21, 2022

Thanks for creating this issue! We believe this issue is related to NuGet tooling, which is maintained by the NuGet team. Thus, we closed this one and encourage you to raise this issue in the NuGet repository instead. Don’t forget to check out NuGet’s contributing guide before submitting an issue!

If you believe this issue was closed out of error, please comment to let us know.

Happy Coding!

@ghost ghost closed this as completed Apr 21, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-NuGet untriaged Request triage from a team member
Projects
None yet
3 participants