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

Reduce extension footprint when not in repository context #1802

Merged
merged 10 commits into from
Aug 7, 2018
35 changes: 25 additions & 10 deletions src/GitHub.InlineReviews/Margins/InlineCommentMarginProvider.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Utilities;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Text.Classification;
using GitHub.InlineReviews.Services;
using GitHub.Services;
using GitHub.VisualStudio;
using GitHub.InlineReviews.Services;

namespace GitHub.InlineReviews.Margins
{
Expand All @@ -17,28 +19,41 @@ namespace GitHub.InlineReviews.Margins
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal sealed class InlineCommentMarginProvider : IWpfTextViewMarginProvider
{
readonly IEditorFormatMapService editorFormatMapService;
readonly IViewTagAggregatorFactoryService tagAggregatorFactory;
readonly IInlineCommentPeekService peekService;
readonly Lazy<IEditorFormatMapService> editorFormatMapService;
readonly Lazy<IViewTagAggregatorFactoryService> tagAggregatorFactory;
readonly Lazy<IInlineCommentPeekService> peekService;
readonly Lazy<IPullRequestSessionManager> sessionManager;
readonly UIContext uiContext;

[ImportingConstructor]
public InlineCommentMarginProvider(
IGitHubServiceProvider serviceProvider,
IEditorFormatMapService editorFormatMapService,
IViewTagAggregatorFactoryService tagAggregatorFactory,
IInlineCommentPeekService peekService)
Lazy<IPullRequestSessionManager> sessionManager,
Lazy<IEditorFormatMapService> editorFormatMapService,
Lazy<IViewTagAggregatorFactoryService> tagAggregatorFactory,
Lazy<IInlineCommentPeekService> peekService)
{
this.sessionManager = sessionManager;
this.editorFormatMapService = editorFormatMapService;
this.tagAggregatorFactory = tagAggregatorFactory;
this.peekService = peekService;
sessionManager = new Lazy<IPullRequestSessionManager>(() => serviceProvider.GetService<IPullRequestSessionManager>());

uiContext = UIContext.FromUIContextGuid(new Guid(Guids.UIContext_Git));
}

public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin parent)
{
if (!uiContext.IsActive)
{
// Only create margin when in the context of a Git repository
return null;
}

return new InlineCommentMargin(
wpfTextViewHost, peekService, editorFormatMapService, tagAggregatorFactory, sessionManager);
wpfTextViewHost,
peekService.Value,
editorFormatMapService.Value,
tagAggregatorFactory.Value,
sessionManager);
}
}
}
35 changes: 25 additions & 10 deletions src/GitHub.InlineReviews/Margins/PullRequestFileMarginProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using GitHub.Commands;
using GitHub.Services;
using GitHub.Settings;
using GitHub.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Utilities;
using Microsoft.VisualStudio.Text.Editor;

