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

Commit 7f9b834

Browse files
committed
Implement updating local PR branch.
1 parent f864171 commit 7f9b834

File tree

5 files changed

+107
-41
lines changed

5 files changed

+107
-41
lines changed

src/GitHub.App/Services/PullRequestService.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,22 @@ public IObservable<Unit> FetchAndCheckout(ILocalRepositoryModel repository, int
9494
return DoFetchAndCheckout(repository, pullRequestNumber, localBranchName).ToObservable();
9595
}
9696

97-
public string GetDefaultLocalBranchName(ILocalRepositoryModel repository, int pullRequestNumber, string pullRequestTitle)
97+
public IObservable<string> GetDefaultLocalBranchName(ILocalRepositoryModel repository, int pullRequestNumber, string pullRequestTitle)
9898
{
99-
var initial = "pr/" + pullRequestNumber + "-" + GetSafeBranchName(pullRequestTitle);
100-
var current = initial;
101-
var repo = gitService.GetRepository(repository.LocalPath);
102-
var index = 2;
103-
104-
while (repo.Branches[current] != null)
99+
return Observable.Defer(() =>
105100
{
106-
current = initial + '-' + index++;
107-
}
101+
var initial = "pr/" + pullRequestNumber + "-" + GetSafeBranchName(pullRequestTitle);
102+
var current = initial;
103+
var repo = gitService.GetRepository(repository.LocalPath);
104+
var index = 2;
108105

109-
return current;
106+
while (repo.Branches[current] != null)
107+
{
108+
current = initial + '-' + index++;
109+
}
110+
111+
return Observable.Return(current);
112+
});
110113
}
111114

112115
public IObservable<HistoryDivergence> CalculateHistoryDivergence(ILocalRepositoryModel repository, int pullRequestNumber)

src/GitHub.App/ViewModels/PullRequestDetailViewModel.cs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -451,38 +451,32 @@ string GetBranchDisplayName(string targetBranchLabel)
451451

452452
IObservable<Unit> DoCheckout(object unused)
453453
{
454+
IObservable<Unit> operation = null;
455+
454456
switch (CheckoutMode)
455457
{
456-
case CheckoutMode.Switch:
457-
return SwitchToBranch();
458+
case CheckoutMode.NeedsPull:
459+
operation = pullRequestsService.FetchAndCheckout(repository, Number, repository.CurrentBranch.Name);
460+
break;
458461
case CheckoutMode.Fetch:
459-
return FetchAndCheckout();
462+
operation = pullRequestsService
463+
.GetDefaultLocalBranchName(repository, Number, Title)
464+
.SelectMany(x => pullRequestsService.FetchAndCheckout(repository, Number, x));
465+
break;
466+
case CheckoutMode.Switch:
467+
operation = pullRequestsService.SwitchToBranch(repository, Number);
468+
break;
460469
default:
461470
Debug.Fail("Invalid CheckoutMode in PullRequestDetailViewModel.DoCheckout.");
462-
return Observable.Empty<Unit>();
471+
operation = Observable.Empty<Unit>();
472+
break;
463473
}
464-
}
465-
466-
IObservable<Unit> SwitchToBranch()
467-
{
468-
return pullRequestsService.SwitchToBranch(repository, Number)
469-
.Catch<Unit, Exception>(ex =>
470-
{
471-
CheckoutError = ex.Message;
472-
return Observable.Empty<Unit>();
473-
});
474-
}
475-
476-
IObservable<Unit> FetchAndCheckout()
477-
{
478-
var branchName = pullRequestsService.GetDefaultLocalBranchName(repository, Number, Title);
479474

480-
return pullRequestsService.FetchAndCheckout(repository, Number, branchName)
481-
.Catch<Unit, Exception>(ex =>
482-
{
483-
CheckoutError = ex.Message;
484-
return Observable.Empty<Unit>();
485-
});
475+
return operation.Catch<Unit, Exception>(ex =>
476+
{
477+
CheckoutError = ex.Message;
478+
return Observable.Empty<Unit>();
479+
});
486480
}
487481
}
488482
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host,
3535
/// <param name="pullRequestNumber">The pull request number.</param>
3636
/// <param name="pullRequestTitle">The pull request title.</param>
3737
/// <returns></returns>
38-
string GetDefaultLocalBranchName(ILocalRepositoryModel repository, int pullRequestNumber, string pullRequestTitle);
38+
IObservable<string> GetDefaultLocalBranchName(ILocalRepositoryModel repository, int pullRequestNumber, string pullRequestTitle);
3939

4040
/// <summary>
4141
/// Gets the local branches that exist for the specified pull request.

