public IObservable <AuthenticationResult> LogInFromCache() { Func <Task <AuthenticationResult> > f = async() => { try { var user = await loginManager.LoginFromCache(Address, ApiClient.GitHubClient); var accountCacheItem = new AccountCacheItem(user); await usage.IncrementCounter(x => x.NumberOfLogins); await ModelService.InsertUser(accountCacheItem); if (user != null) { IsLoggedIn = true; return(AuthenticationResult.Success); } else { return(AuthenticationResult.VerificationFailure); } } catch (AuthorizationException) { return(AuthenticationResult.CredentialFailure); } }; return(f().ToObservable()); }
void ShowWelcomeMessage() { teamExplorerServices.ShowMessage( Resources.TeamExplorerWelcomeMessage, new RelayCommand(o => { var str = o.ToString(); switch (str) { case "show-training": visualStudioBrowser.OpenUrl(new Uri(TrainingUrl)); usageTracker.IncrementCounter(x => x.NumberOfWelcomeTrainingClicks).Forget(); break; case "show-docs": visualStudioBrowser.OpenUrl(new Uri(GitHubUrls.Documentation)); usageTracker.IncrementCounter(x => x.NumberOfWelcomeDocsClicks).Forget(); break; case "dont-show-again": teamExplorerServices.HideNotification(welcomeMessageGuid); settings.HideTeamExplorerWelcomeMessage = true; settings.Save(); break; } }), false, welcomeMessageGuid); }
/// <inheritdoc/> public async Task <IPullRequestReviewModel> CreatePendingReview( ILocalRepositoryModel localRepository, IAccount user, string pullRequestId) { var address = HostAddress.Create(localRepository.CloneUrl.Host); var graphql = await graphqlFactory.CreateConnection(address); var review = new AddPullRequestReviewInput { PullRequestId = pullRequestId, }; var addReview = new Mutation() .AddPullRequestReview(review) .Select(x => new PullRequestReviewModel { Id = x.PullRequestReview.DatabaseId.Value, Body = x.PullRequestReview.Body, CommitId = x.PullRequestReview.Commit.Oid, NodeId = x.PullRequestReview.Id, State = FromGraphQL(x.PullRequestReview.State), User = user, }); var result = await graphql.Run(addReview); await usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentStartReview); return(result); }
Tuple <ITextSnapshotLine, ITrackingPoint> GetLineAndTrackingPoint( ITextView textView, DiffSide side, int lineNumber) { var diffModel = (textView as IWpfTextView)?.TextViewModel as IDifferenceTextViewModel; var snapshot = textView.TextSnapshot; if (diffModel?.ViewType == DifferenceViewType.InlineView) { snapshot = side == DiffSide.Left ? diffModel.Viewer.DifferenceBuffer.LeftBuffer.CurrentSnapshot : diffModel.Viewer.DifferenceBuffer.RightBuffer.CurrentSnapshot; } var line = snapshot.GetLineFromLineNumber(lineNumber); var trackingPoint = snapshot.CreateTrackingPoint(line.Start.Position, PointTrackingMode.Positive); ExpandCollapsedRegions(textView, line.Extent); peekBroker.TriggerPeekSession(textView, trackingPoint, relationship); usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentOpen).Forget(); return(Tuple.Create(line, trackingPoint)); }
async Task <IPullRequestModel> PushAndCreatePR(IModelService modelService, ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body) { // PullRequestModel doesn't keep a reference to repo using (var repo = await Task.Run(() => gitService.GetRepository(sourceRepository.LocalPath))) { var remote = await gitClient.GetHttpRemote(repo, "origin"); await gitClient.Push(repo, sourceBranch.Name, remote.Name); if (!repo.Branches[sourceBranch.Name].IsTracking) { await gitClient.SetTrackingBranch(repo, sourceBranch.Name, remote.Name); } // delay things a bit to avoid a race between pushing a new branch and creating a PR on it if (!Splat.ModeDetector.Current.InUnitTestRunner().GetValueOrDefault()) { await Task.Delay(TimeSpan.FromSeconds(5)); } var ret = await modelService.CreatePullRequest(sourceRepository, targetRepository, sourceBranch, targetBranch, title, body); await usageTracker.IncrementCounter(x => x.NumberOfUpstreamPullRequests); return(ret); } }
/// <inheritdoc/> public async Task CloneRepository( string cloneUrl, string repositoryName, string repositoryPath, object progress = null) { Guard.ArgumentNotEmptyString(cloneUrl, nameof(cloneUrl)); Guard.ArgumentNotEmptyString(repositoryName, nameof(repositoryName)); Guard.ArgumentNotEmptyString(repositoryPath, nameof(repositoryPath)); string path = Path.Combine(repositoryPath, repositoryName); // Switch to a thread pool thread for IO then back to the main thread to call // vsGitServices.Clone() as this must be called on the main thread. await ThreadingHelper.SwitchToPoolThreadAsync(); operatingSystem.Directory.CreateDirectory(path); await ThreadingHelper.SwitchToMainThreadAsync(); try { await vsGitServices.Clone(cloneUrl, path, true, progress); await usageTracker.IncrementCounter(x => x.NumberOfClones); } catch (Exception ex) { log.Error(ex, "Could not clone {CloneUrl} to {Path}", cloneUrl, path); throw; } }
public IObservable <Repository> ForkRepository(IApiClient apiClient, IRepositoryModel sourceRepository, NewRepositoryFork repositoryFork, bool updateOrigin, bool addUpstream, bool trackMasterUpstream) { log.Verbose("ForkRepository Source:{SourceOwner}/{SourceName} To:{DestinationOwner}", sourceRepository.Owner, sourceRepository.Name, repositoryFork.Organization ?? "[Current User]"); log.Verbose("ForkRepository updateOrigin:{UpdateOrigin} addUpstream:{AddUpstream} trackMasterUpstream:{TrackMasterUpstream}", updateOrigin, addUpstream, trackMasterUpstream); usageTracker.IncrementCounter(model => model.NumberOfReposForked).Forget(); return(Observable.Defer(() => apiClient.ForkRepository(sourceRepository.Owner, sourceRepository.Name, repositoryFork) .ObserveOn(RxApp.MainThreadScheduler) .Select(remoteRepo => new { RemoteRepo = remoteRepo, ActiveRepo = updateOrigin ? vsGitServices.GetActiveRepo() : null })) .SelectMany(async repo => { if (repo.ActiveRepo != null) { using (repo.ActiveRepo) { var originUri = repo.RemoteRepo != null ? new Uri(repo.RemoteRepo.CloneUrl) : null; var upstreamUri = addUpstream ? sourceRepository.CloneUrl.ToUri() : null; await SwitchRemotes(repo.ActiveRepo, originUri, upstreamUri, trackMasterUpstream); } } return repo.RemoteRepo; })); }
public override async void Execute() { var connection = await connectionManager.GetConnection(ActiveRepo); if (connection?.IsLoggedIn == true) { usageTracker.IncrementCounter(model => model.NumberOfShowRepoForkDialogClicks).Forget(); await dialogService.ShowForkDialog(ActiveRepo, connection); } }
private async Task RecordForkRepositoryUsage(bool updateOrigin, bool addUpstream, bool trackMasterUpstream) { await usageTracker.IncrementCounter(model => model.NumberOfReposForked); if (updateOrigin) { await usageTracker.IncrementCounter(model => model.NumberOfOriginsUpdatedWhenForkingRepo); } if (addUpstream) { await usageTracker.IncrementCounter(model => model.NumberOfUpstreamsAddedWhenForkingRepo); } if (trackMasterUpstream) { await usageTracker.IncrementCounter(model => model.NumberOfTrackMasterUpstreamWhenForkingRepo); } }
IObservable <Unit> OnCreateRepository(object state) { var newRepository = GatherRepositoryInfo(); return(repositoryCreationService.CreateRepository( newRepository, SelectedAccount, BaseRepositoryPath, modelService.ApiClient) .Do(_ => usageTracker.IncrementCounter(x => x.NumberOfReposCreated).Forget())); }
/// <inheritdoc/> public async Task <IConnection> LogIn(HostAddress address, string userName, string password) { var conns = await GetLoadedConnectionsInternal(); if (conns.Any(x => x.HostAddress == address)) { throw new InvalidOperationException($"A connection to {address} already exists."); } var client = CreateClient(address); var user = await loginManager.Login(address, client, userName, password); var connection = new Connection(address, userName, user, null); conns.Add(connection); await SaveConnections(); await usageTracker.IncrementCounter(x => x.NumberOfLogins); return(connection); }
/// <inheritdoc/> public async Task <IPullRequestReviewCommentModel> PostReviewComment( ILocalRepositoryModel localRepository, string remoteRepositoryOwner, IAccount user, int number, string body, string commitId, string path, int position) { var address = HostAddress.Create(localRepository.CloneUrl.Host); var apiClient = await apiClientFactory.Create(address); var result = await apiClient.CreatePullRequestReviewComment( remoteRepositoryOwner, localRepository.Name, number, body, commitId, path, position); await usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentPost); return(new PullRequestReviewCommentModel { Body = result.Body, CommitId = result.CommitId, DiffHunk = result.DiffHunk, Id = result.Id, OriginalCommitId = result.OriginalCommitId, OriginalPosition = result.OriginalPosition, Path = result.Path, Position = result.Position, CreatedAt = result.CreatedAt, User = user, }); }
private void DoOpenDetailsUrl() { Expression <Func <UsageModel.MeasuresModel, int> > expression; if (CheckType == PullRequestCheckType.StatusApi) { expression = x => x.NumberOfPRStatusesOpenInGitHub; } else { expression = x => x.NumberOfPRChecksOpenInGitHub; } usageTracker.IncrementCounter(expression).Forget(); }
public void Execute(object parameter) { try { object customIn = null; object customOut = null; dte?.Commands.Raise(guid, id, ref customIn, ref customOut); } catch (Exception e) { log.Error(e, "Couldn't raise {Guid}:{ID}", guid, id); } usageTracker.IncrementCounter(x => x.NumberOfShowCurrentPullRequest).Forget(); }
/// <inheritdoc/> public async Task InitializeAsync( RemoteRepositoryModel repository, LocalRepositoryModel localRepository, ActorModel currentUser, PullRequestDetailModel model) { await base.InitializeAsync(repository, localRepository, model).ConfigureAwait(true); timeline.Clear(); CommitCount = 0; currentUserModel = currentUser; CurrentUser = new ActorViewModel(currentUser); var commits = new List <CommitSummaryViewModel>(); foreach (var i in model.Timeline) { if (!(i is CommitModel) && commits.Count > 0) { timeline.Add(new CommitListViewModel(commits)); commits.Clear(); } switch (i) { case CommitModel commit: commits.Add(new CommitSummaryViewModel(commit)); ++CommitCount; break; case CommentModel comment: await AddComment(comment).ConfigureAwait(true); break; } } if (commits.Count > 0) { timeline.Add(new CommitListViewModel(commits)); } await AddPlaceholder().ConfigureAwait(true); await usageTracker.IncrementCounter(x => x.NumberOfPRConversationsOpened); }
IObservable <ProgressState> OnPublishRepository(object arg) { var newRepository = GatherRepositoryInfo(); var account = SelectedAccount; return(repositoryPublishService.PublishRepository(newRepository, account, SelectedHost.ApiClient) .Do(_ => usageTracker.IncrementCounter(x => x.NumberOfReposPublished).Forget()) .Select(_ => ProgressState.Success) .Catch <ProgressState, Exception>(ex => { if (!ex.IsCriticalException()) { log.Error(ex, "Error Publishing Repository"); var error = new PublishRepositoryUserError(ex.Message); notificationService.ShowError((error.ErrorMessage + Environment.NewLine + error.ErrorCauseOrResolution).TrimEnd()); } return Observable.Return(ProgressState.Fail); })); }
/// <inheritdoc/> public async Task InitializeAsync(IServiceProvider paneServiceProvider) { await UpdateContent(teServiceHolder.ActiveRepo); teServiceHolder.Subscribe(this, x => UpdateContent(x).Forget()); connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget(); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser); paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand, (_, __) => { browser.OpenUrl(new Uri(GitHubUrls.Documentation)); usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget(); }); }
public async Task IncrementCounter(Expression <Func <UsageModel.MeasuresModel, int> > counter) { await Initialize(); var property = (MemberExpression)counter.Body; var propertyInfo = (PropertyInfo)property.Member; var counterName = propertyInfo.Name; log.Verbose("Increment counter {Name}", counterName); var updateTask = UpdateUsageMetrics(propertyInfo); if (visualStudioUsageTracker != null) { // Not available on Visual Studio 2015 await visualStudioUsageTracker.IncrementCounter(counter); } await updateTask; }
void Load(PullRequestDetailModel pullRequest) { IsBusy = true; try { PullRequestTitle = pullRequest.Title; var checkSuiteRun = pullRequest .CheckSuites.SelectMany(checkSuite => checkSuite.CheckRuns .Select(checkRun => new{ checkSuite, checkRun })) .First(arg => arg.checkRun.Id == CheckRunId); CheckSuiteName = checkSuiteRun.checkSuite.ApplicationName; CheckRunName = checkSuiteRun.checkRun.Name; CheckRunSummary = checkSuiteRun.checkRun.Summary; CheckRunText = checkSuiteRun.checkRun.Text; var changedFiles = new HashSet <string>(session.PullRequest.ChangedFiles.Select(model => model.FileName)); var annotationsLookup = checkSuiteRun.checkRun.Annotations .ToLookup(annotation => annotation.Path); AnnotationsDictionary = annotationsLookup .Select(models => models.Key) .OrderBy(s => s) .ToDictionary( path => path, path => annotationsLookup[path] .Select(annotation => new PullRequestAnnotationItemViewModel(annotation, changedFiles.Contains(path), checkSuiteRun.checkSuite, session, pullRequestEditorService)) .Cast <IPullRequestAnnotationItemViewModel>() .ToArray() ); usageTracker.IncrementCounter(x => x.NumberOfPullRequestOpenAnnotationsList).Forget(); } finally { IsBusy = false; } }
/// <inheritdoc/> public async Task InitializeAsync(IServiceProvider paneServiceProvider) { await initializing.WaitAsync(); if (initialized) { return; } try { await UpdateContent(teamExplorerContext.ActiveRepository); teamExplorerContext.WhenAnyValue(x => x.ActiveRepository) .Skip(1) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => UpdateContent(x).Forget()); connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget(); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh); BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser); paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand, (_, __) => { browser.OpenUrl(new Uri(GitHubUrls.Documentation)); usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget(); }); } finally { initialized = true; initializing.Release(); } }
IObservable <Gist> OnCreateGist(object unused) { var newGist = new NewGist { Description = Description, Public = !IsPrivate }; newGist.Files.Add(FileName, SelectedText); return(gistPublishService.PublishGist(apiClient, newGist) .Do(_ => usageTracker.IncrementCounter(x => x.NumberOfGists).Forget()) .Catch <Gist, Exception>(ex => { if (!ex.IsCriticalException()) { log.Error(ex, "Error Creating Gist"); var error = StandardUserErrors.GetUserFriendlyErrorMessage(ex, ErrorType.GistCreateFailed); notificationService.ShowError(error); } return Observable.Return <Gist>(null); })); }
public GitHubPaneViewModel( IViewViewModelFactory viewModelFactory, ISimpleApiClientFactory apiClientFactory, IConnectionManager connectionManager, ITeamExplorerContext teamExplorerContext, IVisualStudioBrowser browser, IUsageTracker usageTracker, INavigationViewModel navigator, ILoggedOutViewModel loggedOut, INotAGitHubRepositoryViewModel notAGitHubRepository, INotAGitRepositoryViewModel notAGitRepository, INoRemoteOriginViewModel noRemoteOrigin, ILoginFailedViewModel loginFailed) { Guard.ArgumentNotNull(viewModelFactory, nameof(viewModelFactory)); Guard.ArgumentNotNull(apiClientFactory, nameof(apiClientFactory)); Guard.ArgumentNotNull(connectionManager, nameof(connectionManager)); Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext)); Guard.ArgumentNotNull(browser, nameof(browser)); Guard.ArgumentNotNull(usageTracker, nameof(usageTracker)); Guard.ArgumentNotNull(navigator, nameof(navigator)); Guard.ArgumentNotNull(loggedOut, nameof(loggedOut)); Guard.ArgumentNotNull(notAGitHubRepository, nameof(notAGitHubRepository)); Guard.ArgumentNotNull(notAGitRepository, nameof(notAGitRepository)); Guard.ArgumentNotNull(noRemoteOrigin, nameof(noRemoteOrigin)); Guard.ArgumentNotNull(loginFailed, nameof(loginFailed)); this.viewModelFactory = viewModelFactory; this.apiClientFactory = apiClientFactory; this.connectionManager = connectionManager; this.teamExplorerContext = teamExplorerContext; this.navigator = navigator; this.loggedOut = loggedOut; this.notAGitHubRepository = notAGitHubRepository; this.notAGitRepository = notAGitRepository; this.noRemoteOrigin = noRemoteOrigin; this.loginFailed = loginFailed; var contentAndNavigatorContent = Observable.CombineLatest( this.WhenAnyValue(x => x.Content), navigator.WhenAnyValue(x => x.Content), (c, nc) => new { Content = c, NavigatorContent = nc }); contentOverride = contentAndNavigatorContent .SelectMany(x => { if (x.Content == null) { return(Observable.Return(ContentOverride.Spinner)); } else if (x.Content == navigator && x.NavigatorContent != null) { return(x.NavigatorContent.WhenAnyValue( y => y.IsLoading, y => y.Error, (l, e) => { if (l) { return ContentOverride.Spinner; } if (e != null) { return ContentOverride.Error; } else { return ContentOverride.None; } })); } else { return(Observable.Return(ContentOverride.None)); } }) .ToProperty(this, x => x.ContentOverride); // Returns navigator.Content if Content == navigator, otherwise null. var currentPage = contentAndNavigatorContent .Select(x => x.Content == navigator ? x.NavigatorContent : null); title = currentPage .SelectMany(x => x?.WhenAnyValue(y => y.Title) ?? Observable.Return <string>(null)) .Select(x => x ?? "GitHub") .ToProperty(this, x => x.Title); isSearchEnabled = currentPage .Select(x => x is ISearchablePageViewModel) .ToProperty(this, x => x.IsSearchEnabled); refresh = ReactiveCommand.CreateFromTask( () => navigator.Content.Refresh(), currentPage.SelectMany(x => x?.WhenAnyValue( y => y.IsLoading, y => y.IsBusy, (loading, busy) => !loading && !busy) ?? Observable.Return(false))); refresh.ThrownExceptions.Subscribe(); showPullRequests = ReactiveCommand.CreateFromTask( ShowPullRequests, this.WhenAny(x => x.Content, x => x.Value == navigator)); openInBrowser = ReactiveCommand.Create( () => { var url = ((IOpenInBrowser)navigator.Content).WebUrl; if (url != null) { browser.OpenUrl(url); } }, currentPage.Select(x => x is IOpenInBrowser)); BrowseRepository = ReactiveCommand.Create( () => { var url = LocalRepository.CloneUrl.ToRepositoryUrl(); if (url != null) { browser.OpenUrl(url); } }, currentPage.Select(x => x is IOpenInBrowser)); help = ReactiveCommand.Create(() => { }); help.Subscribe(_ => { browser.OpenUrl(new Uri(GitHubUrls.Documentation)); usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget(); }); navigator.WhenAnyObservable(x => x.Content.NavigationRequested) .Subscribe(x => NavigateTo(x).Forget()); this.WhenAnyValue(x => x.SearchQuery) .Where(x => navigator.Content is ISearchablePageViewModel) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => ((ISearchablePageViewModel)navigator.Content).SearchQuery = x); }
public override void Initialize(IServiceProvider serviceProvider) { Guard.ArgumentNotNull(serviceProvider, nameof(serviceProvider)); serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.pullRequestCommand, (s, e) => Load(new ViewWithData(UIControllerFlow.PullRequestList)).Forget()); back = serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.backCommand, () => !disabled && (navController?.HasBack ?? false), () => { DisableButtons(); navController.Back(); }, true); forward = serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.forwardCommand, () => !disabled && (navController?.HasForward ?? false), () => { DisableButtons(); navController.Forward(); }, true); refresh = serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.refreshCommand, () => !disabled, () => { DisableButtons(); Refresh(); }, true); serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.githubCommand, () => !disabled && (RepositoryOrigin == RepositoryOrigin.DotCom || RepositoryOrigin == RepositoryOrigin.Enterprise), () => { switch (navController?.Current.CurrentFlow) { case UIControllerFlow.PullRequestDetail: var prDetailViewModel = control.DataContext as IPullRequestDetailViewModel; if (prDetailViewModel != null) { browser.OpenUrl(ActiveRepoUri.ToRepositoryUrl().Append("pull/" + prDetailViewModel.Model.Number)); } else { goto default; } break; case UIControllerFlow.PullRequestList: case UIControllerFlow.PullRequestCreation: browser.OpenUrl(ActiveRepoUri.ToRepositoryUrl().Append("pulls/")); break; case UIControllerFlow.Home: default: browser.OpenUrl(ActiveRepoUri.ToRepositoryUrl()); break; } }, true); serviceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand, () => true, () => { browser.OpenUrl(new Uri(GitHubUrls.Documentation)); usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget(); }, true); initialized = true; base.Initialize(serviceProvider); hosts.WhenAnyValue(x => x.IsLoggedInToAnyHost).Subscribe(_ => LoadDefault()); }
public Task IncrementCounter(Expression <Func <UsageModel, int> > counter) => inner.IncrementCounter(counter);
public override void Execute() { openPullRequests.Execute(); usageTracker.IncrementCounter(x => x.NumberOfTeamExplorerHomeOpenPullRequestList).Forget(); }
public void Execute(object parameter) { command.Execute(parameter); usageTracker.IncrementCounter(counter).Forget(); }
/// <inheritdoc/> public async Task <ITextView> OpenFile( IPullRequestSession session, string relativePath, bool workingDirectory) { Guard.ArgumentNotNull(session, nameof(session)); Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath)); try { var fullPath = GetAbsolutePath(session.LocalRepository, relativePath); string fileName; string commitSha; if (workingDirectory) { fileName = fullPath; commitSha = null; } else { var file = await session.GetFile(relativePath); fileName = await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, file.RelativePath, file.CommitSha, pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath)); commitSha = file.CommitSha; } IVsTextView textView; IWpfTextView wpfTextView; using (workingDirectory ? null : OpenInProvisionalTab()) { var readOnly = !workingDirectory; textView = OpenDocument(fileName, readOnly, out wpfTextView); if (!workingDirectory) { AddBufferTag(wpfTextView.TextBuffer, session, fullPath, commitSha, null); EnableNavigateToEditor(textView, session); } } if (workingDirectory) { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsOpenFileInSolution); } else { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsViewFile); } return(wpfTextView); } catch (Exception e) { ShowErrorInStatusBar("Error opening file", e); return(null); } }
private void DoOpenDetailsUrl(object obj) { usageTracker.IncrementCounter(x => x.NumberOfPRCheckStatusesOpenInGitHub).Forget(); }
/// <summary> /// Loads the view model from octokit models. /// </summary> /// <param name="pullRequest">The pull request model.</param> public async Task Load(PullRequestDetailModel pullRequest) { try { var firstLoad = (Model == null); Model = pullRequest; Author = new ActorViewModel(pullRequest.Author); Title = Resources.PullRequestNavigationItemText + " #" + pullRequest.Number; IsBusy = true; IsFromFork = !pullRequestsService.IsPullRequestFromRepository(LocalRepository, pullRequest); SourceBranchDisplayName = GetBranchDisplayName(IsFromFork, pullRequest.HeadRepositoryOwner, pullRequest.HeadRefName); TargetBranchDisplayName = GetBranchDisplayName(IsFromFork, pullRequest.BaseRepositoryOwner, pullRequest.BaseRefName); Body = !string.IsNullOrWhiteSpace(pullRequest.Body) ? pullRequest.Body : Resources.NoDescriptionProvidedMarkdown; Reviews = PullRequestReviewSummaryViewModel.BuildByUser(Session.User, pullRequest).ToList(); Checks = (IReadOnlyList <IPullRequestCheckViewModel>)PullRequestCheckViewModel.Build(viewViewModelFactory, pullRequest)?.ToList() ?? Array.Empty <IPullRequestCheckViewModel>(); // Only show unresolved comments await Files.InitializeAsync(Session, c => !c.IsResolved); var localBranches = await pullRequestsService.GetLocalBranches(LocalRepository, pullRequest).ToList(); var currentBranch = gitService.GetBranch(LocalRepository); IsCheckedOut = localBranches.Contains(currentBranch); if (IsCheckedOut) { var divergence = await pullRequestsService.CalculateHistoryDivergence(LocalRepository, Model.Number); var pullEnabled = divergence.BehindBy > 0; var pushEnabled = divergence.AheadBy > 0 && !pullEnabled; string pullToolTip; string pushToolTip; if (pullEnabled) { pullToolTip = string.Format( CultureInfo.InvariantCulture, Resources.PullRequestDetailsPullToolTip, IsFromFork ? Resources.Fork : Resources.Remote, SourceBranchDisplayName); } else { pullToolTip = Resources.NoCommitsToPull; } if (pushEnabled) { pushToolTip = string.Format( CultureInfo.InvariantCulture, Resources.PullRequestDetailsPushToolTip, IsFromFork ? Resources.Fork : Resources.Remote, SourceBranchDisplayName); } else if (divergence.AheadBy == 0) { pushToolTip = Resources.NoCommitsToPush; } else { pushToolTip = Resources.MustPullBeforePush; } var submodulesToSync = await pullRequestsService.CountSubmodulesToSync(LocalRepository); var syncSubmodulesToolTip = string.Format(CultureInfo.InvariantCulture, Resources.SyncSubmodules, submodulesToSync); UpdateState = new UpdateCommandState(divergence, pullEnabled, pushEnabled, pullToolTip, pushToolTip, syncSubmodulesToolTip, submodulesToSync); CheckoutState = null; } else { var caption = localBranches.Count > 0 ? string.Format( CultureInfo.InvariantCulture, Resources.PullRequestDetailsCheckout, localBranches.First().DisplayName) : string.Format( CultureInfo.InvariantCulture, Resources.PullRequestDetailsCheckoutTo, await pullRequestsService.GetDefaultLocalBranchName(LocalRepository, Model.Number, Model.Title)); var clean = await pullRequestsService.IsWorkingDirectoryClean(LocalRepository); string disabled = null; if (pullRequest.HeadRepositoryOwner == null) { disabled = Resources.SourceRepositoryNoLongerAvailable; } else if (!clean) { disabled = Resources.WorkingDirectoryHasUncommittedCHanges; } CheckoutState = new CheckoutCommandState(caption, disabled); UpdateState = null; } sessionSubscription?.Dispose(); sessionSubscription = Session.WhenAnyValue(x => x.HasPendingReview) .Skip(1) .Subscribe(x => Reviews = PullRequestReviewSummaryViewModel.BuildByUser(Session.User, Session.PullRequest).ToList()); if (firstLoad) { usageTracker.IncrementCounter(x => x.NumberOfPullRequestsOpened).Forget(); } if (!isInCheckout) { pullRequestsService.RemoveUnusedRemotes(LocalRepository).Subscribe(_ => { }); } } finally { IsBusy = false; } }
/// <inheritdoc/> public async Task OpenFile( IPullRequestSession session, string relativePath, bool workingDirectory) { Guard.ArgumentNotNull(session, nameof(session)); Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath)); try { var fullPath = Path.Combine(session.LocalRepository.LocalPath, relativePath); string fileName; string commitSha; if (workingDirectory) { fileName = fullPath; commitSha = null; } else { var file = await session.GetFile(relativePath); fileName = await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, file.RelativePath, file.CommitSha, pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath)); commitSha = file.CommitSha; } using (workingDirectory ? null : OpenInProvisionalTab()) { var window = VisualStudio.Services.Dte.ItemOperations.OpenFile(fileName); window.Document.ReadOnly = !workingDirectory; var buffer = GetBufferAt(fileName); if (!workingDirectory) { AddBufferTag(buffer, session, fullPath, commitSha, null); var textView = FindActiveView(); var file = await session.GetFile(relativePath); EnableNavigateToEditor(textView, session, file); } } if (workingDirectory) { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsOpenFileInSolution); } else { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsViewFile); } } catch (Exception e) { ShowErrorInStatusBar("Error opening file", e); } }