Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1982 from github/fixes/1981-open-from-github-clon…
Browse files Browse the repository at this point in the history
…e-2015

Fix cloning using Open From GitHub on Visual Studio 2015
  • Loading branch information
jcansdale authored Oct 11, 2018
2 parents b2385e6 + dd94727 commit c38cd21
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/GitHub.App/Services/RepositoryCloneService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public async Task CloneOrOpenRepository(
}
}

// Give user a chance to choose a solution
teamExplorerServices.ShowHomePage();
}

Expand Down
5 changes: 3 additions & 2 deletions src/GitHub.Exports/Services/VSServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ public bool TryOpenRepository(string repoPath)
return false;
}

var repoDir = os.Directory.GetDirectory(repoPath);
if (!repoDir.Exists)
var gitPath = Path.Combine(repoPath, ".git");
var gitDir = os.Directory.GetDirectory(gitPath);
if (!gitDir.Exists)
{
return false;
}
Expand Down
32 changes: 0 additions & 32 deletions src/GitHub.StartPage/StartPagePackage.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
Expand All @@ -9,7 +8,6 @@
using GitHub.Primitives;
using GitHub.Services;
using GitHub.VisualStudio;
using Microsoft.TeamFoundation.Controls;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.CodeContainerManagement;
using Microsoft.VisualStudio.Threading;
Expand Down Expand Up @@ -59,7 +57,6 @@ async Task<CodeContainer> RunAcquisition(IProgress<ServiceProgressData> download
try
{
var uiProvider = await Task.Run(() => Package.GetGlobalService(typeof(IGitHubServiceProvider)) as IGitHubServiceProvider);
await ShowTeamExplorerPage(uiProvider);
request = await ShowCloneDialog(uiProvider, downloadProgress, repository);
}
catch (Exception e)
Expand All @@ -84,35 +81,6 @@ async Task<CodeContainer> RunAcquisition(IProgress<ServiceProgressData> download
lastAccessed: DateTimeOffset.UtcNow);
}

async Task ShowTeamExplorerPage(IGitHubServiceProvider gitHubServiceProvider)
{
var te = gitHubServiceProvider?.GetService(typeof(ITeamExplorer)) as ITeamExplorer;

if (te != null)
{
var page = te.NavigateToPage(new Guid(TeamExplorerPageIds.Connect), null);

if (page == null)
{
var tcs = new TaskCompletionSource<ITeamExplorerPage>();
PropertyChangedEventHandler handler = null;

handler = new PropertyChangedEventHandler((s, e) =>
{
if (e.PropertyName == "CurrentPage")
{
tcs.SetResult(te.CurrentPage);
te.PropertyChanged -= handler;
}
});

te.PropertyChanged += handler;

page = await tcs.Task;
}
}
}

