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

Commit 40427d2

Browse files
author
Steven Kirk
committed
Merge remote-tracking branch 'refs/remotes/origin/settings/add-property-events' into feature/metrics
2 parents 4be0f81 + c8ea901 commit 40427d2

File tree

85 files changed

+2201
-176
lines changed

Some content is hidden

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

85 files changed

+2201
-176
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,4 @@ WiX.Toolset.DummyFile.txt
238238
nunit-UnitTests.xml
239239
nunit-TrackingCollectionTests.xml
240240
GitHubVS.sln.DotSettings
241-
**/generated/*.cs
241+
**/generated/*.cs

CONTRIBUTING.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,33 @@ There are certain areas of the extension that are restricted in what they can do
3131
- Team Explorer content outside the Home page is slightly less restricted, but not by much
3232
- Dialogs and views that don't inherit from TeamExplorer classes are free to use what they need.
3333

34+
## Submitting an Issue
35+
36+
### Bug Reporting
37+
38+
Here are a few helpful tips when reporting a bug:
39+
- Verify the bug resides in the GitHub for Visual Studio extension
40+
- A lot of functionality provided by this extension resides in the Team Explorer pane, alongside other non-GitHub tools to manage and collaborate on source code, including Visual Studio's Git support, which is owned by Microsoft.
41+
- If this bug not is related to the GitHub extension, visit the [Visual Studio support page](https://www.visualstudio.com/support/support-overview-vs) for help
42+
- Screenshots are very helpful in diagnosing bugs and understanding the state of the extension when it's experiencing problems. Please include them whenever possible.
43+
- A log file is helpful in diagnosing bug issues. To include log files in your issue:
44+
45+
1. Close Visual Studio if it's open
46+
2. Open a Developer Command Prompt for VS2015
47+
3. Run devenv /log
48+
4. Reproduce your issue
49+
5. Close VS
50+
6. Locate the following files on your system and email them to [email protected] or create a gist and link it in the issue report:
51+
- `%appdata%\Microsoft\VisualStudio\14.0\ActivityLog.xml`
52+
- `%localappdata%\temp\extension.log`
53+
- `%localappdata%\GitHubVisualStudio\extension.log`
54+
55+
### Feature Requests
56+
If you have a feature that you think would be a great addition to the extension, we might already have thought about it too, so be sure to check if your suggestion matches our [roadmap](#roadmap-and-future-feature-ideas) before making a request. Also take a peek at our [pull requests](https://github.com/github/VisualStudio/pulls) to see what we're currently working on. Additionally, someone might have already thought of your idea, so check out Issues labeled as [features](https://github.com/github/VisualStudio/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) to see if it already exists.
57+
3458
## Things to improve in the current version
3559

36-
- Localization
60+
- [Localization](https://github.com/github/VisualStudio/issues/18)
3761

3862
## Roadmap and future feature ideas
3963

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ Visit the [Contributor Guidelines](CONTRIBUTING.md) for details on how to contri
4444

4545
## Copyright
4646

47-
Copyright 2015 GitHub, Inc.
47+
Copyright 2015 - 2016 GitHub, Inc.
4848

4949
Licensed under the [MIT License](LICENSE.md)

src/GitHub.App/Api/ApiClient.cs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@
1313
using Octokit;
1414
using Octokit.Reactive;
1515
using ReactiveUI;
16+
using System.Threading.Tasks;
17+
using System.Reactive.Threading.Tasks;
18+
using Octokit.Internal;
19+
using System.Collections.Generic;
20+
using GitHub.Models;
1621

1722
namespace GitHub.Api
1823
{
1924
public partial class ApiClient : IApiClient
2025
{
21-
static readonly Logger log = LogManager.GetCurrentClassLogger();
22-
26+
const string ScopesHeader = "X-OAuth-Scopes";
2327
const string ProductName = Info.ApplicationInfo.ApplicationDescription;
28+
static readonly Logger log = LogManager.GetCurrentClassLogger();
29+
static readonly Uri userEndpoint = new Uri("user", UriKind.Relative);
2430

2531
readonly IObservableGitHubClient gitHubClient;
2632
// There are two sets of authorization scopes, old and new:
2733
// The old scopes must be used by older versions of Enterprise that don't support the new scopes:
28-
readonly string[] oldAuthorizationScopes = { "user", "repo" };
34+
readonly string[] oldAuthorizationScopes = { "user", "repo", "gist" };
2935
// These new scopes include write:public_key, which allows us to add public SSH keys to an account:
30-
readonly string[] newAuthorizationScopes = { "user", "repo", "write:public_key" };
36+
readonly string[] newAuthorizationScopes = { "user", "repo", "gist", "write:public_key" };
3137
readonly static Lazy<string> lazyNote = new Lazy<string>(() => ProductName + " on " + GetMachineNameSafe());
3238
readonly static Lazy<string> lazyFingerprint = new Lazy<string>(GetFingerprint);
3339

@@ -52,9 +58,35 @@ public IObservable<Repository> CreateRepository(NewRepository repository, string
5258
return (isUser ? client.Create(repository) : client.Create(login, repository));
5359
}
5460

55-
public IObservable<User> GetUser()
61+
public IObservable<Gist> CreateGist(NewGist newGist)
62+
{
63+
return gitHubClient.Gist.Create(newGist);
64+
}
65+
66+
public IObservable<UserAndScopes> GetUser()
5667
{
57-
return gitHubClient.User.Current();
68+
return GetUserInternal().ToObservable();
69+
}
70+
71+
async Task<UserAndScopes> GetUserInternal()
72+
{
73+
var response = await gitHubClient.Connection.Get<User>(
74+
userEndpoint, null, null).ConfigureAwait(false);
75+
var scopes = default(string[]);
76+
77+
if (response.HttpResponse.Headers.ContainsKey(ScopesHeader))
78+
{
79+
scopes = response.HttpResponse.Headers[ScopesHeader]
80+
.Split(',')
81+
.Select(x => x.Trim())
82+
.ToArray();
83+
}
84+
else
85+
{
86+
log.Error($"Error reading scopes: /user succeeded but {ScopesHeader} was not present.");
87+
}
88+
89+
return new UserAndScopes(response.Body, scopes);
5890
}
5991

6092
public IObservable<ApplicationAuthorization> GetOrCreateApplicationAuthenticationCode(

src/GitHub.App/Controllers/UIController.cs

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ public UIController(IUIProvider uiProvider, IRepositoryHosts hosts, IUIFactory f
170170

171171
uiStateMachine = new StateMachineType(UIViewType.None);
172172
triggers = new Dictionary<Trigger, StateMachineType.TriggerWithParameters<ViewWithData>>();
173+
173174
ConfigureUIHandlingStates();
175+
174176
}
175177

176178
public IObservable<LoadData> SelectFlow(UIControllerFlow choice)
@@ -257,12 +259,12 @@ public void Start([AllowNull] IConnection conn)
257259

258260
public void Jump(ViewWithData where)
259261
{
260-
Debug.Assert(where.Flow == mainFlow, "Jump called for flow " + where.Flow + " but this is " + mainFlow);
261-
if (where.Flow != mainFlow)
262+
Debug.Assert(where.ActiveFlow == mainFlow, "Jump called for flow " + where.ActiveFlow + " but this is " + mainFlow);
263+
if (where.ActiveFlow != mainFlow)
262264
return;
263265

264266
requestedTarget = where;
265-
if (activeFlow == where.Flow)
267+
if (activeFlow == where.ActiveFlow)
266268
Fire(Trigger.Next, where);
267269
}
268270

@@ -295,8 +297,7 @@ void ConfigureUIHandlingStates()
295297
.OnEntry(tr => stopping = false)
296298
.PermitDynamic(Trigger.Next, () =>
297299
{
298-
var loggedIn = connection != null && hosts.LookupHost(connection.HostAddress).IsLoggedIn;
299-
activeFlow = loggedIn ? mainFlow : UIControllerFlow.Authentication;
300+
activeFlow = SelectActiveFlow();
300301
return Go(Trigger.Next);
301302
})
302303
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish));
@@ -352,6 +353,18 @@ void ConfigureUIHandlingStates()
352353
.PermitDynamic(Trigger.Cancel, () => Go(Trigger.Cancel))
353354
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish));
354355

356+
uiStateMachine.Configure(UIViewType.Gist)
357+
.OnEntry(tr => RunView(UIViewType.Gist, CalculateDirection(tr)))
358+
.PermitDynamic(Trigger.Next, () => Go(Trigger.Next))
359+
.PermitDynamic(Trigger.Cancel, () => Go(Trigger.Cancel))
360+
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish));
361+
362+
uiStateMachine.Configure(UIViewType.LogoutRequired)
363+
.OnEntry(tr => RunView(UIViewType.LogoutRequired, CalculateDirection(tr)))
364+
.PermitDynamic(Trigger.Next, () => Go(Trigger.Next))
365+
.PermitDynamic(Trigger.Cancel, () => Go(Trigger.Cancel))
366+
.PermitDynamic(Trigger.Finish, () => Go(Trigger.Finish));
367+
355368
uiStateMachine.Configure(UIViewType.End)
356369
.OnEntryFrom(Trigger.Cancel, () => End(false))
357370
.OnEntryFrom(Trigger.Next, () => End(true))
@@ -518,6 +531,43 @@ void ConfigureLogicStates()
518531
logic.Configure(UIViewType.End)
519532
.Permit(Trigger.Next, UIViewType.None);
520533
machines.Add(UIControllerFlow.PullRequests, logic);
534+
535+
// gist flow
536+
logic = new StateMachine<UIViewType, Trigger>(UIViewType.None);
537+
logic.Configure(UIViewType.None)
538+
.Permit(Trigger.Next, UIViewType.Gist)
539+
.Permit(Trigger.Finish, UIViewType.End);
540+
logic.Configure(UIViewType.Gist)
541+
.Permit(Trigger.Next, UIViewType.End)
542+
.Permit(Trigger.Cancel, UIViewType.End)
543+
.Permit(Trigger.Finish, UIViewType.End);
544+
logic.Configure(UIViewType.End)
545+
.Permit(Trigger.Next, UIViewType.None);
546+
machines.Add(UIControllerFlow.Gist, logic);
547+
548+
// logout required flow
549+
logic = new StateMachine<UIViewType, Trigger>(UIViewType.None);
550+
logic.Configure(UIViewType.None)
551+
.Permit(Trigger.Next, UIViewType.LogoutRequired)
552+
.Permit(Trigger.Finish, UIViewType.End);
553+
logic.Configure(UIViewType.LogoutRequired)
554+
.Permit(Trigger.Next, UIViewType.End)
555+
.Permit(Trigger.Cancel, UIViewType.End)
556+
.Permit(Trigger.Finish, UIViewType.End);
557+
logic.Configure(UIViewType.End)
558+
.Permit(Trigger.Next, UIViewType.None);
559+
machines.Add(UIControllerFlow.LogoutRequired, logic);
560+
}
561+
562+
UIControllerFlow SelectActiveFlow()
563+
{
564+
var host = connection != null ? hosts.LookupHost(connection.HostAddress) : null;
565+
var loggedIn = host?.IsLoggedIn ?? false;
566+
if (!loggedIn || mainFlow != UIControllerFlow.Gist)
567+
return loggedIn ? mainFlow : UIControllerFlow.Authentication;
568+
569+
var supportsGist = host?.SupportsGist ?? false;
570+
return supportsGist ? mainFlow : UIControllerFlow.LogoutRequired;
521571
}
522572

523573
static LoadDirection CalculateDirection(StateMachineType.Transition tr)
@@ -580,12 +630,14 @@ void RunView(UIViewType viewType, LoadDirection direction, ViewWithData arg = nu
580630
requestedTarget = null;
581631
}
582632

633+
if (arg == null)
634+
arg = new ViewWithData { ActiveFlow = activeFlow, MainFlow = mainFlow, ViewType = viewType };
583635
bool firstTime = CreateViewAndViewModel(viewType, arg);
584636
var view = GetObjectsForFlow(activeFlow)[viewType].View;
585637
transition.OnNext(new LoadData
586638
{
587639
View = view,
588-
Data = arg ?? new ViewWithData { Flow = activeFlow, ViewType = viewType },
640+
Data = arg,
589641
Direction = direction
590642
});
591643

@@ -660,7 +712,7 @@ void SetupView(UIViewType viewType, IView view)
660712
/// </summary>
661713
/// <param name="viewType"></param>
662714
/// <returns>true if the View/ViewModel didn't exist and had to be created</returns>
663-
bool CreateViewAndViewModel(UIViewType viewType, [AllowNull]ViewWithData data = null)
715+
bool CreateViewAndViewModel(UIViewType viewType, ViewWithData data = null)
664716
{
665717
var list = GetObjectsForFlow(activeFlow);
666718
if (viewType == UIViewType.Login)

src/GitHub.App/GitHub.App.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<Reference Include="Microsoft.VisualStudio.ComponentModelHost, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
5555
<Reference Include="Microsoft.VisualStudio.Shell.14.0, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
5656
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
57+
<Reference Include="Microsoft.VisualStudio.TextManager.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
5758
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
5859
<SpecificVersion>False</SpecificVersion>
5960
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
@@ -183,6 +184,7 @@
183184
<Compile Include="Services\IEnterpriseProbe.cs" />
184185
<Compile Include="Factories\RepositoryHostFactory.cs" />
185186
<Compile Include="Services\RepositoryCreationService.cs" />
187+
<Compile Include="Services\GistPublishService.cs" />
186188
<Compile Include="Services\RepositoryPublishService.cs" />
187189
<Compile Include="Services\SerializedObjectProvider.cs" />
188190
<Compile Include="Services\StandardUserErrors.cs" />
@@ -194,6 +196,8 @@
194196
<Compile Include="UserErrors\PrivateRepositoryQuotaExceededUserError.cs" />
195197
<Compile Include="ViewModels\BaseViewModel.cs" />
196198
<Compile Include="Models\ConnectionRepositoryHostMap.cs" />
199+
<Compile Include="ViewModels\GistCreationViewModel.cs" />
200+
<Compile Include="ViewModels\LogoutRequiredViewModel.cs" />
197201
<Compile Include="ViewModels\PullRequestCreationViewModel.cs" />
198202
<Compile Include="ViewModels\PullRequestDetailViewModel.cs" />
199203
<Compile Include="ViewModels\PullRequestListViewModel.cs" />

src/GitHub.App/Models/ConnectionRepositoryHostMap.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.ComponentModel.Composition;
22
using GitHub.Models;
33
using GitHub.Services;
4+
using GitHub.Extensions;
45

56
namespace GitHub.ViewModels
67
{

src/GitHub.App/Models/DisconnectedRepositoryHosts.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public DisconnectedRepositoryHost()
2626
[AllowNull]
2727
public bool IsLoggedIn { get; private set; }
2828
public bool IsLoggingIn { get; private set; }
29+
public bool SupportsGist { get; private set; }
2930
public ReactiveList<IAccount> Organizations { get; private set; }
3031
public ReactiveList<IAccount> Accounts { get; private set; }
3132
public string Title { get; private set; }

0 commit comments

Comments
 (0)