src/UnitTests/GitHub.App/Services/PullRequestServiceTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void CreatePullRequestAllArgsMandatory()
5555
public class TheGetDefaultLocalBranchNameMethod
5656
{
5757
[Fact]
58-
public void ShouldReturnCorrectDefaultLocalBranchName()
58+
public async Task ShouldReturnCorrectDefaultLocalBranchName()
5959
{
6060
var service = new PullRequestService(
6161
Substitute.For<IGitClient>(),
@@ -64,12 +64,12 @@ public void ShouldReturnCorrectDefaultLocalBranchName()
6464
Substitute.For<IUsageTracker>());
6565

6666
var localRepo = Substitute.For<ILocalRepositoryModel>();
67-
var result = service.GetDefaultLocalBranchName(localRepo, 123, "Pull requests can be \"named\" all sorts of thing's (sic)");
67+
var result = await service.GetDefaultLocalBranchName(localRepo, 123, "Pull requests can be \"named\" all sorts of thing's (sic)");
6868
Assert.Equal("pr/123-pull-requests-can-be-named-all-sorts-of-thing-s-sic-", result);
6969
}
7070

7171
[Fact]
72-
public void DefaultLocalBranchNameShouldNotClashWithExistingBranchNames()
72+
public async Task DefaultLocalBranchNameShouldNotClashWithExistingBranchNames()
7373
{
7474
var service = new PullRequestService(
7575
Substitute.For<IGitClient>(),
@@ -78,7 +78,7 @@ public void DefaultLocalBranchNameShouldNotClashWithExistingBranchNames()
7878
Substitute.For<IUsageTracker>());
7979

8080
var localRepo = Substitute.For<ILocalRepositoryModel>();
81-
var result = service.GetDefaultLocalBranchName(localRepo, 123, "foo1");
81+
var result = await service.GetDefaultLocalBranchName(localRepo, 123, "foo1");
8282
Assert.Equal("pr/123-foo1-3", result);
8383
}
8484

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

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,79 @@ public async Task CheckoutDisabledMessageShouldBeSetWhenInvalidStateAndWorkingDi
193193
Assert.False(target.Checkout.CanExecute(null));
194194
}
195195

196+
[Fact]
197+
public async Task CheckoutNeedsPullShouldCallService()
198+
{
199+
var target = CreateTargetAndService(
200+
currentBranch: "pr/123",
201+
existingPrBranch: "pr/123",
202+
behindBy: 3);
203+
204+
await target.Item1.Load(CreatePullRequest(), new PullRequestFile[0]);
205+
206+
Assert.Equal(CheckoutMode.NeedsPull, target.Item1.CheckoutMode);
207+
208+
target.Item1.Checkout.Execute(null);
209+
210+
var unused = target.Item2.Received()
211+
.FetchAndCheckout(Arg.Any<ILocalRepositoryModel>(), target.Item1.Number, "pr/123");
212+
}
213+
214+
[Fact]
215+
public async Task CheckoutSwitchShouldCallService()
216+
{
217+
var target = CreateTargetAndService(
218+
currentBranch: "master",
219+
existingPrBranch: "pr/123");
220+
221+
await target.Item1.Load(CreatePullRequest(), new PullRequestFile[0]);
222+
223+
Assert.Equal(CheckoutMode.Switch, target.Item1.CheckoutMode);
224+
225+
target.Item1.Checkout.Execute(null);
226+
227+
var unused = target.Item2.Received()
228+
.SwitchToBranch(Arg.Any<ILocalRepositoryModel>(), 1);
229+
}
230+
231+
[Fact]
232+
public async Task CheckoutFetchShouldCallService()
233+
{
234+
var target = CreateTargetAndService(currentBranch: "master");
235+
target.Item2.GetDefaultLocalBranchName(Arg.Any<ILocalRepositoryModel>(), 1, Arg.Any<string>())
236+
.Returns(Observable.Return("pr/1-foo"));
237+
238+
await target.Item1.Load(CreatePullRequest(), new PullRequestFile[0]);
239+
240+
Assert.Equal(CheckoutMode.Fetch, target.Item1.CheckoutMode);
241+
242+
target.Item1.Checkout.Execute(null);
243+
244+
var unused = target.Item2.Received()
245+
.FetchAndCheckout(Arg.Any<ILocalRepositoryModel>(), target.Item1.Number, "pr/1-foo");
246+
}
247+
196248
PullRequestDetailViewModel CreateTarget(
197249
string currentBranch = "master",
198250
string existingPrBranch = null,
199251
bool dirty = false,
200252
int aheadBy = 0,
201253
int behindBy = 0)
254+
{
255+
return CreateTargetAndService(
256+
currentBranch: currentBranch,
257+
existingPrBranch: existingPrBranch,
258+
dirty: dirty,
259+
aheadBy: aheadBy,
260+
behindBy: behindBy).Item1;
261+
}
262+
263+
Tuple<PullRequestDetailViewModel, IPullRequestService> CreateTargetAndService(
264+
string currentBranch = "master",
265+
string existingPrBranch = null,
266+
bool dirty = false,
267+
int aheadBy = 0,
268+
int behindBy = 0)
202269
{
203270
var repository = Substitute.For<ILocalRepositoryModel>();
204271
var currentBranchModel = new BranchModel(currentBranch, repository);
@@ -227,11 +294,13 @@ PullRequestDetailViewModel CreateTarget(
227294
pullRequestService.CalculateHistoryDivergence(repository, Arg.Any<int>())
228295
.Returns(Observable.Return(divergence));
229296

230-
return new PullRequestDetailViewModel(
297+
var vm = new PullRequestDetailViewModel(
231298
Substitute.For<IRepositoryHost>(),
232299
repository,
233300
pullRequestService,
234301
Substitute.For<IAvatarProvider>());
302+
303+
return Tuple.Create(vm, pullRequestService);
235304
}
236305

237306
PullRequest CreatePullRequest(string body = "PR Body")

0 commit comments

Comments
 (0)