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

Commit 1847d4d

Browse files
committed
Merge feature/pr/creation into release/1.0.99.7
2 parents 6d89938 + 6777be3 commit 1847d4d

38 files changed

+757
-746
lines changed

GitHubVS.sln

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script", "Script", "{7B6C5F
5252
script\Require-CleanWorkTree.ps1 = script\Require-CleanWorkTree.ps1
5353
script\Run-NUnit.ps1 = script\Run-NUnit.ps1
5454
script\Run-XUnit.ps1 = script\Run-XUnit.ps1
55-
script\SolutionInfo.cs = script\SolutionInfo.cs
5655
script\Upload-DirectoryToS3.ps1 = script\Upload-DirectoryToS3.ps1
5756
EndProjectSection
5857
EndProject

src/GitHub.App/Api/ApiClient.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,15 @@ public IObservable<PullRequest> GetPullRequestsForRepository(string owner, strin
237237
SortDirection = SortDirection.Descending
238238
});
239239
}
240+
241+
public IObservable<Branch> GetBranches(string owner, string repo)
242+
{
243+
return gitHubClient.Repository.GetAllBranches(owner, repo);
244+
}
245+
246+
public IObservable<PullRequest> CreatePullRequest(NewPullRequest pullRequest, string owner, string repo)
247+
{
248+
return gitHubClient.PullRequest.Create(owner, repo, pullRequest);
249+
}
240250
}
241251
}

src/GitHub.App/Controllers/UIController.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ internal enum Trigger
105105
readonly IUIFactory factory;
106106
readonly IUIProvider uiProvider;
107107
readonly IRepositoryHosts hosts;
108-
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
109108
readonly IConnectionManager connectionManager;
110109

111110
readonly CompositeDisposable disposables = new CompositeDisposable();
@@ -333,7 +332,8 @@ void ConfigureUIHandlingStates()
333332
.OnEntryFrom(triggers[Trigger.PRDetail], (arg, tr) => RunView(UIViewType.PRDetail, CalculateDirection(tr), arg))
334333
.PermitDynamic(Trigger.Next, () => Go(Trigger.Next))
335334
.PermitDynamic(Trigger.Cancel, () => Go(Trigger.Cancel))
336-
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish));
335+
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish))
336+
.OnExit(() => DisposeView(activeFlow, UIViewType.PRDetail));
337337

338338
uiStateMachine.Configure(UIViewType.PRCreation)
339339
.OnEntry(tr => RunView(UIViewType.PRCreation, CalculateDirection(tr)))
@@ -622,6 +622,17 @@ void DisposeFlow(UIControllerFlow flow)
622622
list.Clear();
623623
}
624624

