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

Commit 4f07ee6

Browse files
authored
Merge branch 'master' into ui/primary-button
2 parents a5580ae + a44defa commit 4f07ee6

File tree

119 files changed

+2888
-1632
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+2888
-1632
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ build/
2020

2121
# Roslyn cache directories
2222
*.ide/
23+
.vs/
2324

2425
# MSTest test Results
2526
[Tt]est[Rr]esult*/

GitHubVS.sln

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.25029.0
4+
VisualStudioVersion = 14.0.25123.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio", "src\GitHub.VisualStudio\GitHub.VisualStudio.csproj", "{11569514-5AE5-4B5B-92A2-F10B0967DE5F}"
77
EndProject
@@ -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

ISSUE_TEMPLATE.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Thank you for contributing! Before you submit this issue please check that you have:
2+
- [ ] Read the ["Submitting an Issue"](https://github.com/github/VisualStudio/blob/master/CONTRIBUTING.md#submitting-an-issue) section of the Contributor Guidelines
3+
4+
### Version of the GitHub Extension
5+
The version of the extension is at `Tools\Extensions\Installed - GitHub Extension for Visual Studio`
6+
7+
### Version of Visual Studio
8+
The version of VS is on the `Help\About`, on the top left, above the copyright line.
9+
10+
### What happened
11+
Tell us what went wrong
12+
13+
### Steps to reproduce

script

src/CredentialManagement/CredentialManagement.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<NuGetPackageImportStamp>
1515
</NuGetPackageImportStamp>
1616
<TargetFrameworkProfile />
17-
<BuildType Condition="Exists('..\..\script\ApiClientConfiguration.cs')">Internal</BuildType>
17+
<BuildType Condition="Exists('..\..\script\src\ApiClientConfiguration.cs')">Internal</BuildType>
1818
<OutputPath>bin\$(Configuration)\</OutputPath>
1919
</PropertyGroup>
2020
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

src/GitHub.Api/GitHub.Api.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<AssemblyName>GitHub.Api</AssemblyName>
1212
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
14-
<BuildType Condition="Exists('..\..\script\ApiClientConfiguration.cs')">Internal</BuildType>
14+
<BuildType Condition="Exists('..\..\script\src\ApiClientConfiguration.cs')">Internal</BuildType>
1515
<OutputPath>bin\$(Configuration)\</OutputPath>
1616
<TargetFrameworkProfile />
1717
</PropertyGroup>

src/GitHub.App/Api/ApiClient.cs

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

src/GitHub.App/Caches/CacheIndex.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ namespace GitHub.Caches
1010
{
1111
public class CacheIndex
1212
{
13+
public const string PRPrefix = "index:pr";
14+
public const string RepoPrefix = "index:repos";
15+
public const string GitIgnoresPrefix = "index:ignores";
16+
public const string LicensesPrefix = "index:licenses";
17+
1318
public static CacheIndex Create(string key)
1419
{
1520
return new CacheIndex { IndexKey = key };
@@ -21,6 +26,15 @@ public CacheIndex()
2126
OldKeys = new List<string>();
2227
}
2328

29+
public CacheIndex Add(string indexKey, CacheItem item)
30+
{
31+
var k = string.Format(CultureInfo.InvariantCulture, "{0}|{1}", IndexKey, item.Key);
32+
if (!Keys.Contains(k))
33+
Keys.Add(k);
34+
UpdatedAt = DateTimeOffset.UtcNow;
35+
return this;
36+
}
37+
2438
public IObservable<CacheIndex> AddAndSave(IBlobCache cache, string indexKey, CacheItem item,
2539
DateTimeOffset? absoluteExpiration = null)
2640
{
@@ -29,7 +43,7 @@ public IObservable<CacheIndex> AddAndSave(IBlobCache cache, string indexKey, Cac
2943
Keys.Add(k);
3044
UpdatedAt = DateTimeOffset.UtcNow;
3145
return cache.InsertObject(IndexKey, this, absoluteExpiration)
32-
.Select(x => this);
46+
.Select(x => this);
3347
}
3448

3549
public static IObservable<CacheIndex> AddAndSaveToIndex(IBlobCache cache, string indexKey, CacheItem item,
@@ -47,15 +61,19 @@ public static IObservable<CacheIndex> AddAndSaveToIndex(IBlobCache cache, string
4761
.Select(x => index));
4862
}
4963

50-
public IObservable<CacheIndex> Clear(IBlobCache cache, string indexKey, DateTimeOffset? absoluteExpiration = null)
64+
public CacheIndex Clear()
5165
{
5266
OldKeys = Keys.ToList();
5367
Keys.Clear();
5468
UpdatedAt = DateTimeOffset.UtcNow;
55-
return cache
56-
.InvalidateObject<CacheIndex>(indexKey)
57-
.SelectMany(_ => cache.InsertObject(indexKey, this, absoluteExpiration))
58-
.Select(_ => this);
69+
return this;
70+
}
71+
72+
public IObservable<CacheIndex> Save(IBlobCache cache,
73+
DateTimeOffset? absoluteExpiration = null)
74+
{
75+
return cache.InsertObject(IndexKey, this, absoluteExpiration)
76+
.Select(x => this);
5977
}
6078

6179
[AllowNull]

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: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Reactive.Linq;
55
using Akavache;
66
using GitHub.Caches;
7+
using System.Threading.Tasks;
78

89
namespace GitHub.Extensions
910
{
@@ -199,39 +200,76 @@ static IObservable<T> GetAndFetchLatestFromIndex<T>(this IBlobCache This,
199200
bool shouldInvalidateOnError = false)
200201
where T : CacheItem
201202
{
202-
var fetch = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key))
203+
var idx = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key))).Replay().RefCount();
204+
205+
206+
var fetch = idx
203207
.Select(x => Tuple.Create(x, fetchPredicate == null || !x.Keys.Any() || fetchPredicate(x.UpdatedAt)))
204208
.Where(predicateIsTrue => predicateIsTrue.Item2)
205209
.Select(x => x.Item1)
206-
.SelectMany(index => index.Clear(This, key, absoluteExpiration))
207-
.SelectMany(index =>
208-
{
209-
var fetchObs = fetchFunc().Catch<T, Exception>(ex =>
210-
{
211-
var shouldInvalidate = shouldInvalidateOnError ?
212-
This.InvalidateObject<CacheIndex>(key) :
213-
Observable.Return(Unit.Default);
214-
return shouldInvalidate.SelectMany(__ => Observable.Throw<T>(ex));
215-
});
216-
217-
return fetchObs
218-
.SelectMany(x => x.Save<T>(This, key, absoluteExpiration))
219-
.Do(x => index.AddAndSave(This, key, x, absoluteExpiration))
220-
.Finally(() =>
210+
.Select(index => index.Clear())
211+
.SelectMany(index => fetchFunc()
212+
.Catch<T, Exception>(ex =>
221213
{
222-
This.GetObjects<T>(index.OldKeys.Except(index.Keys))
223-
.Do(dict => This.InvalidateObjects<T>(dict.Keys))
224-
.SelectMany(dict => dict.Values)
225-
.Do(removedItemsCallback)
226-
.Subscribe();
227-
});
228-
}));
229-
230-
var cache = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key))
231-
.SelectMany(index => This.GetObjects<T>(index.Keys))
232-
.SelectMany(dict => dict.Values));
233-
234-
return cache.Merge(fetch).Replay().RefCount();
214+
var shouldInvalidate = shouldInvalidateOnError ?
215+
This.InvalidateObject<CacheIndex>(key) :
216+
Observable.Return(Unit.Default);
217+
return shouldInvalidate.SelectMany(__ => Observable.Throw<T>(ex));
218+
})
219+
.SelectMany(x => x.Save<T>(This, key, absoluteExpiration))
220+
.Do(x => index.Add(key, x))
221+
);
222+
223+
var cache = idx
224+
.SelectMany(index => This.GetObjects<T>(index.Keys.ToList()))
225+
.SelectMany(dict => dict.Values);
226+
227+
return cache.Merge(fetch)
228+
.Finally(async () =>
229+
{
230+
var index = await idx;
231+
await index.Save(This);
232+
233+
var list = index.OldKeys.Except(index.Keys);
234+
if (!list.Any())
235+
return;
236+
var removed = await This.GetObjects<T>(list);
237+
foreach (var d in removed.Values)
238+
removedItemsCallback(d);
239+
await This.InvalidateObjects<T>(list);
240+
})
241+
.Replay().RefCount();
242+
}
243+
244+
/// <summary>
245+
/// This method adds a new object to the database and updates the
246+
/// corresponding index.
247+
/// </summary>
248+
/// <typeparam name="T"></typeparam>
249+
/// <param name="blobCache">The cache to retrieve the object from.</param>
250+
/// <param name="key">The key to look up the cache value with.</param>
251+
/// <param name="item">The item to add to the database</param>
252+
/// <param name="maxCacheDuration">
253+
/// The maximum age of a cache object before the object is treated as
254+
/// expired and unusable. Cache objects older than this will be treated
255+
/// as a cache miss.
256+
/// <returns></returns>
257+
public static IObservable<T> PutAndUpdateIndex<T>(this IBlobCache blobCache,
258+
string key,
259+
Func<IObservable<T>> fetchFunc,
260+
TimeSpan maxCacheDuration)
261+
where T : CacheItem
262+
{
263+
return Observable.Defer(() =>
264+
{
265+
var absoluteExpiration = blobCache.Scheduler.Now + maxCacheDuration;
266+
return blobCache.GetOrCreateObject(key, () => CacheIndex.Create(key))
267+
.SelectMany(index => fetchFunc()
268+
.Catch<T, Exception>(Observable.Throw<T>)
269+
.SelectMany(x => x.Save<T>(blobCache, key, absoluteExpiration))
270+
.Do(x => index.AddAndSave(blobCache, key, x, absoluteExpiration))
271+
);
272+
});
235273
}
236274

237275
static bool IsExpired(IBlobCache blobCache, DateTimeOffset itemCreatedAt, TimeSpan cacheDuration)

0 commit comments

Comments
 (0)