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

Commit 3b923d8

Browse files
authored
Merge branch 'master' into fixes/551-link-to-button
2 parents bd3b46a + 0328c97 commit 3b923d8

File tree

12 files changed

+258
-47
lines changed

12 files changed

+258
-47
lines changed

src/GitHub.App/Services/GitClient.cs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Reactive;
55
using System.Reactive.Linq;
6+
using System.Threading.Tasks;
67
using GitHub.Extensions;
78
using GitHub.Primitives;
89
using LibGit2Sharp;
@@ -23,65 +24,61 @@ public GitClient(IGitHubCredentialProvider credentialProvider)
2324
fetchOptions = new FetchOptions { CredentialsProvider = credentialProvider.HandleCredentials };
2425
}
2526

26-
public IObservable<Unit> Push(IRepository repository, string branchName, string remoteName)
27+
public Task Push(IRepository repository, string branchName, string remoteName)
2728
{
2829
Guard.ArgumentNotEmptyString(branchName, nameof(branchName));
2930
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));
3031

31-
return Observable.Defer(() =>
32+
return Task.Factory.StartNew(() =>
3233
{
3334
if (repository.Head?.Commits != null && repository.Head.Commits.Any())
3435
{
3536
var remote = repository.Network.Remotes[remoteName];
3637
repository.Network.Push(remote, "HEAD", @"refs/heads/" + branchName, pushOptions);
3738
}
38-
return Observable.Return(Unit.Default);
3939
});
4040
}
4141

42-
public IObservable<Unit> Fetch(IRepository repository, string remoteName)
42+
public Task Fetch(IRepository repository, string remoteName)
4343
{
4444
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));
4545

46-
return Observable.Defer(() =>
46+
return Task.Factory.StartNew(() =>
4747
{
4848
var remote = repository.Network.Remotes[remoteName];
4949
repository.Network.Fetch(remote, fetchOptions);
50-
return Observable.Return(Unit.Default);
5150
});
5251
}
5352

54-
public IObservable<Unit> Fetch(IRepository repository, string remoteName, params string[] refspecs)
53+
public Task Fetch(IRepository repository, string remoteName, params string[] refspecs)
5554
{
5655
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));
5756

58-
return Observable.Defer(() =>
57+
return Task.Factory.StartNew(() =>
5958
{
6059
var remote = repository.Network.Remotes[remoteName];
6160
repository.Network.Fetch(remote, refspecs, fetchOptions);
62-
return Observable.Return(Unit.Default);
6361
});
6462
}
6563

66-
public IObservable<Unit> SetRemote(IRepository repository, string remoteName, Uri url)
64+
public Task SetRemote(IRepository repository, string remoteName, Uri url)
6765
{
6866
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));
6967

70-
return Observable.Defer(() =>
68+
return Task.Factory.StartNew(() =>
7169
{
70+
7271
repository.Config.Set("remote." + remoteName + ".url", url.ToString());
7372
repository.Config.Set("remote." + remoteName + ".fetch", "+refs/heads/*:refs/remotes/" + remoteName + "/*");
74-
75-
return Observable.Return(Unit.Default);
7673
});
7774
}
7875

79-
public IObservable<Unit> SetTrackingBranch(IRepository repository, string branchName, string remoteName)
76+
public Task SetTrackingBranch(IRepository repository, string branchName, string remoteName)
8077
{
8178
Guard.ArgumentNotEmptyString(branchName, nameof(branchName));
8279
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));
8380

84-
return Observable.Defer(() =>
81+
return Task.Factory.StartNew(() =>
8582
{
8683
var remoteBranchName = IsCanonical(remoteName) ? remoteName : "refs/remotes/" + remoteName + "/" + branchName;
8784
var remoteBranch = repository.Branches[remoteBranchName];
@@ -92,21 +89,21 @@ public IObservable<Unit> SetTrackingBranch(IRepository repository, string branch
9289
var localBranch = repository.Branches[localBranchName];
9390
repository.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName);
9491
}
95-
return Observable.Return(Unit.Default);
9692
});
9793
}
9894