625+
void DisposeView(UIControllerFlow flow, UIViewType type)
626+
{
627+
var list = GetObjectsForFlow(flow);
628+
IUIPair uipair = null;
629+
if (list.TryGetValue(type, out uipair))
630+
{
631+
list.Remove(type);
632+
uipair.Dispose();
633+
}
634+
}
635+
625636
void RunView(UIViewType viewType, LoadDirection direction, ViewWithData arg = null)
626637
{
627638
if (requestedTarget?.ViewType == viewType)

src/GitHub.App/Extensions/AkavacheExtensions.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,37 @@ static IObservable<T> GetAndFetchLatestFromIndex<T>(this IBlobCache This,
234234
return cache.Merge(fetch).Replay().RefCount();
235235
}
236236

237+
/// <summary>
238+
/// This method adds a new object to the database and updates the
239+
/// corresponding index.
240+
/// </summary>
241+
/// <typeparam name="T"></typeparam>
242+
/// <param name="blobCache">The cache to retrieve the object from.</param>
243+
/// <param name="key">The key to look up the cache value with.</param>
244+
/// <param name="item">The item to add to the database</param>
245+
/// <param name="maxCacheDuration">
246+
/// The maximum age of a cache object before the object is treated as
247+
/// expired and unusable. Cache objects older than this will be treated
248+
/// as a cache miss.
249+
/// <returns></returns>
250+
public static IObservable<T> PutAndUpdateIndex<T>(this IBlobCache blobCache,
251+
string key,
252+
Func<IObservable<T>> fetchFunc,
253+
TimeSpan maxCacheDuration)
254+
where T : CacheItem
255+
{
256+
return Observable.Defer(() =>
257+
{
258+
var absoluteExpiration = blobCache.Scheduler.Now + maxCacheDuration;
259+
return blobCache.GetOrCreateObject(key, () => CacheIndex.Create(key))
260+
.SelectMany(index => fetchFunc()
261+
.Catch<T, Exception>(Observable.Throw<T>)
262+
.SelectMany(x => x.Save<T>(blobCache, key, absoluteExpiration))
263+
.Do(x => index.AddAndSave(blobCache, key, x, absoluteExpiration))
264+
);
265+
});
266+
}
267+
237268
static bool IsExpired(IBlobCache blobCache, DateTimeOffset itemCreatedAt, TimeSpan cacheDuration)
238269
{
239270
var elapsed = blobCache.Scheduler.Now - itemCreatedAt.ToUniversalTime();

src/GitHub.App/GitHub.App.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
<Compile Include="Factories\UIFactory.cs" />
129129
<Compile Include="GlobalSuppressions.cs" />
130130
<Compile Include="Infrastructure\LoggingConfiguration.cs" />
131+
<Compile Include="Models\BranchModel.cs" />
131132
<Compile Include="Models\PullRequestModel.cs" />
132133
<Compile Include="Resources.Designer.cs">
133134
<AutoGen>True</AutoGen>
@@ -145,6 +146,7 @@
145146
<Compile Include="Services\ImageDownloader.cs" />
146147
<Compile Include="Services\GitClient.cs" />
147148
<Compile Include="Services\ModelService.cs" />
149+
<Compile Include="Services\PullRequestService.cs" />
148150
<Compile Include="Services\RepositoryCloneService.cs" />
149151
<Compile Include="Extensions\FileExtensions.cs" />
150152
<Compile Include="Caches\CredentialCache.cs" />
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace GitHub.Models
2+
{
3+
public class BranchModel : IBranch
4+
{
5+
public BranchModel()
6+
{ }
7+
8+
public BranchModel(Octokit.Branch branch)
9+
{
10+
Name = branch.Name;
11+
}
12+
13+
public BranchModel(LibGit2Sharp.Branch branch)
14+
{
15+
Name = branch.FriendlyName;
16+
}
17+
18+
public string Name { get; set; }
19+
}
20+
}

src/GitHub.App/Models/PullRequestModel.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ public IAccount Assignee
126126
set { assignee = value; this.RaisePropertyChange(); }
127127
}
128128

129+
public ISimpleRepositoryModel Repository { get; }
130+
public IBranch Head { get; }
131+
public IBranch Base { get; }
129132

130133
[return: AllowNull] // nullguard thinks a string.Format can return null. sigh.
131134
public override string ToString()
Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
using System.Diagnostics.CodeAnalysis;
22
using GitHub.ViewModels;
33
using System.Collections.Generic;
4+
using GitHub.Models;
5+
using GitHub.Validation;
6+
using System;
7+
using System.Windows.Input;
8+
using ReactiveUI;
49

510
namespace GitHub.SampleData
611
{
@@ -9,27 +14,38 @@ public class PullRequestCreationViewModelDesigner : BaseViewModel, IPullRequestC
914
{
1015
public PullRequestCreationViewModelDesigner()
1116
{
12-
Branches = new List<string>()
17+
Branches = new List<IBranch>
1318
{
14-
"don/stub-ui",
15-
"feature/pr/views",
16-
"release-1.0.17.0"
17-
};
19+
new BranchModel { Name = "master" },
20+
new BranchModel { Name = "don/stub-ui" },
21+
new BranchModel { Name = "feature/pr/views" },
22+
new BranchModel { Name = "release-1.0.17.0" }
23+
}.AsReadOnly();
24+
25+
TargetBranch = new BranchModel { Name = "master" };
26+
SourceBranch = Branches[2];
1827

19-
CurrentBranchName = "fix-everything";
2028
SelectedAssignee = "Haacked (Phil Haack)";
21-
TargetBranchName = "master";
2229
Users = new List<string>()
2330
{
2431
"Haacked (Phil Haack)",
2532
"shana (Andreia Gaita)"
2633
};
2734
}
2835

29-
public string CurrentBranchName { get; set; }
36+
public IBranch SourceBranch { get; set; }
37+
public IBranch TargetBranch { get; set; }
38+
public IReadOnlyList<IBranch> Branches { get; set; }
39+
3040
public string SelectedAssignee { get; set; }
31-
public string TargetBranchName { get; set; }
32-
public List<string> Branches { get; set; }
3341
public List<string> Users { get; set; }
42+
43+
public IReactiveCommand<IPullRequestModel> CreatePullRequest { get; }
44+
45+
public string PRTitle { get; set; }
46+
47+
public ReactivePropertyValidator TitleValidator { get; }
48+
49+
public ReactivePropertyValidator BranchValidator { get; }
3450
}
3551
}