Expand All @@ -19,25 +21,28 @@ namespace GitHub.InlineReviews.Margins
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed class PullRequestFileMarginProvider : IWpfTextViewMarginProvider
{
readonly IPullRequestSessionManager sessionManager;
readonly IToggleInlineCommentMarginCommand enableInlineCommentsCommand;
readonly IGoToSolutionOrPullRequestFileCommand goToSolutionOrPullRequestFileCommand;
readonly IPackageSettings packageSettings;
readonly Lazy<IPullRequestSessionManager> sessionManager;
readonly Lazy<IToggleInlineCommentMarginCommand> enableInlineCommentsCommand;
readonly Lazy<IGoToSolutionOrPullRequestFileCommand> goToSolutionOrPullRequestFileCommand;
readonly Lazy<IPackageSettings> packageSettings;
readonly Lazy<IUsageTracker> usageTracker;
readonly UIContext uiContext;

[ImportingConstructor]
public PullRequestFileMarginProvider(
IToggleInlineCommentMarginCommand enableInlineCommentsCommand,
IGoToSolutionOrPullRequestFileCommand goToSolutionOrPullRequestFileCommand,
IPullRequestSessionManager sessionManager,
IPackageSettings packageSettings,
Lazy<IToggleInlineCommentMarginCommand> enableInlineCommentsCommand,
Lazy<IGoToSolutionOrPullRequestFileCommand> goToSolutionOrPullRequestFileCommand,
Lazy<IPullRequestSessionManager> sessionManager,
Lazy<IPackageSettings> packageSettings,
Lazy<IUsageTracker> usageTracker)
{
this.enableInlineCommentsCommand = enableInlineCommentsCommand;
this.goToSolutionOrPullRequestFileCommand = goToSolutionOrPullRequestFileCommand;
this.sessionManager = sessionManager;
this.packageSettings = packageSettings;
this.usageTracker = usageTracker;

uiContext = UIContext.FromUIContextGuid(new Guid(Guids.UIContext_Git));
}

/// <summary>
Expand All @@ -50,8 +55,14 @@ public PullRequestFileMarginProvider(
/// </returns>
public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin marginContainer)
{
if (!uiContext.IsActive)
{
// Only create margin when in the context of a Git repository
return null;
}

// Comments in the editor feature flag
if (!packageSettings.EditorComments)
if (!packageSettings.Value.EditorComments)
{
return null;
}
Expand All @@ -63,7 +74,11 @@ public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTex
}

return new PullRequestFileMargin(
wpfTextViewHost.TextView, enableInlineCommentsCommand, goToSolutionOrPullRequestFileCommand, sessionManager, usageTracker);
wpfTextViewHost.TextView,
enableInlineCommentsCommand.Value,
goToSolutionOrPullRequestFileCommand.Value,
sessionManager.Value,
usageTracker);
}

bool IsDiffView(ITextView textView) => textView.Roles.Contains("DIFF");
Expand Down
6 changes: 3 additions & 3 deletions src/GitHub.TeamFoundation.14/Services/VSGitExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
using Task = System.Threading.Tasks.Task;
using static Microsoft.VisualStudio.VSConstants;