99-
public IObservable<Remote> GetHttpRemote(IRepository repo, string remote)
95+
public Task<Remote> GetHttpRemote(IRepository repo, string remote)
10096
{
101-
return Observable.Defer(() => Observable.Return(GitService.GitServiceHelper.GetRemoteUri(repo, remote)))
102-
.Select(uri => new { Remote = uri.IsHypertextTransferProtocol ? remote : remote + "-http", Uri = uri })
103-
.Select(r =>
104-
{
105-
var ret = repo.Network.Remotes[r.Remote];
106-
if (ret == null)
107-
ret = repo.Network.Remotes.Add(r.Remote, UriString.ToUriString(r.Uri.ToRepositoryUrl()));
108-
return ret;
109-
});
97+
return Task.Factory.StartNew(() =>
98+
{
99+
100+
var uri = GitService.GitServiceHelper.GetRemoteUri(repo, remote);
101+
var remoteName = uri.IsHypertextTransferProtocol ? remote : remote + "-http";
102+
var ret = repo.Network.Remotes[remoteName];
103+
if (ret == null)
104+
ret = repo.Network.Remotes.Add(remoteName, UriString.ToUriString(uri.ToRepositoryUrl()));
105+
return ret;
106+
});
110107
}
111108

112109
static bool IsCanonical(string s)

src/GitHub.App/Services/RepositoryPublishService.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.ComponentModel.Composition;
33
using System.IO;
44
using System.Reactive.Linq;
5+
using System.Reactive.Threading.Tasks;
56
using GitHub.Api;
67
using GitHub.Models;
78
using LibGit2Sharp;
@@ -38,11 +39,16 @@ public string LocalRepositoryName
3839
IApiClient apiClient)
3940
{
4041
return Observable.Defer(() => apiClient.CreateRepository(newRepository, account.Login, account.IsUser)
41-
.Select(remoteRepo => new { RemoteRepo = remoteRepo, LocalRepo = activeRepository }))
42-
.SelectMany(repo => gitClient.SetRemote(repo.LocalRepo, "origin", new Uri(repo.RemoteRepo.CloneUrl)).Select(_ => repo))
43-
.SelectMany(repo => gitClient.Push(repo.LocalRepo, "master", "origin").Select(_ => repo))
44-
.SelectMany(repo => gitClient.Fetch(repo.LocalRepo, "origin").Select(_ => repo))
45-
.SelectMany(repo => gitClient.SetTrackingBranch(repo.LocalRepo, "master", "origin").Select(_ => repo.RemoteRepo));
42+
.Select(remoteRepo => new { RemoteRepo = remoteRepo, LocalRepo = activeRepository }))
43+
.Select(async repo =>
44+
{
45+
await gitClient.SetRemote(repo.LocalRepo, "origin", new Uri(repo.RemoteRepo.CloneUrl));
46+
await gitClient.Push(repo.LocalRepo, "master", "origin");
47+
await gitClient.Fetch(repo.LocalRepo, "origin");
48+
await gitClient.SetTrackingBranch(repo.LocalRepo, "master", "origin");
49+
return repo.RemoteRepo;
50+
})
51+
.Select(t => t.Result);
4652
}
4753
}
4854
}

