Skip to content

Conversation

@dsparkplug
Copy link

@dsparkplug dsparkplug commented Jun 3, 2021

Fixes #6493

Summary
MSBuild's MakeRelative function does not fit the spec for how that function should work.

Customer impact
Customers who use our MakeRelative function expect the relative path produced to end in a slash if and only if the input path ends in a slash. It currently does not end in a slash whether or not the input path ended in a slash. Users can invoke this function directly, and it can lead to dlls not being found, among other problems.

Regression?
Yes, from #6311 (16.10 Preview 2). The URI-based function that had existed prior failed in another scenario, and the new form is also faster. This PR resolves a bug associated with that change.

Changes Made
Only removes the ending slash if the input path did not end in a slash.

Testing
Extensive unit test coverage. This is a community contribution, and I imagine it was also tested locally. (Please correct me if I'm wrong, @dsparkplug.)

Risk
Low. Rather than always removing the final slash, this conditionally removes it, reverting to prior behavior. No other (non-test) parts of the code base were altered.

Added some more unit tests as per suggestions

Fixed unit test failing on linux

Removed unnecessary length check

Co-authored-by: Forgind <[email protected]>
@dsparkplug dsparkplug marked this pull request as ready for review June 3, 2021 03:02
@Forgind
Copy link
Contributor

Forgind commented Jun 4, 2021

The MSBuild team agreed we would try to take this for 16.10 as you suggested. We will need internal approval, so I'm modifying your opening message to fit the template.

}
sb.Length--;

if (fullPath[fullPath.Length - 1] != Path.DirectorySeparatorChar)
Copy link
Member

Choose a reason for hiding this comment

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

should it also check Path.AlternateDirectorySeparatorChar?

Copy link
Author

Choose a reason for hiding this comment

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

My understanding is that the fullPath has already been normalised within the Path.GetFullPath function so should only contain Path.DirectorySeparatorChar?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like that's true for unix. Windows calls down into the kernel, but I'm assuming it's the same.

Copy link
Author

Choose a reason for hiding this comment

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

Sure is:

Microsoft (R) Visual C# Interactive Compiler version 3.10.0-4.21269.26 ()
Loading context from 'CSharpInteractive.rsp'.
Type "#help" for more information.
> System.Console.WriteLine(System.IO.Path.GetFullPath("C:/abc/def/"));
C:\abc\def\
> System.Console.WriteLine(System.IO.Path.GetFullPath("C:/abc/def"));
C:\abc\def
> 

Copy link
Contributor

@Forgind Forgind left a comment

Choose a reason for hiding this comment

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

Thank you for fixing this!

Comment on lines +1571 to +1572
public static bool operator ==(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; }
public static bool operator !=(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; }
Copy link
Member

Choose a reason for hiding this comment

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

Sorry about this; we fixed if for 16.11 but not 16.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants