-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* GitExecute changes for WSL * address PR comments * incorporate feedback * incorporate feedback continued * address PR feedback * changes
- Loading branch information
Showing
3 changed files
with
277 additions
and
9 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
extensions/GitExtension/FileExplorerGitIntegration.UnitTest/WslIntegratorUnitTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Diagnostics; | ||
using FileExplorerGitIntegration.Models; | ||
|
||
namespace FileExplorerGitIntegration.UnitTest; | ||
|
||
[TestClass] | ||
public class WslIntegratorUnitTests | ||
{ | ||
[TestMethod] | ||
[DataRow(@"\\wsl$\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"\\wsl$\Ubuntu\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\Debian\home\user\repo")] | ||
[DataRow(@"\\wsl$\kali-linux\home\user\repo")] | ||
[DataRow(@"\\wsl$\Ubuntu-18.04\home\user\testRepo")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-18.04\home\user\testRepo")] | ||
[DataRow(@"\\WSL.LOCALHOST\Ubuntu-18.04\home\user\testRepo")] | ||
[DataRow(@"\\WSL$\Ubuntu-18.04\home\user\testRepo")] | ||
[DataRow(@"\\WsL.loCaLHoST\Ubuntu-18.04\home\user\testRepo")] | ||
[DataRow(@"\\WsL$\Ubuntu-18.04\home\user\testRepo")] | ||
public void IsWSLRepoPositiveTests(string repositoryPath) | ||
{ | ||
Assert.IsTrue(WslIntegrator.IsWSLRepo(repositoryPath)); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"//wsl$/kali-linux/home/user/repo")] | ||
[DataRow(@"C:\Users\foo\bar")] | ||
[DataRow(@"\\wsl$*\Ubuntu\home\user\repo")] | ||
[DataRow(@"D:\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"\\wsl.test\Ubuntu\home\user\repo")] | ||
[DataRow("")] | ||
[DataRow(@"\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"wsl$\Ubuntu-20.04\home\user\repo")] | ||
public void IsWslRepoNegativeTests(string repositoryPath) | ||
{ | ||
Assert.IsFalse(WslIntegrator.IsWSLRepo(repositoryPath)); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"\\wsl$\Ubuntu-20.04\home\user\repo", "Ubuntu-20.04")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-20.04\home\user\repo", "Ubuntu-20.04")] | ||
[DataRow(@"\\wsl$\Debian\home\user\repo", "Debian")] | ||
[DataRow(@"\\wsl.localhost\kali-linux\home\user\repo", "kali-linux")] | ||
[DataRow(@"\\wsl.localhost\UbuntuTest\home\user\testRepo", "UbuntuTest")] | ||
[DataRow(@"\\wsl$\CustomDistribution\home\user\testRepo", "CustomDistribution")] | ||
public void GetDistributionNamePositiveTest(string repositoryPath, string value) | ||
{ | ||
var distributionName = WslIntegrator.GetWslDistributionName(repositoryPath); | ||
Assert.AreEqual(value, distributionName); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"C:\Distribution\home\user\testRepo")] | ||
[DataRow(@"\\Ubuntu-18.04\wsl$\home\user\testRepo")] | ||
[DataRow(@"wslg\Ubuntu-18.04\wsl.localhost\home\user\testRepo")] | ||
[DataRow("")] | ||
[DataRow(@"\\wsl$")] | ||
[DataRow(@"\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"wsl$\Ubuntu-20.04\home\user\repo")] | ||
public void GetDistributionNameNegativeTest(string repositoryPath) | ||
{ | ||
Trace.Listeners.Clear(); | ||
Assert.ThrowsException<ArgumentException>(() => WslIntegrator.GetWslDistributionName(repositoryPath)); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"\\wsl$\Ubuntu-20.04\home\user\repo", @"\\wsl$\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-20.04\home\user\repo", @"\\wsl$\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"\\wsl$\Debian\home\user\repo", @"\\wsl$\Debian\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\kali-linux\home\user\repo", @"\\wsl$\kali-linux\home\user\repo")] | ||
[DataRow(@"\\wsl.localhost\customDistribution\home\user\testRepo", @"\\wsl$\customDistribution\home\user\testRepo")] | ||
[DataRow(@"\\wsl$\Ubuntu-18.04\home\user\dir1\dir2\DIR3\testRepo", @"\\wsl$\Ubuntu-18.04\home\user\dir1\dir2\DIR3\testRepo")] | ||
public void GetWorkingDirectoryPositiveTest(string repositoryPath, string value) | ||
{ | ||
var workingDirPath = WslIntegrator.GetWorkingDirectory(repositoryPath); | ||
Assert.AreEqual(value, workingDirPath); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"C:\Distribution\home\user\testRepo")] | ||
[DataRow(@"\\Ubuntu-18.04\wsl$\home\user\testRepo")] | ||
[DataRow(@"wslg\Ubuntu-18.04\wsl.localhost\home\user\testRepo")] | ||
[DataRow("")] | ||
[DataRow(@"\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"wsl$\Ubuntu-20.04\home\user\repo")] | ||
public void GetWorkingDirectoryNegativeTest(string repositoryPath) | ||
{ | ||
Trace.Listeners.Clear(); | ||
Assert.ThrowsException<ArgumentException>(() => WslIntegrator.GetWorkingDirectory(repositoryPath)); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"\\wsl$\Ubuntu-20.04\home\user\repo", "-d Ubuntu-20.04 git ")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-20.04\home\user\repo", "-d Ubuntu-20.04 git ")] | ||
[DataRow(@"\\wsl$\Debian\home\user\repo", "-d Debian git ")] | ||
[DataRow(@"\\wsl.localhost\kali-linux\home\user\repo", "-d kali-linux git ")] | ||
[DataRow(@"\\wsl$\Ubuntu-18.04\home\user\testRepo", "-d Ubuntu-18.04 git ")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-18.04\home\user\testRepo", "-d Ubuntu-18.04 git ")] | ||
[DataRow(@"\\wsl.localhost\CustomDistribution\home\user\testRepo", "-d CustomDistribution git ")] | ||
public void GetArgumentPrefixForWslPositiveTest(string repositoryPath, string value) | ||
{ | ||
var prefix = WslIntegrator.GetArgumentPrefixForWsl(repositoryPath); | ||
Assert.AreEqual(value, prefix); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow("")] | ||
[DataRow(@"\\wsl.localhost")] | ||
[DataRow(@"C:\Users\foo\bar")] | ||
[DataRow(@"\wsl.localhost\Ubuntu-20.04\home\user\repo")] | ||
[DataRow(@"wsl$\Ubuntu-20.04\home\user\repo")] | ||
public void GetArgumentPrefixForWslNegativeTest(string repositoryPath) | ||
{ | ||
Trace.Listeners.Clear(); | ||
Assert.ThrowsException<ArgumentException>(() => WslIntegrator.GetArgumentPrefixForWsl(repositoryPath)); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(@"\\wsl$\Ubuntu-20.04\home\user\repo", "/home/user/repo")] | ||
[DataRow(@"\\wsl.localhost\Ubuntu-20.04\home\user\repo", "/home/user/repo")] | ||
[DataRow(@"\\wsl$\Debian\home\user\repo", "/home/user/repo")] | ||
[DataRow(@"\\wsl.localhost\kali-linux\home\user\repo", "/home/user/repo")] | ||
[DataRow(@"\\WSL.LOCALHOST\UBUNTU-18.04\HOME\USER\TESTREPO", "/HOME/USER/TESTREPO")] | ||
[DataRow(@"\\WSL$\UBUNTU-18.04\HOME\USER\TESTREPO", "/HOME/USER/TESTREPO")] | ||
[DataRow(@"\\WSL.LOCALHOST\UBUNTU-18.04\HoME\USeR\TeSTREpO", "/HoME/USeR/TeSTREpO")] | ||
[DataRow(@"\\wsl.localhost\kali-linux\home\user\dir1\dir2\dir3\dir4\repo", "/home/user/dir1/dir2/dir3/dir4/repo")] | ||
[DataRow("", "")] | ||
public void GetNormalizedLinuxPathTest(string repositoryPath, string value) | ||
{ | ||
var normalizedPath = WslIntegrator.GetNormalizedLinuxPath(repositoryPath); | ||
Assert.AreEqual(value, normalizedPath); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
extensions/GitExtension/FileExplorerGitIntegration/Models/WslIntegrator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Diagnostics; | ||
using Serilog; | ||
|
||
namespace FileExplorerGitIntegration.Models; | ||
|
||
public class WslIntegrator | ||
{ | ||
private static readonly string[] _wslPathPrefixes = { @"\\wsl$\", @"\\wsl.localhost\" }; | ||
private static readonly ILogger _log = Log.ForContext<WslIntegrator>(); | ||
|
||
public static bool IsWSLRepo(string repositoryPath) | ||
{ | ||
if (string.IsNullOrEmpty(repositoryPath)) | ||
{ | ||
_log.Debug($"The repository path is empty"); | ||
return false; | ||
} | ||
|
||
if (repositoryPath.Contains(Path.AltDirectorySeparatorChar)) | ||
{ | ||
_log.Debug($"The repository path is not in the expected format: {repositoryPath}"); | ||
return false; | ||
} | ||
|
||
// Check if the repository path contains any of the WSL path prefixes | ||
foreach (string prefix in _wslPathPrefixes) | ||
{ | ||
if (repositoryPath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
return true; | ||
} | ||
} | ||
|
||
_log.Debug(repositoryPath + " is not a WSL path"); | ||
return false; | ||
} | ||
|
||
public static string GetWslDistributionName(string repositoryPath) | ||
{ | ||
if (string.IsNullOrEmpty(repositoryPath)) | ||
{ | ||
_log.Debug("The repository path is empty"); | ||
throw new ArgumentException("Repository path is empty"); | ||
} | ||
|
||
Debug.Assert(IsWSLRepo(repositoryPath), "the repository path must be a valid wsl path"); | ||
if (!IsWSLRepo(repositoryPath)) | ||
{ | ||
throw new ArgumentException($"Not a valid WSL path: {repositoryPath}"); | ||
} | ||
|
||
// Parse the repository path to get the distribution name | ||
string[] pathParts = repositoryPath.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); | ||
if (pathParts.Length > 1) | ||
{ | ||
return pathParts[1]; | ||
} | ||
|
||
_log.Debug($"Failed to get the distribution name from the repository path: {repositoryPath}"); | ||
throw new ArgumentException("Failed to get the distribution name from the repository path"); | ||
} | ||
|
||
public static string GetWorkingDirectory(string repositoryPath) | ||
{ | ||
if (string.IsNullOrEmpty(repositoryPath)) | ||
{ | ||
throw new ArgumentException("Repository path is empty"); | ||
} | ||
|
||
Debug.Assert(IsWSLRepo(repositoryPath), "the repository path must be a valid wsl path"); | ||
if (!IsWSLRepo(repositoryPath)) | ||
{ | ||
throw new ArgumentException($"Not a valid WSL path: {repositoryPath}"); | ||
} | ||
|
||
string[] pathParts = repositoryPath.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); | ||
|
||
// Ensure the first part is replaced with "\\wsl$" | ||
if (pathParts.Length > 0) | ||
{ | ||
pathParts[0] = Path.DirectorySeparatorChar + "\\wsl$"; | ||
} | ||
|
||
var workingDirPath = string.Join(Path.DirectorySeparatorChar.ToString(), pathParts); | ||
return workingDirPath; | ||
} | ||
|
||
public static string GetNormalizedLinuxPath(string repositoryPath) | ||
{ | ||
if (string.IsNullOrEmpty(repositoryPath)) | ||
{ | ||
_log.Debug("The repository path is empty"); | ||
return string.Empty; | ||
} | ||
|
||
string[] pathParts = repositoryPath.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); | ||
var workingDirPath = string.Join(Path.DirectorySeparatorChar.ToString(), pathParts.Skip(2)); | ||
workingDirPath = workingDirPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); | ||
workingDirPath = workingDirPath.Insert(0, Path.AltDirectorySeparatorChar.ToString()); | ||
return workingDirPath; | ||
} | ||
|
||
public static string GetArgumentPrefixForWsl(string repositoryPath) | ||
{ | ||
if (string.IsNullOrEmpty(repositoryPath)) | ||
{ | ||
throw new ArgumentException("Repository path is empty"); | ||
} | ||
|
||
Debug.Assert(IsWSLRepo(repositoryPath), "the repository path must be a valid wsl path"); | ||
if (!IsWSLRepo(repositoryPath)) | ||
{ | ||
throw new ArgumentException($"Not a valid WSL path: {repositoryPath}"); | ||
} | ||
|
||
return $"-d {GetWslDistributionName(repositoryPath)} git "; | ||
} | ||
} |