src/GitHub.App/Services/ModelService.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ public ITrackingCollection<IPullRequestModel> GetPullRequests(ISimpleRepositoryM
171171
return collection;
172172
}
173173

174+
public IObservable<IPullRequestModel> CreatePullRequest(ISimpleRepositoryModel repository, string title, IBranch source, IBranch target)
175+
{
176+
var keyobs = GetUserFromCache()
177+
.Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|pr", user.Login, repository.Name));
178+
179+
return Observable.Defer(() => keyobs
180+
.SelectMany(key =>
181+
hostCache.PutAndUpdateIndex(key, () =>
182+
apiClient.CreatePullRequest(new NewPullRequest(title, source.Name, target.Name),
183+
repository.CloneUrl.Owner,
184+
repository.CloneUrl.RepositoryName)
185+
.Select(PullRequestCacheItem.Create),
186+
TimeSpan.FromMinutes(30))
187+
)
188+
.Select(Create)
189+
);
190+
}
191+
174192
public IObservable<Unit> InvalidateAll()
175193
{
176194
return hostCache.InvalidateAll().ContinueAfter(() => hostCache.Vacuum());
@@ -234,12 +252,22 @@ IObservable<IReadOnlyList<IRepositoryModel>> GetOrganizationRepositories(string
234252
});
235253
}
236254

255+
public IObservable<IBranch> GetBranches(ISimpleRepositoryModel repo)
256+
{
257+
var keyobs = GetUserFromCache()
258+
.Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|branch", user.Login, repo.Name));
259+
260+
return Observable.Defer(() => keyobs
261+
.SelectMany(key => apiClient.GetBranches(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName)))
262+
.Select(Create);
263+
}
264+
237265
static LicenseItem Create(LicenseCacheItem licenseCacheItem)
238266
{
239267
return new LicenseItem(licenseCacheItem.Key, licenseCacheItem.Name);
240268
}
241269

242-
Models.Account Create(AccountCacheItem accountCacheItem)
270+
IAccount Create(AccountCacheItem accountCacheItem)
243271
{
244272
return new Models.Account(
245273
accountCacheItem.Login,
@@ -275,6 +303,11 @@ IPullRequestModel Create(PullRequestCacheItem prCacheItem)
275303
};
276304
}
277305

306+
IBranch Create(Branch branch)
307+
{
308+
return new BranchModel(branch);
309+
}
310+
278311
public IObservable<Unit> InsertUser(AccountCacheItem user)
279312
{
280313
return hostCache.InsertObject("user", user);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.ComponentModel.Composition;
3+
using GitHub.Models;
4+
5+
namespace GitHub.Services
6+
{
7+
[Export(typeof(IPullRequestService))]
8+
[PartCreationPolicy(CreationPolicy.Shared)]
9+
public class PullRequestService : IPullRequestService
10+
{
11+
public IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ISimpleRepositoryModel repository, string title, IBranch source, IBranch target)
12+
{
13+
return host.ModelService.CreatePullRequest(repository, title, source, target);
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)