Skip to content

Commit

Permalink
Add a baseDirectory argument for LooksLikeUnixFilePath and ..
Browse files Browse the repository at this point in the history
.. MaybeAdjustFilePath. The former checks if the first segment of the
path might be the name of an existent directory. This depends on the
CWD, but in some cases we might need to check this in a different
directory.

For example, project A initiates a build of project B, and while B is
being evaluated the CWD may not have been updated, but the paths in B's
project file are relative to B. So, the checks should be done in B's
directory.

This will be useful in an upcoming fix.
  • Loading branch information
Ankit Jain committed Apr 28, 2017
1 parent 5d14719 commit 28dc2d4
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/Shared/FileUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,10 @@ internal static string FixFilePath(string path)
/// first segment exists and is a directory.
/// Use a native shared method to massage file path. If the file is adjusted,
/// that qualifies is as a path.
///
/// @baseDirectory is just passed to LooksLikeUnixFilePath, to help with the check
/// </summary>
internal static string MaybeAdjustFilePath(string value)
internal static string MaybeAdjustFilePath(string value, string baseDirectory="")
{
// Don't bother with arrays or properties or network paths, or those that
// have no slashes.
Expand Down Expand Up @@ -436,15 +438,18 @@ internal static string MaybeAdjustFilePath(string value)
}
}

return LooksLikeUnixFilePath(checkValue) ? newValue : value;
return LooksLikeUnixFilePath(checkValue, baseDirectory) ? newValue : value;
}

/// <summary>
/// If on Unix, check if the string looks like a file path.
/// The heuristic is if something resembles paths (contains slashes) check if the
/// first segment exists and is a directory.
///
/// If @baseDirectory is not null, then look for the first segment exists under
/// that
/// </summary>
internal static bool LooksLikeUnixFilePath(string value)
internal static bool LooksLikeUnixFilePath(string value, string baseDirectory="")
{
if (!NativeMethodsShared.IsUnixLike)
{
Expand All @@ -459,7 +464,7 @@ internal static bool LooksLikeUnixFilePath(string value)
firstSlash = value.Substring(1).IndexOf('/') + 1;
}

if (firstSlash > 0 && Directory.Exists(value.Substring(0, firstSlash)))
if (firstSlash > 0 && Directory.Exists(Path.Combine(baseDirectory, value.Substring(0, firstSlash))))
{
return true;
}
Expand Down
63 changes: 63 additions & 0 deletions src/Shared/UnitTests/FileUtilities_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,69 @@ public void PathDoesNotLookLikeUnixPathOnWindows()
Assert.False(FileUtilities.LooksLikeUnixFilePath("/root"));
}

[Fact]
[PlatformSpecific(Xunit.PlatformID.AnyUnix)]
public void RelativePathLooksLikeUnixPathOnUnixWithBaseDirectory()
{
string filePath = ObjectModelHelpers.CreateFileInTempProjectDirectory("first/second/file.txt", String.Empty);
string oldCWD = Directory.GetCurrentDirectory();

try
{
// <tmp_dir>/first
string firstDirectory = Path.GetDirectoryName(Path.GetDirectoryName(filePath));
string tmpDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(filePath)));

Directory.SetCurrentDirectory(tmpDirectory);

// We are in <tmp_dir> and second is not under that, so this will be false
Assert.False(FileUtilities.LooksLikeUnixFilePath("second/file.txt"));

// .. but if we have baseDirectory:firstDirectory, then it will be true
Assert.True(FileUtilities.LooksLikeUnixFilePath("second/file.txt", firstDirectory));
}
finally
{
if (filePath != null)
{
File.Delete(filePath);
}
Directory.SetCurrentDirectory(oldCWD);
}
}

[Fact]
[PlatformSpecific(Xunit.PlatformID.AnyUnix)]
public void RelativePathMaybeAdjustFilePathWithBaseDirectory()
{
// <tmp_dir>/first/second/file.txt
string filePath = ObjectModelHelpers.CreateFileInTempProjectDirectory("first/second/file.txt", String.Empty);
string oldCWD = Directory.GetCurrentDirectory();

try
{
// <tmp_dir>/first
string firstDirectory = Path.GetDirectoryName(Path.GetDirectoryName(filePath));
string tmpDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(filePath)));

Directory.SetCurrentDirectory(tmpDirectory);

// We are in <tmp_dir> and second is not under that, so this won't convert
Assert.Equal("second\\file.txt", FileUtilities.MaybeAdjustFilePath("second\\file.txt"));

// .. but if we have baseDirectory:firstDirectory, then it will
Assert.Equal("second/file.txt", FileUtilities.MaybeAdjustFilePath("second\\file.txt", firstDirectory));
}
finally
{
if (filePath != null)
{
File.Delete(filePath);
}
Directory.SetCurrentDirectory(oldCWD);
}
}

private static string SystemSpecificAbsolutePath => FileUtilities.ExecutingAssemblyPath;


Expand Down

0 comments on commit 28dc2d4

Please sign in to comment.