src/GitHub.App/ViewModels/RepositoryCloneViewModel.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ public RepositoryCloneViewModel(
7575
repositories.Filter = FilterRepository;
7676
repositories.NewerComparer = OrderedComparer<IRemoteRepositoryModel>.OrderByDescending(x => x.UpdatedAt).Compare;
7777

78-
filterTextIsEnabled = this.WhenAny(x => x.IsLoading, x => x.Value)
79-
.Select(x => !x && repositories.UnfilteredCount > 0)
78+
filterTextIsEnabled = this.WhenAny(x => x.IsLoading,
79+
loading => loading.Value || repositories.UnfilteredCount > 0 && !LoadingFailed)
8080
.ToProperty(this, x => x.FilterTextIsEnabled);
8181

82-
this.WhenAny(x => x.FilterTextIsEnabled, x => x.IsLoading, x => x.LoadingFailed
83-
, (any, loading, failed) => !any.Value && !loading.Value && !failed.Value)
82+
this.WhenAny(x => x.IsLoading, x => x.LoadingFailed,
83+
(loading, failed) => !loading.Value && !failed.Value && repositories.UnfilteredCount == 0)
8484
.Subscribe(x => NoRepositoriesFound = x);
8585

8686
this.WhenAny(x => x.FilterText, x => x.Value)

src/GitHub.Exports.Reactive/Services/IGitClient.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Reactive;
2+
using System.Threading.Tasks;
33
using LibGit2Sharp;
44

55
namespace GitHub.Services
@@ -13,15 +13,15 @@ public interface IGitClient
1313
/// <param name="remoteName">The name of the remote</param>
1414
/// <param name="branchName">the branch to pull</param>
1515
/// <returns></returns>
16-
IObservable<Unit> Push(IRepository repository, string branchName, string remoteName);
16+
Task Push(IRepository repository, string branchName, string remoteName);
1717

1818
/// <summary>
1919
/// Fetches the remote.
2020
/// </summary>
2121
/// <param name="repository">The repository to pull</param>
2222
/// <param name="remoteName">The name of the remote</param>
2323
/// <returns></returns>
24-
IObservable<Unit> Fetch(IRepository repository, string remoteName);
24+
Task Fetch(IRepository repository, string remoteName);
2525

2626
/// <summary>
2727
/// Fetches from the remote, using custom refspecs.
@@ -30,7 +30,7 @@ public interface IGitClient
3030
/// <param name="remoteName">The name of the remote</param>
3131
/// <param name="refspecs">The custom refspecs</param>
3232
/// <returns></returns>
33-
IObservable<Unit> Fetch(IRepository repository, string remoteName, params string[] refspecs);
33+
Task Fetch(IRepository repository, string remoteName, params string[] refspecs);
3434

3535
/// <summary>
3636
/// Sets the specified remote to the specified URL.
@@ -39,7 +39,7 @@ public interface IGitClient
3939
/// <param name="remoteName">The name of the remote</param>
4040
/// <param name="url">The URL to set as the remote</param>
4141
/// <returns></returns>
42-
IObservable<Unit> SetRemote(IRepository repository, string remoteName, Uri url);
42+
Task SetRemote(IRepository repository, string remoteName, Uri url);
4343

4444
/// <summary>
4545
/// Sets the remote branch that the local branch tracks
@@ -48,8 +48,8 @@ public interface IGitClient
4848
/// <param name="branchName">The name of the local remote</param>
4949
/// <param name="remoteName">The name of the remote branch</param>
5050
/// <returns></returns>
51-
IObservable<Unit> SetTrackingBranch(IRepository repository, string branchName, string remoteName);
51+
Task SetTrackingBranch(IRepository repository, string branchName, string remoteName);
5252

53-
IObservable<Remote> GetHttpRemote(IRepository repo, string remote);
53+
Task<Remote> GetHttpRemote(IRepository repo, string remote);
5454
}
5555
}

