Skip to content

Commit

Permalink
Merge branch 'daveMueller-GH2838_MakeRelative' into release/1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
devlead committed Dec 9, 2020
2 parents 5a0700e + 7c7ed02 commit 8b755a7
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 1 deletion.
122 changes: 122 additions & 0 deletions src/Cake.Common.Tests/Unit/IO/DirectoryAliasesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Cake.Core;
using Cake.Core.IO;
using Cake.Testing;
using Cake.Testing.Xunit;
using NSubstitute;
using Xunit;

Expand Down Expand Up @@ -1016,6 +1017,127 @@ public void Should_Return_Absolute_Directory_Path()
}
}

public sealed class TheMakeRelativeMethod
{
[Fact]
public void Should_Throw_For_DirectoryPath_If_Context_Is_Null()
{
// Given, When
var result = Record.Exception(() => DirectoryAliases.MakeRelative(null, new DirectoryPath("./build")));

// Then
AssertEx.IsArgumentNullException(result, "context");
}

[Fact]
public void Should_Throw_For_FilePath_If_Context_Is_Null()
{
// Given, When
var result = Record.Exception(() => DirectoryAliases.MakeRelative(null, new FilePath("./build")));

// Then
AssertEx.IsArgumentNullException(result, "context");
}

[Fact]
public void Should_Throw_If_DirectoryPath_Is_Null()
{
// Given
var context = Substitute.For<ICakeContext>();
DirectoryPath path = null;

// When
var result = Record.Exception(() => DirectoryAliases.MakeRelative(context, path));

// Then
AssertEx.IsArgumentNullException(result, "path");
}

[Fact]
public void Should_Throw_If_FilePath_Is_Null()
{
// Given
var context = Substitute.For<ICakeContext>();
FilePath path = null;

// When
var result = Record.Exception(() => DirectoryAliases.MakeRelative(context, path));

// Then
AssertEx.IsArgumentNullException(result, "path");
}

[WindowsTheory]
[InlineData(@"\Working", @"\Working\build", "build")]
[InlineData(@"\Working", @"\Working", ".")]
[InlineData("C:/Working/build/core", "C:/Working/stage/core", "../../stage/core")]
[InlineData("C:/Working/build/core", "C:/Working", "../..")]
public void Should_Return_Relative_Directory_Path_For_Working_Directory(string rootPath, string path, string expected)
{
// Given
var context = Substitute.For<ICakeContext>();
context.Environment.WorkingDirectory.Returns(d => rootPath);

// When
var result = DirectoryAliases.MakeRelative(context, new DirectoryPath(path));

// Then
Assert.Equal(expected, result.FullPath);
}

[WindowsTheory]
[InlineData(@"\Working", @"\Working\build", "build")]
[InlineData(@"\Working", @"\Working", ".")]
[InlineData("C:/Working/build/core", "C:/Working/stage/core", "../../stage/core")]
[InlineData("C:/Working/build/core", "C:/Working", "../..")]
public void Should_Return_Relative_Directory_Path_For_Defined_Root_Directory(string rootPath, string path, string expected)
{
// Given
var context = Substitute.For<ICakeContext>();

// When
var result = DirectoryAliases.MakeRelative(context, new DirectoryPath(path), new DirectoryPath(rootPath));

// Then
Assert.Equal(expected, result.FullPath);
}

[WindowsTheory]
[InlineData(@"\Working", @"\Working\build\file.cake", "build/file.cake")]
[InlineData(@"\Working", @"\Working\file.cake", "file.cake")]
[InlineData("C:/Working/build/core", "C:/Working/stage/core/file.cake", "../../stage/core/file.cake")]
[InlineData("C:/Working/build/core", "C:/Working/file.cake", "../../file.cake")]
public void Should_Return_Relative_File_Path_For_Working_Directory(string rootPath, string path, string expected)
{
// Given
var context = Substitute.For<ICakeContext>();
context.Environment.WorkingDirectory.Returns(d => rootPath);

// When
var result = DirectoryAliases.MakeRelative(context, new FilePath(path));

// Then
Assert.Equal(expected, result.FullPath);
}

[WindowsTheory]
[InlineData(@"\Working", @"\Working\build\file.cake", "build/file.cake")]
[InlineData(@"\Working", @"\Working\file.cake", "file.cake")]
[InlineData("C:/Working/build/core", "C:/Working/stage/core/file.cake", "../../stage/core/file.cake")]
[InlineData("C:/Working/build/core", "C:/Working/file.cake", "../../file.cake")]
public void Should_Return_Relative_File_Path_For_Defined_Root_Directory(string rootPath, string path, string expected)
{
// Given
var context = Substitute.For<ICakeContext>();

// When
var result = DirectoryAliases.MakeRelative(context, new FilePath(path), new DirectoryPath(rootPath));

// Then
Assert.Equal(expected, result.FullPath);
}
}

