From 527b1d134f334e3210d07be04c3a3de491f65bee Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Wed, 26 Sep 2018 13:48:57 +0100 Subject: [PATCH] Sanity check local repository Check the following conditions: - Local repository exists at path - Local repository has an 'origin' remote - Local repository's URL matches selected repository --- .../Clone/RepositoryCloneViewModelDesigner.cs | 1 + .../Dialog/Clone/RepositoryCloneViewModel.cs | 47 ++++++++++++++++++- .../Dialog/Clone/IRepositoryCloneViewModel.cs | 5 ++ .../Dialog/Clone/RepositoryCloneView.xaml | 4 ++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/GitHub.App/SampleData/Dialog/Clone/RepositoryCloneViewModelDesigner.cs b/src/GitHub.App/SampleData/Dialog/Clone/RepositoryCloneViewModelDesigner.cs index 1fbe04d9e..35d392f8d 100644 --- a/src/GitHub.App/SampleData/Dialog/Clone/RepositoryCloneViewModelDesigner.cs +++ b/src/GitHub.App/SampleData/Dialog/Clone/RepositoryCloneViewModelDesigner.cs @@ -17,6 +17,7 @@ namespace GitHub.SampleData.Dialog.Clone public string Path { get; set; } public string PathError { get; set; } + public string PathWarning { get; set; } public int SelectedTabIndex { get; set; } public string Title => null; public IObservable Done => null; diff --git a/src/GitHub.App/ViewModels/Dialog/Clone/RepositoryCloneViewModel.cs b/src/GitHub.App/ViewModels/Dialog/Clone/RepositoryCloneViewModel.cs index 8510763dd..84122b9b5 100644 --- a/src/GitHub.App/ViewModels/Dialog/Clone/RepositoryCloneViewModel.cs +++ b/src/GitHub.App/ViewModels/Dialog/Clone/RepositoryCloneViewModel.cs @@ -23,12 +23,14 @@ namespace GitHub.ViewModels.Dialog.Clone readonly IOperatingSystem os; readonly IConnectionManager connectionManager; readonly IRepositoryCloneService service; + readonly IGitService gitService; readonly IUsageService usageService; readonly IUsageTracker usageTracker; readonly IReadOnlyList tabs; string path; IRepositoryModel previousRepository; ObservableAsPropertyHelper pathError; + ObservableAsPropertyHelper pathWarning; int selectedTabIndex; [ImportingConstructor] @@ -36,6 +38,7 @@ namespace GitHub.ViewModels.Dialog.Clone IOperatingSystem os, IConnectionManager connectionManager, IRepositoryCloneService service, + IGitService gitService, IUsageService usageService, IUsageTracker usageTracker, IRepositorySelectViewModel gitHubTab, @@ -45,6 +48,7 @@ namespace GitHub.ViewModels.Dialog.Clone this.os = os; this.connectionManager = connectionManager; this.service = service; + this.gitService = gitService; this.usageService = usageService; this.usageTracker = usageTracker; @@ -62,9 +66,15 @@ namespace GitHub.ViewModels.Dialog.Clone pathError = Observable.CombineLatest( repository, this.WhenAnyValue(x => x.Path), - ValidatePath) + ValidatePathError) .ToProperty(this, x => x.PathError); + pathWarning = Observable.CombineLatest( + repository, + this.WhenAnyValue(x => x.Path), + ValidatePathWarning) + .ToProperty(this, x => x.PathWarning); + var canClone = Observable.CombineLatest( repository, this.WhenAnyValue(x => x.Path), this.WhenAnyValue(x => x.PathError), (repo, path, error) => repo != null && error == null && !service.DestinationDirectoryExists(path)); @@ -94,6 +104,8 @@ namespace GitHub.ViewModels.Dialog.Clone public string PathError => pathError.Value; + public string PathWarning => pathWarning.Value; + public int SelectedTabIndex { get => selectedTabIndex; @@ -235,7 +247,7 @@ namespace GitHub.ViewModels.Dialog.Clone } } - string ValidatePath(IRepositoryModel repository, string path) + string ValidatePathError(IRepositoryModel repository, string path) { if (repository != null) { @@ -246,5 +258,36 @@ namespace GitHub.ViewModels.Dialog.Clone return null; } + + string ValidatePathWarning(IRepositoryModel repositoryModel, string path) + { + if (repositoryModel != null) + { + if (service.DestinationDirectoryExists(path)) + { + using (var repository = gitService.GetRepository(path)) + { + if (repository == null) + { + return $"Can't find a repository at local path"; + } + + var localUrl = gitService.GetRemoteUri(repository)?.ToRepositoryUrl(); + if (localUrl == null) + { + return $"Local repository doesn't have an 'origin' remote"; + } + + var targetUrl = repositoryModel.CloneUrl?.ToRepositoryUrl(); + if (localUrl != targetUrl) + { + return $"Local repository has a remote of {localUrl}"; + } + } + } + } + + return null; + } } } diff --git a/src/GitHub.Exports.Reactive/ViewModels/Dialog/Clone/IRepositoryCloneViewModel.cs b/src/GitHub.Exports.Reactive/ViewModels/Dialog/Clone/IRepositoryCloneViewModel.cs index 97c09039b..ba6d41c97 100644 --- a/src/GitHub.Exports.Reactive/ViewModels/Dialog/Clone/IRepositoryCloneViewModel.cs +++ b/src/GitHub.Exports.Reactive/ViewModels/Dialog/Clone/IRepositoryCloneViewModel.cs @@ -34,6 +34,11 @@ namespace GitHub.ViewModels.Dialog.Clone /// string PathError { get; } + /// + /// Gets a warning message that explains why is suspect. + /// + string PathWarning { get; } + /// /// Gets the index of the selected tab. /// diff --git a/src/GitHub.VisualStudio/Views/Dialog/Clone/RepositoryCloneView.xaml b/src/GitHub.VisualStudio/Views/Dialog/Clone/RepositoryCloneView.xaml index 28dcfa522..9678d75d3 100644 --- a/src/GitHub.VisualStudio/Views/Dialog/Clone/RepositoryCloneView.xaml +++ b/src/GitHub.VisualStudio/Views/Dialog/Clone/RepositoryCloneView.xaml @@ -55,6 +55,10 @@ + +