async Task<CloneDialogResult> ShowCloneDialog(
IGitHubServiceProvider gitHubServiceProvider,
IProgress<ServiceProgressData> progress,
Expand Down
83 changes: 64 additions & 19 deletions src/GitHub.TeamFoundation.14/Services/VSGitServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#endif

using System;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel.Composition;
using System.Globalization;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
Expand All @@ -17,15 +17,12 @@
using GitHub.Models;
using GitHub.TeamFoundation;
using GitHub.VisualStudio;
#if TEAMEXPLORER14
using Microsoft.TeamFoundation.Controls;
using Microsoft.TeamFoundation.Git.Controls.Extensibility;
using ReactiveUI;
#else
using Microsoft.VisualStudio.Shell.Interop;
using System.Threading;
#endif
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
using ReactiveUI;
using Serilog;
using Microsoft;

namespace GitHub.Services
{
Expand All @@ -39,6 +36,8 @@ public class VSGitServices : IVSGitServices

[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used in VS2017")]
readonly Lazy<IStatusBarNotificationService> statusBar;
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used in VS2015")]
readonly Lazy<IVSServices> vsServices;

/// <summary>
/// This MEF export requires specific versions of TeamFoundation. IGitExt is declared here so
Expand All @@ -49,10 +48,13 @@ public class VSGitServices : IVSGitServices
IGitExt gitExtService;

[ImportingConstructor]
public VSGitServices(IGitHubServiceProvider serviceProvider, Lazy<IStatusBarNotificationService> statusBar)
public VSGitServices(IGitHubServiceProvider serviceProvider,
Lazy<IStatusBarNotificationService> statusBar,
Lazy<IVSServices> vsServices)
{
this.serviceProvider = serviceProvider;
this.statusBar = statusBar;
this.vsServices = vsServices;
}

// The Default Repository Path that VS uses is hidden in an internal
Expand Down Expand Up @@ -81,25 +83,68 @@ public async Task Clone(
bool recurseSubmodules,
object progress = null)
{
#if TEAMEXPLORER14
var gitExt = serviceProvider.GetService<IGitRepositoriesExt>();
gitExt.Clone(cloneUrl, clonePath, recurseSubmodules ? CloneOptions.RecurseSubmodule : CloneOptions.None);
var teamExplorer = serviceProvider.TryGetService<ITeamExplorer>();
Assumes.Present(teamExplorer);

// The operation will have completed when CanClone goes false and then true again.
await gitExt.WhenAnyValue(x => x.CanClone).Where(x => !x).Take(1);
await gitExt.WhenAnyValue(x => x.CanClone).Where(x => x).Take(1);
#if TEAMEXPLORER14
await StartClonenOnConnectPageAsync(teamExplorer, cloneUrl, clonePath, recurseSubmodules);
NavigateToHomePage(teamExplorer); // Show progress on Team Explorer - Home
await WaitForCloneOnHomePageAsync(teamExplorer);
vsServices.Value.TryOpenRepository(clonePath); // Show the repository on Team Explorer - Home
#else
var gitExt = serviceProvider.GetService<IGitActionsExt>();
var typedProgress = ((Progress<ServiceProgressData>)progress) ?? new Progress<ServiceProgressData>();
typedProgress.ProgressChanged += (s, e) => statusBar.Value.ShowMessage(e.ProgressText);
var cloneTask = gitExt.CloneAsync(cloneUrl, clonePath, recurseSubmodules, default(CancellationToken), typedProgress);

await Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
typedProgress.ProgressChanged += (s, e) => statusBar.Value.ShowMessage(e.ProgressText);
await gitExt.CloneAsync(cloneUrl, clonePath, recurseSubmodules, default(CancellationToken), typedProgress);
});
NavigateToHomePage(teamExplorer); // Show progress on Team Explorer - Home
await cloneTask;
#endif
}

static async Task StartClonenOnConnectPageAsync(
ITeamExplorer teamExplorer, string cloneUrl, string clonePath, bool recurseSubmodules)
{
var connectPage = await NavigateToPageAsync(teamExplorer, new Guid(TeamExplorerPageIds.Connect));
Assumes.Present(connectPage);
var gitExt = connectPage.GetService<IGitRepositoriesExt>();
Assumes.Present(gitExt);

gitExt.Clone(cloneUrl, clonePath, recurseSubmodules ? CloneOptions.RecurseSubmodule : CloneOptions.None);
}

static async Task WaitForCloneOnHomePageAsync(ITeamExplorer teamExplorer)
{
// The clone progress bar appears on the GettingStartedSection of the Home page,
// so we wait for this to be hidden before continuing.
var sectionId = new Guid("d0200918-c025-4cc3-9dee-4f5e89d0c918"); // GettingStartedSection
await teamExplorer
.WhenAnyValue(x => x.CurrentPage)
.Where(p => p.GetId() == new Guid(TeamExplorerPageIds.Home))
.Select(p => p.GetSection(sectionId))
.Where(s => s != null)
.Select(s => s.WhenAnyValue(x => x.IsVisible))
.Switch() // Watch the topmost section
.StartWith(false) // If no events arrive default to invisible
.Throttle(TimeSpan.FromSeconds(1)) // Ignore glitch where section starts invisible
.Any(x => x == false);
}

static void NavigateToHomePage(ITeamExplorer teamExplorer)
{
teamExplorer.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null);
}

static async Task<ITeamExplorerPage> NavigateToPageAsync(ITeamExplorer teamExplorer, Guid pageId)
{
teamExplorer.NavigateToPage(pageId, null);
var page = await teamExplorer
.WhenAnyValue(x => x.CurrentPage)
.Where(x => x?.GetId() == pageId)
.Take(1);
return page;
}

IGitRepositoryInfo GetRepoFromVS()
{
gitExtService = serviceProvider.GetService<IGitExt>();
Expand Down
3 changes: 2 additions & 1 deletion test/GitHub.Exports.UnitTests/VSServicesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ VSServices CreateVSServices(string repoDir, IOperatingSystem os = null, DTE dte

if (repoDir != null)
{
var gitDir = Path.Combine(repoDir, ".git");
var directoryInfo = Substitute.For<IDirectoryInfo>();
directoryInfo.Exists.Returns(repoDirExists);
os.Directory.GetDirectory(repoDir).Returns(directoryInfo);
os.Directory.GetDirectory(gitDir).Returns(directoryInfo);
}

var provider = Substitute.For<IGitHubServiceProvider>();
Expand Down

0 comments on commit c38cd21

Please sign in to comment.