Handle situation when repo has moved

If user tries to open a repo dir that no longer exists, let them find and open the solution manually.
There is no need to reset the selected repo if opening solution fails.
This commit is contained in:
Jamie Cansdale 2017-02-14 23:30:51 +00:00
Родитель 121d09adc8
Коммит 1ba5aafc8f
3 изменённых файлов: 49 добавлений и 22 удалений

Просмотреть файл

@ -83,6 +83,13 @@ namespace GitHub.Services
/// <returns>True if a transient solution was successfully created in target directory (which should trigger opening of repository).</returns> /// <returns>True if a transient solution was successfully created in target directory (which should trigger opening of repository).</returns>
public bool TryOpenRepository(string repoPath) public bool TryOpenRepository(string repoPath)
{ {
var os = serviceProvider.TryGetService<IOperatingSystem>();
if (os == null)
{
VsOutputLogger.WriteLine("TryOpenRepository couldn't find IOperatingSystem service.");
return false;
}
var dte = serviceProvider.TryGetService<DTE>(); var dte = serviceProvider.TryGetService<DTE>();
if (dte == null) if (dte == null)
{ {
@ -90,12 +97,16 @@ namespace GitHub.Services
return false; return false;
} }
bool solutionCreated = false; var repoDir = os.Directory.GetDirectory(repoPath);
const string slnName = TempSolutionName; if(!repoDir.Exists)
{
return false;
}
bool solutionCreated = false;
try try
{ {
dte.Solution.Create(repoPath, slnName); dte.Solution.Create(repoPath, TempSolutionName);
solutionCreated = true; solutionCreated = true;
dte.Solution.Close(false); // Don't create a .sln file when we close. dte.Solution.Close(false); // Don't create a .sln file when we close.
@ -106,21 +117,13 @@ namespace GitHub.Services
} }
finally finally
{ {
TryCleanupSolutionUserFiles(repoPath, slnName); TryCleanupSolutionUserFiles(os, repoPath, TempSolutionName);
} }
return solutionCreated; return solutionCreated;
} }
void TryCleanupSolutionUserFiles(string repoPath, string slnName) void TryCleanupSolutionUserFiles(IOperatingSystem os, string repoPath, string slnName)
{ {
var os = serviceProvider.TryGetService<IOperatingSystem>();
if (os == null)
{
VsOutputLogger.WriteLine("TryOpenRepository couldn't find IOperatingSystem service.");
return;
}
var vsTempPath = Path.Combine(repoPath, ".vs", slnName); var vsTempPath = Path.Combine(repoPath, ".vs", slnName);
try try
{ {

Просмотреть файл

@ -353,11 +353,10 @@ namespace GitHub.VisualStudio.TeamExplorer.Connect
var opened = vsServices.TryOpenRepository(SelectedRepository.LocalPath); var opened = vsServices.TryOpenRepository(SelectedRepository.LocalPath);
if (!opened) if (!opened)
{ {
// Fall back to making the user select a solution to open. // TryOpenRepository might fail because dir no longer exists. Let user find solution themselves.
opened = ErrorHandler.Succeeded(ServiceProvider.GetSolution().OpenSolutionViaDlg(SelectedRepository.LocalPath, 1)); opened = ErrorHandler.Succeeded(ServiceProvider.GetSolution().OpenSolutionViaDlg(SelectedRepository.LocalPath, 1));
if (!opened) if (!opened)
{ {
SelectedRepository = old;
return false; return false;
} }
} }

Просмотреть файл

@ -14,9 +14,10 @@ public class VSServicesTests
[Fact] [Fact]
public void NoExceptions_ReturnsTrue() public void NoExceptions_ReturnsTrue()
{ {
var target = CreateVSServices(); var repoDir = @"x:\repo";
var target = CreateVSServices(repoDir);
var success = target.TryOpenRepository(""); var success = target.TryOpenRepository(repoDir);
Assert.True(success); Assert.True(success);
} }
@ -24,16 +25,32 @@ public class VSServicesTests
[Fact] [Fact]
public void SolutionCreateThrows_ReturnsFalse() public void SolutionCreateThrows_ReturnsFalse()
{ {
var repoDir = @"x:\repo";
var dte = Substitute.For<DTE>(); var dte = Substitute.For<DTE>();
dte.Solution.When(s => s.Create(Arg.Any<string>(), Arg.Any<string>())).Do( dte.Solution.When(s => s.Create(Arg.Any<string>(), Arg.Any<string>())).Do(
ci => { throw new COMException(); }); ci => { throw new COMException(); });
var target = CreateVSServices(dte: dte); var target = CreateVSServices(repoDir, dte: dte);
var success = target.TryOpenRepository(""); var success = target.TryOpenRepository("");
Assert.False(success); Assert.False(success);
} }
[Fact]
public void RepoDirExistsFalse_ReturnFalse()
{
var repoDir = @"x:\repo";
var os = Substitute.For<IOperatingSystem>();
//var directoryInfo = Substitute.For<IDirectoryInfo>();
//directoryInfo.Exists.Returns(false);
//os.Directory.GetDirectory(repoDir).Returns(directoryInfo);
var target = CreateVSServices(null, os: os);
var success = target.TryOpenRepository(repoDir);
Assert.False(success);
}
[Fact] [Fact]
public void DeleteThrowsIOException_ReturnTrue() public void DeleteThrowsIOException_ReturnTrue()
{ {
@ -43,9 +60,9 @@ public class VSServicesTests
var directoryInfo = Substitute.For<IDirectoryInfo>(); var directoryInfo = Substitute.For<IDirectoryInfo>();
directoryInfo.Exists.Returns(true); directoryInfo.Exists.Returns(true);
os.Directory.GetDirectory(tempDir).Returns(directoryInfo); os.Directory.GetDirectory(tempDir).Returns(directoryInfo);
directoryInfo.When(di => di.Delete(true)).Do( directoryInfo.When(di => di.Delete(true)).Do(
ci => { throw new IOException(); }); ci => { throw new IOException(); });
var target = CreateVSServices(os: os); var target = CreateVSServices(repoDir, os: os);
var success = target.TryOpenRepository(repoDir); var success = target.TryOpenRepository(repoDir);
@ -61,17 +78,25 @@ public class VSServicesTests
var directoryInfo = Substitute.For<IDirectoryInfo>(); var directoryInfo = Substitute.For<IDirectoryInfo>();
directoryInfo.Exists.Returns(true); directoryInfo.Exists.Returns(true);
os.Directory.GetDirectory(tempDir).Returns(directoryInfo); os.Directory.GetDirectory(tempDir).Returns(directoryInfo);
var target = CreateVSServices(os: os); var target = CreateVSServices(repoDir, os: os);
var success = target.TryOpenRepository(repoDir); var success = target.TryOpenRepository(repoDir);
directoryInfo.Received().Delete(true); directoryInfo.Received().Delete(true);
} }
VSServices CreateVSServices(IOperatingSystem os = null, DTE dte = null) VSServices CreateVSServices(string repoDir, IOperatingSystem os = null, DTE dte = null)
{ {
os = os ?? Substitute.For<IOperatingSystem>(); os = os ?? Substitute.For<IOperatingSystem>();
dte = dte ?? Substitute.For<DTE>(); dte = dte ?? Substitute.For<DTE>();
if (repoDir != null)
{
var directoryInfo = Substitute.For<IDirectoryInfo>();
directoryInfo.Exists.Returns(true);
os.Directory.GetDirectory(repoDir).Returns(directoryInfo);
}
var provider = Substitute.For<IGitHubServiceProvider>(); var provider = Substitute.For<IGitHubServiceProvider>();
provider.TryGetService<DTE>().Returns(dte); provider.TryGetService<DTE>().Returns(dte);
provider.TryGetService<IOperatingSystem>().Returns(os); provider.TryGetService<IOperatingSystem>().Returns(os);