src/GitHub.VisualStudio/PkgCmdID.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// MUST match PkgCmdID.h
33
namespace GitHub.VisualStudio
44
{
5-
static class PkgCmdIDList
5+
public static class PkgCmdIDList
66
{
77
public const int addConnectionCommand = 0x110;
88
public const int idGitHubToolbar = 0x1120;

src/GitHub.VisualStudio/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
[assembly: AssemblyTitle("GitHub.VisualStudio")]
55
[assembly: AssemblyDescription("GitHub for Visual Studio VSPackage")]
6-
[assembly: Guid("fad77eaa-3fe1-4c4b-88dc-3753b6263cd7")]
6+
[assembly: Guid("fad77eaa-3fe1-4c4b-88dc-3753b6263cd7")]

src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ void StartFlow(UIControllerFlow controllerFlow, [AllowNull]IConnection conn, Vie
279279
void GoForward(ViewWithData data)
280280
{
281281
currentNavItem++;
282-
if (currentNavItem < navStack.Count - 1)
283-
navStack.RemoveRange(currentNavItem, navStack.Count - 1 - currentNavItem);
282+
if (currentNavItem < navStack.Count)
283+
navStack.RemoveRange(currentNavItem, navStack.Count - currentNavItem);
284284
navStack.Add(data);
285285
}
286286

src/UnitTests/GitHub.App/ViewModels/PullRequestCreationViewModelTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static LibGit2Sharp.IRepository SetupLocalRepoMock(IGitClient gitClient, IGitSer
2323
{
2424
var l2remote = Substitute.For<LibGit2Sharp.Remote>();
2525
l2remote.Name.Returns(remote);
26-
gitClient.GetHttpRemote(Args.LibGit2Repo, Args.String).Returns(Observable.Return(l2remote));
26+
gitClient.GetHttpRemote(Args.LibGit2Repo, Args.String).Returns(Task.FromResult(l2remote));
2727

2828
var l2repo = Substitute.For<LibGit2Sharp.IRepository>();
2929
var l2branchcol = Substitute.For<LibGit2Sharp.BranchCollection>();

src/UnitTests/GitHub.App/ViewModels/RepositoryCloneViewModelTests.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,74 @@ public void IsTrueWhenLoadingCompleteNotFailedAndNoRepositories()
209209
}
210210
}
211211

212+
public class TheFilterTextEnabledProperty : TestBaseClass
213+
{
214+
[Fact]
215+
public void IsTrueInitially()
216+
{
217+
var repoSubject = new Subject<IRemoteRepositoryModel>();
218+
var col = TrackingCollection.Create(repoSubject);
219+
var repositoryHost = Substitute.For<IRepositoryHost>();
220+
repositoryHost.ModelService.GetRepositories(Arg.Any<ITrackingCollection<IRemoteRepositoryModel>>()).Returns(_ => col);
221+
var cloneService = Substitute.For<IRepositoryCloneService>();
222+
223+
var vm = GetVM(
224+
repositoryHost,
225+
cloneService,
226+
Substitute.For<IOperatingSystem>(),
227+
Substitute.For<INotificationService>(),
228+
Substitute.For<IUsageTracker>());
229+
230+
Assert.False(vm.LoadingFailed);
231+
Assert.True(vm.FilterTextIsEnabled);
232+
}
233+
234+
[Fact]
235+
public void IsFalseIfLoadingReposFails()
236+
{
237+
var repoSubject = new Subject<IRemoteRepositoryModel>();
238+
var col = TrackingCollection.Create(repoSubject);
239+
var repositoryHost = Substitute.For<IRepositoryHost>();
240+
repositoryHost.ModelService.GetRepositories(Arg.Any<ITrackingCollection<IRemoteRepositoryModel>>()).Returns(_ => col);
241+
var cloneService = Substitute.For<IRepositoryCloneService>();
242+
var vm = GetVM(
243+
repositoryHost,
244+
cloneService,
245+
Substitute.For<IOperatingSystem>(),
246+
Substitute.For<INotificationService>(),
247+
Substitute.For<IUsageTracker>());
248+
249+
Assert.False(vm.LoadingFailed);
250+
251+
repoSubject.OnError(new InvalidOperationException("Doh!"));
252+
253+
Assert.True(vm.LoadingFailed);
254+
Assert.False(vm.FilterTextIsEnabled);
255+
repoSubject.OnCompleted();
256+
}
257+
258+
[Fact]
259+
public void IsFalseWhenLoadingCompleteNotFailedAndNoRepositories()
260+
{
261+
var repoSubject = new Subject<IRemoteRepositoryModel>();
262+
var col = TrackingCollection.Create(repoSubject);
263+
var repositoryHost = Substitute.For<IRepositoryHost>();
264+
repositoryHost.ModelService.GetRepositories(Arg.Any<ITrackingCollection<IRemoteRepositoryModel>>()).Returns(_ => col);
265+
266+
var cloneService = Substitute.For<IRepositoryCloneService>();
267+
var vm = GetVM(
268+
repositoryHost,
269+
cloneService,
270+
Substitute.For<IOperatingSystem>(),
271+
Substitute.For<INotificationService>(),
272+
Substitute.For<IUsageTracker>());
273+
274+
repoSubject.OnCompleted();
275+
276+
Assert.False(vm.FilterTextIsEnabled);
277+
}
278+
}
279+
212280
public class TheLoadingFailedProperty : TestBaseClass
213281
{
214282
[Fact]

0 commit comments

Comments
 (0)