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

Combine rootDir with relative file names #94528

Merged
merged 1 commit into from
Nov 28, 2023

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Nov 8, 2023

Fixes #50648

Using Path.GetFullPath on relative file names causes that the in-memory Matcher.Match to treat files as relative to the CWD blocking scenarios that are using a rootDir in a different drive as the one discussed in #50648. We should combine the rootDir with the relative file names instead. This is also what's described in the documentation.

files IEnumerable<String>
Collection of file names. If relative paths rootDir will be prepended to the paths.

However, this is a (massive?) breaking change as there's already a lot of tests showing that filenames are relative to CWD and not to rootDir, and in the wild, there will be most likely use cases that depend in this bug (need to check).

@jozkee jozkee added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Nov 8, 2023
@jozkee jozkee added this to the 9.0.0 milestone Nov 8, 2023
@jozkee jozkee self-assigned this Nov 8, 2023
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Nov 8, 2023
@ghost
Copy link

ghost commented Nov 8, 2023

Added needs-breaking-change-doc-created label because this PR has the breaking-change label.

When you commit this breaking change:

  1. Create and link to this PR and the issue a matching issue in the dotnet/docs repo using the breaking change documentation template, then remove this needs-breaking-change-doc-created label.
  2. Ask a committer to mail the .NET Breaking Change Notification DL.

Tagging @dotnet/compat for awareness of the breaking change.

@ghost
Copy link

ghost commented Nov 8, 2023

Tagging subscribers to this area: @dotnet/area-extensions-filesystem
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #50648

Using Path.GetFullPath on relative file names causes that the in-memory Matcher.Match to treat files as relative to the CWD blocking scenarios that are using a rootDir in a different drive as the one discussed in #50648. We should combine the rootDir with the relative file names instead. This is also what's described in the documentation.

files IEnumerable<String>
Collection of file names. If relative paths rootDir will be prepended to the paths.

However, this is a (massive?) breaking change as there's already a lot of tests showing that filenames are relative to CWD and not to rootDir, and in the wild, there will be most likely use cases that depend in this bug (need to check).

Author: Jozkee
Assignees: Jozkee
Labels:

breaking-change, area-Extensions-FileSystem

Milestone: 9.0.0

@jeffhandley
Copy link
Member

This looks like a good change to make, and it's valuable to make the change very early in .NET 9.

Given the potential breaking-change impact though, we might need to produce a qualified assessment of risk and probably even find ways to alert users this is coming. We can partner with the @dotnet/compat folks to study call sites, identify some places that might be depending on this behavior, and determine if this is something we need to phase in with a compat switch. We might even discover a scenario where this behavior could not be opted into. If we see a lot of risk, we might even want to explore an analyzer to produce a warning on call sites. @jozkee I'll follow up with you offline.

In the meantime, I'll mark this PR as NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) .

@jeffhandley jeffhandley added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Nov 8, 2023
@jozkee
Copy link
Member Author

jozkee commented Nov 16, 2023

I found one usage of the affected overload in our first party data. It is for smoke tests on dotnet/installer. This leads me to believe that most people use the overloads that don’t take a rootDir, those use the cwd as rootDir inplicitly.

I’ll try to visualize the breaking change:

string rootDir = "dir1";
string[] files = ["dir1/test.0", "dir1/subdir/test.1", "dir2/test.2"];

PatternMatchingResult result = new Matcher().AddInclude("**/*").Match(rootDir, files);
Console.WriteLine(string.Join(", ", result.Files.Select(x => x.Path)));

Because both args are treated as relative to the cwd.
This currently prints test.0, subdir/test.1.
With the breaking change this now would print dir1/test.0, dir1/subdir/test.1, dir2/test.2. It includes dir2 because now all is under rootDir.

In order to get a similar (but not same) output as prior you need to change the code to something like the following:

string rootDir = "dir1";
string[] files = ["dir1/test.0", "dir1/subdir/test.1", "dir2/test.2"];

-PatternMatchingResult result = new Matcher().AddInclude("**/*").Match(rootDir, files);
+PatternMatchingResult result = new Matcher().AddInclude("dir1/**/*").Match(rootDir, files);
Console.WriteLine(string.Join(", ", result.Files.Select(x => x.Path)));

// prints
// dir1/test.0
// dir1/subdir/test.1

@ericstj would be good to send this to the VMR in order to validate that the dotnet/installer test doesn't break with this change?

@jozkee jozkee requested a review from ericstj November 16, 2023 18:20
@jozkee
Copy link
Member Author

jozkee commented Nov 21, 2023

Ping @adamsitnik @jeffhandley @ericstj

@jeffhandley
Copy link
Member

Good find, @jozkee! Is there a way to update the calling code before the change goes through that would allow the calling code to function as desired both now and after the breaking change goes through? If so, we could go ahead and update dotnet/installer so that as the breaking change goes through the tests will keep passing. If not, then we might want to consider disabling that test until the change flows through and then re-enabling it.

@jozkee
Copy link
Member Author

jozkee commented Nov 21, 2023

@jeffhandley I can verify it, just need to find out how to run the smoke tests in dotnet/installer.

@ericstj
Copy link
Member

ericstj commented Nov 27, 2023

With the breaking change this now would print dir1/test.0, dir1/subdir/test.1, dir2/test.2. It includes dir2 because now all is under rootDir.

How is dir2 under rootDir? I thought rootDir was dir1.

@ericstj would be good to send this to the VMR

Not necessary - it wouldn't be running these tests (nor is it accepting commits yet). You'd just need to watch this change flowing up to installer then fix up the test when it hits it.

@jozkee
Copy link
Member Author

jozkee commented Nov 27, 2023

How is dir2 under rootDir?

Because now rootDir is prefixed to each path in files, except when a path is absolute. In a simplified manner:

foreach (string file in files)
{
    if (Path.IsPathRooted(file))
        fileList.Add(file);
    else
        fileList.Add(Path.Combine(rootDir, file));
}

fileList now contains
"C:/somepath/dir1/dir1/test.0"
"C:/somepath/dir1/dir1/subdir/test.1"
"C:/somepath/dir1/dir2/test.2"

While previously it contained the following, because rootDir was not being prefixed.
"C:/somepath/dir1/test.0"
"C:/somepath/dir1/subdir/test.1"
"C:/somepath/dir2/test.2"

@jozkee jozkee closed this Nov 28, 2023
@jozkee jozkee reopened this Nov 28, 2023
@jozkee jozkee merged commit b190ea8 into dotnet:main Nov 28, 2023
111 of 113 checks passed
@jozkee jozkee deleted the glob-match-inmemory branch November 28, 2023 23:23
@jozkee jozkee removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Nov 28, 2023
@ericstj
Copy link
Member

ericstj commented Nov 30, 2023

I see - might be better to not reuse the name - since the use of dir1 implies the same dir1

@github-actions github-actions bot locked and limited conversation to collaborators Dec 31, 2023
@jozkee
Copy link
Member Author

jozkee commented Jan 18, 2024

Breaking change doc. created: dotnet/docs#39189

@jozkee jozkee removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jan 18, 2024
@ViktorHofer
Copy link
Member

ViktorHofer commented Apr 8, 2024

I think this change caused another unintended breaking change. Filed: #100762

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-FileSystem breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InMemoryDirectoryInfo is unexpectedly dependent on working directory due to its use of GetFullPath.
4 participants