namespace GitHub.VisualStudio.Base
{
Expand Down Expand Up @@ -51,9 +52,8 @@ public VSGitExt(IAsyncServiceProvider asyncServiceProvider, IVSUIContextFactory
// Start with empty array until we have a chance to initialize.
ActiveRepositories = Array.Empty<ILocalRepositoryModel>();

// The IGitExt service isn't available when a TFS based solution is opened directly.
// It will become available when moving to a Git based solution (and cause a UIContext event to fire).
var context = factory.GetUIContext(new Guid(Guids.GitSccProviderId));
// Initialize when we enter the context of a Git repository
var context = factory.GetUIContext(UICONTEXT.RepositoryOpen_guid);
context.WhenActivated(() => JoinableTaskFactory.RunAsync(InitializeAsync).Task.Forget(log));
}

Expand Down
13 changes: 5 additions & 8 deletions src/GitHub.VisualStudio/GitContextPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,28 @@
using System.Threading;
using System.Runtime.InteropServices;
using GitHub.Exports;
using GitHub.Logging;
using GitHub.Services;
using Microsoft.VisualStudio.Shell;
using Serilog;
using Task = System.Threading.Tasks.Task;
using static Microsoft.VisualStudio.VSConstants;

namespace GitHub.VisualStudio
{
/// <summary>
/// This package creates a custom UIContext <see cref="Guids.UIContext_Git"/> that is activated when a
/// repository is active in <see cref="IVSGitExt"/>.
/// repository is active in <see cref="IVSGitExt"/> and the current process is Visual Studio (not Blend).
/// </summary>
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(Guids.UIContext_Git)]
// this is the Git service GUID, so we load whenever it loads
[ProvideAutoLoad(Guids.GitSccProviderId, PackageAutoLoadFlags.BackgroundLoad)]
// Initialize when we enter the context of a Git repository
[ProvideAutoLoad(UICONTEXT.RepositoryOpen_string, PackageAutoLoadFlags.BackgroundLoad)]
public class GitContextPackage : AsyncPackage
{
static readonly ILogger log = LogManager.ForContext<GitContextPackage>();

protected async override Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
if (!ExportForVisualStudioProcessAttribute.IsVisualStudioProcess())
{
log.Warning("Don't activate 'UIContext_Git' for non-Visual Studio process");
// Don't activate 'UIContext_Git' for non-Visual Studio process
return;
}

Expand Down
30 changes: 16 additions & 14 deletions src/GitHub.VisualStudio/Resources/icons/mark_github.xaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Width="1024" Height="1024">
<Viewbox
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
Width="1024" Height="1024">

<Viewbox.Resources>
<ResourceDictionary>
<Color x:Key="GitHubContextMenuIconColor">#424242</Color>
<SolidColorBrush x:Key="GitHubContextMenuIconBrush" Color="{StaticResource GitHubContextMenuIconColor}" PresentationOptions:Freeze="true" />
</ResourceDictionary>
</Viewbox.Resources>

<Border BorderBrush="Transparent" BorderThickness="1">
<ghfvs:OcticonImage xmlns:ghfvs="https://github.com/github/VisualStudio"
Foreground="{DynamicResource GitHubContextMenuIconBrush}"
Icon="mark_github">
<ghfvs:OcticonImage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ghfvs:SharedDictionaryManager Source="pack://application:,,,/GitHub.VisualStudio.UI;component/SharedDictionary.xaml" />
<ghfvs:SharedDictionaryManager Source="pack://application:,,,/GitHub.UI;component/SharedDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ghfvs:OcticonImage.Resources>
</ghfvs:OcticonImage>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Width="16" Height="16">
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Fill="{StaticResource GitHubContextMenuIconBrush}" Data="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</Canvas>
</Border>
</Viewbox>
10 changes: 5 additions & 5 deletions test/GitHub.TeamFoundation.UnitTests/VSGitExtTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
using Task = System.Threading.Tasks.Task;
using static Microsoft.VisualStudio.VSConstants;

public class VSGitExtTests
{
public class TheConstructor : TestBaseClass
{
[TestCase(true, 1)]
[TestCase(false, 0)]
public void GetServiceIGitExt_WhenSccProviderContextIsActive(bool isActive, int expectCalls)
public void GetServiceIGitExt_WhenRepositoryOpenIsActive(bool isActive, int expectCalls)
{
var context = CreateVSUIContext(isActive);
var sp = Substitute.For<IAsyncServiceProvider>();
Expand Down Expand Up @@ -135,7 +136,7 @@ public void WhenUIContextChanged_FiredUsingThreadPoolThread()
public class TheActiveRepositoriesProperty : TestBaseClass
{
[Test]
public void SccProviderContextNotActive_IsEmpty()
public void RepositoryOpenContextNotActive_IsEmpty()
{
var context = CreateVSUIContext(false);
var target = CreateVSGitExt(context);
Expand All @@ -144,7 +145,7 @@ public void SccProviderContextNotActive_IsEmpty()
}

[Test]
public void SccProviderContextIsActive_InitializeWithActiveRepositories()
public void RepositoryOpenIsActive_InitializeWithActiveRepositories()
{
var repoPath = "repoPath";
var repoFactory = Substitute.For<ILocalRepositoryModelFactory>();
Expand Down Expand Up @@ -217,8 +218,7 @@ static VSGitExt CreateVSGitExt(IVSUIContext context = null, IGitExt gitExt = nul
repoFactory = repoFactory ?? Substitute.For<ILocalRepositoryModelFactory>();
joinableTaskContext = joinableTaskContext ?? new JoinableTaskContext();
var factory = Substitute.For<IVSUIContextFactory>();
var contextGuid = new Guid(Guids.GitSccProviderId);
factory.GetUIContext(contextGuid).Returns(context);
factory.GetUIContext(UICONTEXT.RepositoryOpen_guid).Returns(context);
sp.GetServiceAsync(typeof(IGitExt)).Returns(gitExt);
var vsGitExt = new VSGitExt(sp, factory, repoFactory, joinableTaskContext);
vsGitExt.JoinTillEmpty();
Expand Down