public sealed class TheMoveDirectoryMethod
{
[Fact]
Expand Down
62 changes: 62 additions & 0 deletions src/Cake.Common/IO/DirectoryAliases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,68 @@ public static DirectoryPath MakeAbsolute(this ICakeContext context, DirectoryPat
return path.MakeAbsolute(context.Environment);
}

/// <summary>
/// Makes the directory path relative (if absolute) to a specified root directory. If no root directory is defined
/// the current working directory is used as default root.
/// </summary>
/// <example>
/// <code>
/// var path = MakeRelative(Directory("C:\Cake\Tests\Integration"));
/// </code>
/// </example>
/// <param name="context">The context.</param>
/// <param name="path">The path.</param>
/// <param name="rootPath">The root path.</param>
/// <returns>A relative directory path.</returns>
[CakeMethodAlias]
[CakeAliasCategory("Path")]
public static DirectoryPath MakeRelative(this ICakeContext context, DirectoryPath path, DirectoryPath rootPath = null)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

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

var root = rootPath ?? context.Environment.WorkingDirectory;
return root.GetRelativePath(path);
}

/// <summary>
/// Makes the file path relative (if absolute) to a specified root directory. If no root directory is defined
/// the current working directory is used as default root.
/// </summary>
/// <example>
/// <code>
/// var path = MakeRelative(Directory("C:\Cake\Tests\Integration\file.cake"));
/// </code>
/// </example>
/// <param name="context">The context.</param>
/// <param name="path">The path.</param>
/// <param name="rootPath">The root path.</param>
/// <returns>A relative file path.</returns>
[CakeMethodAlias]
[CakeAliasCategory("Path")]
public static FilePath MakeRelative(this ICakeContext context, FilePath path, DirectoryPath rootPath = null)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

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

var root = rootPath ?? context.Environment.WorkingDirectory;
return root.GetRelativePath(path);
}

/// <summary>
/// Moves an existing directory to a new location, providing the option to specify a new directory name.
/// </summary>
Expand Down
40 changes: 39 additions & 1 deletion tests/integration/Cake.Common/IO/DirectoryAliases.cake
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,42 @@ Task("Cake.Common.IO.DirectoryAliases.DeleteDirectories.Recurse")
Assert.False(System.IO.Directory.Exists(path2.FullPath));
});

Task("Cake.Common.IO.DirectoryAliases.MakeRelative.DefinedRootPath")
.Does(() =>
{
// Given
var directoryPath = Paths.Temp.Combine("./hello/world");
var filePath = Paths.Temp.Combine("./hello/world/test.cake");
var rootPath1 = Paths.Temp;
var rootPath2 = Paths.Temp.Combine("./cake/world");
// When
var relativeDirectoryPath1 = MakeRelative(directoryPath, rootPath1);
var relativeDirectoryPath2 = MakeRelative(directoryPath, rootPath2);
var relativeFilePath = MakeRelative(filePath, rootPath2);
// Then
Assert.Equal("hello/world", relativeDirectoryPath1.ToString());
Assert.Equal("../../hello/world", relativeDirectoryPath2.ToString());
Assert.Equal("../../hello/world/test.cake", relativeFilePath.ToString());
});

Task("Cake.Common.IO.DirectoryAliases.MakeRelative.WorkingDirectory")
.Does(() =>
{
// Given
var directoryPath = Paths.Temp.Combine("./hello/world");
var filePath = Paths.Temp.Combine("./hello/world/test.cake");
// When
var relativeDirectoryPath = MakeRelative(directoryPath);
var relativeFilePath = MakeRelative(filePath);
// Then
Assert.Equal("temp/hello/world", relativeDirectoryPath.ToString());
Assert.Equal("temp/hello/world/test.cake", relativeFilePath.ToString());
});

//////////////////////////////////////////////////////////////////////////////

Task("Cake.Common.IO.DirectoryAliases")
Expand All @@ -177,4 +213,6 @@ Task("Cake.Common.IO.DirectoryAliases")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.DeleteDirectory")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.DeleteDirectory.Recurse")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.DeleteDirectories")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.DeleteDirectories.Recurse");
.IsDependentOn("Cake.Common.IO.DirectoryAliases.DeleteDirectories.Recurse")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.MakeRelative.DefinedRootPath")
.IsDependentOn("Cake.Common.IO.DirectoryAliases.MakeRelative.WorkingDirectory");

0 comments on commit 8b755a7

Please sign in to comment.