From 154b14a3e8028df8f509d8fcec01fdb33ec2afda Mon Sep 17 00:00:00 2001 From: Manuel-S Date: Wed, 22 Jun 2016 12:21:36 +0200 Subject: [PATCH 1/2] Use Visual Studio Settings Store This changeset removes the FileSettingProvider and uses the Visual Studio User Setting store instead, as this is the recommended way of storing extension settings. The Settings-Object is now managed by MEF as Singleton. --- src/AutoMerge.Tests/AutoMerge.Tests.csproj | 1 - src/AutoMerge.Tests/JsonParserTests.cs | 20 ---- src/AutoMerge/AutoMerge.csproj | 4 +- src/AutoMerge/AutoMergePackage.cs | 4 +- src/AutoMerge/AutoMergePage.cs | 2 + src/AutoMerge/Branches/BranchesSection.cs | 9 +- src/AutoMerge/Branches/BranchesViewModel.cs | 12 ++- .../Configuration/FileSettingProvider.cs | 71 ------------- .../Configuration/ISettingProvider.cs | 9 -- src/AutoMerge/Configuration/JsonParser.cs | 23 ---- src/AutoMerge/Configuration/Settings.cs | 100 +++++++----------- src/AutoMerge/source.extension.vsixmanifest | 4 +- 12 files changed, 61 insertions(+), 198 deletions(-) delete mode 100644 src/AutoMerge.Tests/JsonParserTests.cs delete mode 100644 src/AutoMerge/Configuration/FileSettingProvider.cs delete mode 100644 src/AutoMerge/Configuration/ISettingProvider.cs delete mode 100644 src/AutoMerge/Configuration/JsonParser.cs diff --git a/src/AutoMerge.Tests/AutoMerge.Tests.csproj b/src/AutoMerge.Tests/AutoMerge.Tests.csproj index 4a22bf7..e0bdd64 100644 --- a/src/AutoMerge.Tests/AutoMerge.Tests.csproj +++ b/src/AutoMerge.Tests/AutoMerge.Tests.csproj @@ -57,7 +57,6 @@ - diff --git a/src/AutoMerge.Tests/JsonParserTests.cs b/src/AutoMerge.Tests/JsonParserTests.cs deleted file mode 100644 index 4ed1b50..0000000 --- a/src/AutoMerge.Tests/JsonParserTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Xunit; - -namespace AutoMerge.Tests -{ - public class JsonParserTests - { - [Fact] - public void WhenValueHasNewLine_ShouldCorrectParse() - { - var value = string.Format("{0}Patch Back", Environment.NewLine); - var json = string.Format("{{\"comment_format\": \"{0}\"}}", value); - - var values = JsonParser.ParseJson(json); - - Assert.NotEmpty(values); - Assert.Equal(value, values["comment_format"]); - } - } -} diff --git a/src/AutoMerge/AutoMerge.csproj b/src/AutoMerge/AutoMerge.csproj index 86dd076..b1bf92e 100644 --- a/src/AutoMerge/AutoMerge.csproj +++ b/src/AutoMerge/AutoMerge.csproj @@ -47,6 +47,7 @@ ..\..\lib\System.Windows.Interactivity.WPF.2.0.20525\lib\net40\Microsoft.Expression.Interactions.dll True + @@ -216,9 +217,6 @@ - - - SplitButton.xaml diff --git a/src/AutoMerge/AutoMergePackage.cs b/src/AutoMerge/AutoMergePackage.cs index ac206e5..5a8d99e 100644 --- a/src/AutoMerge/AutoMergePackage.cs +++ b/src/AutoMerge/AutoMergePackage.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System.ComponentModel.Composition; +using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using Microsoft.VisualStudio.Shell; @@ -38,7 +39,6 @@ public AutoMergePackage() } - ///////////////////////////////////////////////////////////////////////////// // Overridden Package Implementation #region Package Members diff --git a/src/AutoMerge/AutoMergePage.cs b/src/AutoMerge/AutoMergePage.cs index 4be3ddb..e1b5a46 100644 --- a/src/AutoMerge/AutoMergePage.cs +++ b/src/AutoMerge/AutoMergePage.cs @@ -15,5 +15,7 @@ public AutoMergePage() { Title = Resources.AutoMergePageName; } + + } } diff --git a/src/AutoMerge/Branches/BranchesSection.cs b/src/AutoMerge/Branches/BranchesSection.cs index 300928f..661cc32 100644 --- a/src/AutoMerge/Branches/BranchesSection.cs +++ b/src/AutoMerge/Branches/BranchesSection.cs @@ -1,5 +1,7 @@ -using AutoMerge.Base; +using System.ComponentModel.Composition; +using AutoMerge.Base; using Microsoft.TeamFoundation.Controls; +using Microsoft.VisualStudio.ComponentModelHost; namespace AutoMerge { @@ -11,9 +13,12 @@ protected override object CreateView(SectionInitializeEventArgs e) return new BranchesView(); } + [Import] + public Settings Settings { get; set; } + protected override ITeamExplorerSection CreateViewModel(SectionInitializeEventArgs e) { - var viewModel = base.CreateViewModel(e) ?? new BranchesViewModel(new VsLogger(ServiceProvider)); + var viewModel = base.CreateViewModel(e) ?? new BranchesViewModel(Settings, new VsLogger(ServiceProvider)); return viewModel; } diff --git a/src/AutoMerge/Branches/BranchesViewModel.cs b/src/AutoMerge/Branches/BranchesViewModel.cs index 88e2e5a..634fd12 100644 --- a/src/AutoMerge/Branches/BranchesViewModel.cs +++ b/src/AutoMerge/Branches/BranchesViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel.Composition; using System.Globalization; using System.Linq; using System.Reflection; @@ -16,6 +17,7 @@ using Microsoft.TeamFoundation.VersionControl.Client; using Microsoft.TeamFoundation.VersionControl.Common; using Microsoft.TeamFoundation.WorkItemTracking.Client; +using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell.Interop; using TeamExplorerSectionViewModelBase = AutoMerge.Base.TeamExplorerSectionViewModelBase; @@ -24,13 +26,14 @@ namespace AutoMerge public sealed class BranchesViewModel : TeamExplorerSectionViewModelBase { private readonly IEventAggregator _eventAggregator; + private readonly Settings _settings; private ChangesetService _changesetService; private Workspace _workspace; private ChangesetViewModel _changeset; private bool _merging; - public BranchesViewModel(ILogger logger) + public BranchesViewModel(Settings settings, ILogger logger) : base(logger) { Title = Resources.BrancheSectionName; @@ -42,6 +45,7 @@ public BranchesViewModel(ILogger logger) SelectWorkspaceCommand = new DelegateCommand(SelectWorkspaceExecute); OpenSourceControlExplorerCommand = new DelegateCommand(OpenSourceControlExplorerExecute, OpenSourceControlExplorerCanExecute); + _settings = settings; _eventAggregator = EventAggregatorFactory.Get(); _merging = false; } @@ -212,7 +216,7 @@ protected async override Task InitializeAsync(object sender, SectionInitializeEv MergeMode.Merge, MergeMode.MergeAndCheckIn }; - MergeMode = Settings.Instance.LastMergeOperation; + MergeMode = _settings.LastMergeOperation; await RefreshAsync(); } @@ -581,7 +585,7 @@ private async void MergeExecute(MergeMode? mergeMode) if (!mergeMode.HasValue) return; MergeMode = mergeMode.Value; - Settings.Instance.LastMergeOperation = mergeMode.Value; + _settings.LastMergeOperation = mergeMode.Value; switch (mergeMode) { case MergeMode.Merge: @@ -769,7 +773,7 @@ private List MergeExecuteInternal(bool checkInIfSuccess) var pendingChanges = GetChangesetPendingChanges(changeset.Changes); var mergeRelationships = GetMergeRelationships(pendingChanges, targetBranches, versionControl); - var commentFormater = new CommentFormater(Settings.Instance.CommentFormat); + var commentFormater = new CommentFormater(_settings.CommentFormat); foreach (var mergeInfo in mergeInfos.Where(b => b.Checked)) { var mergeResultModel = new MergeResultModel diff --git a/src/AutoMerge/Configuration/FileSettingProvider.cs b/src/AutoMerge/Configuration/FileSettingProvider.cs deleted file mode 100644 index 61cb332..0000000 --- a/src/AutoMerge/Configuration/FileSettingProvider.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.IO; - -namespace AutoMerge -{ - internal class FileSettingProvider : ISettingProvider - { - public T ReadValue(string key) - { - if (key == null) - throw new ArgumentNullException("key"); - - T value; - if (!TryReadValue(key, out value)) - throw new InvalidOperationException(string.Format("Setting {0} not found", key)); - - return value; - } - - public bool TryReadValue(string key, out T value) - { - if (key == null) - throw new ArgumentNullException("key"); - - value = default(T); - var path = GetSettingFilePath(); - var settingJson = File.ReadAllText(path); - var settings = JsonParser.ParseJson(settingJson); - - string stringValue; - if (!settings.TryGetValue(key, out stringValue)) - return false; - - value = (T) Convert.ChangeType(stringValue, typeof(T)); - return true; - } - - public void WriteValue(string key, T value) - { - if (key == null) - throw new ArgumentNullException("key"); - - var path = GetSettingFilePath(); - var settingJson = File.ReadAllText(path); - var settings = JsonParser.ParseJson(settingJson); - - settings[key] = value.ToString(); - - settingJson = JsonParser.ToJson(settings); - File.WriteAllText(path, settingJson); - } - - private static string GetSettingFilePath() - { - var roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - var autoMergeFolder = Path.Combine(roamingPath, "Visual Studio Auto Merge"); - if (!Directory.Exists(autoMergeFolder)) - { - Directory.CreateDirectory(autoMergeFolder); - } - var settingFilePath = Path.Combine(autoMergeFolder, "automerge.conf"); - if (!File.Exists(settingFilePath)) - { - using (File.Create(settingFilePath)) - { - } - } - return settingFilePath; - } - } -} diff --git a/src/AutoMerge/Configuration/ISettingProvider.cs b/src/AutoMerge/Configuration/ISettingProvider.cs deleted file mode 100644 index 64ce808..0000000 --- a/src/AutoMerge/Configuration/ISettingProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AutoMerge -{ - internal interface ISettingProvider - { - T ReadValue(string key); - bool TryReadValue(string key, out T value); - void WriteValue(string key, T value); - } -} diff --git a/src/AutoMerge/Configuration/JsonParser.cs b/src/AutoMerge/Configuration/JsonParser.cs deleted file mode 100644 index 366c8e8..0000000 --- a/src/AutoMerge/Configuration/JsonParser.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web.Script.Serialization; - -namespace AutoMerge -{ - public static class JsonParser - { - public static Dictionary ParseJson(string jsonText) - { - var jss = new JavaScriptSerializer(); - return jss.Deserialize>(jsonText); - } - - public static string ToJson(Dictionary dict) - { - var entries = dict.Select(d => - string.Format("\"{0}\": \"{1}\"", d.Key, d.Value)); - return "{" + Environment.NewLine + " " + string.Join(",\r\n ", entries) + Environment.NewLine + "}"; - } - } -} diff --git a/src/AutoMerge/Configuration/Settings.cs b/src/AutoMerge/Configuration/Settings.cs index afca987..f38d943 100644 --- a/src/AutoMerge/Configuration/Settings.cs +++ b/src/AutoMerge/Configuration/Settings.cs @@ -1,14 +1,20 @@ using System; +using System.ComponentModel.Composition; using System.Linq; +using Microsoft.VisualStudio.Settings; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Settings; namespace AutoMerge { - internal class Settings + [Export] + public class Settings { - private readonly ISettingProvider _settingProvider; - private static readonly Lazy _instance; - private MergeMode? _lastMergeOperation; + private readonly string[] _mergeOperationDefaultValues; + private readonly WritableSettingsStore _vsSettingsProvider; + + private const string collectionKey = "AutoMerge"; private const string lastMergeOperationKey = "last_operation"; private const string mergeModeMerge = "merge"; @@ -18,7 +24,6 @@ internal class Settings private const string mergeOperationDefaultLast = "last"; private const string mergeOperationDefaultMerge = mergeModeMerge; private const string mergeOperationDefaultMergeCheckin = mergeModeMergeAndCheckin; - private readonly string[] _mergeOperationDefaultValues; private const string commentFormatKey = "comment_format"; private const string commentFormatDefault = "MERGE {FromOriginalToTarget} ({OriginalComment})"; @@ -27,24 +32,27 @@ internal class Settings private const string branchDelimiterKey = "branch_delimiter"; private const string branchDelimiterDefault = " -> "; - static Settings() + private static WritableSettingsStore GetWritableSettingsStore(IServiceProvider vsServiceProvider) { - _instance = new Lazy(() => new Settings()); + var shellSettingsManager = new ShellSettingsManager(vsServiceProvider); + return shellSettingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); } - private Settings() + [ImportingConstructor] + public Settings(SVsServiceProvider serviceProvider) { - _settingProvider = new FileSettingProvider(); - _mergeOperationDefaultValues = new[] - {mergeOperationDefaultLast, mergeOperationDefaultMerge, mergeOperationDefaultMergeCheckin}; - } + _vsSettingsProvider = GetWritableSettingsStore(serviceProvider); - public static Settings Instance - { - get { return _instance.Value; } + if (!_vsSettingsProvider.CollectionExists(collectionKey)) + { + _vsSettingsProvider.CreateCollection(collectionKey); + } + + _mergeOperationDefaultValues = new[] { mergeOperationDefaultLast, mergeOperationDefaultMerge, mergeOperationDefaultMergeCheckin }; } - public MergeMode LastMergeOperation { + public MergeMode LastMergeOperation + { get { return LastMergeOperationGet(); @@ -57,38 +65,15 @@ public MergeMode LastMergeOperation { public CommentFormat CommentFormat { - get { return CommentFormatGet(); } - } - - private CommentFormat CommentFormatGet() - { - string commentFormat; - if (!_settingProvider.TryReadValue(commentFormatKey, out commentFormat)) - { - commentFormat = commentFormatDefault; - } - - string commentFormatDiscard; - if (!_settingProvider.TryReadValue(commentFormatDiscardKey, out commentFormatDiscard)) - { - commentFormatDiscard = commentFormatDiscardDefault; - } - - commentFormatDiscard = commentFormatDiscard.Replace("{" + commentFormatKey + "}", commentFormat); - - string branchDelimiter; - if (!_settingProvider.TryReadValue(branchDelimiterKey, out branchDelimiter)) + get { - branchDelimiter = branchDelimiterDefault; + return new CommentFormat + { + Format = _vsSettingsProvider.GetString(collectionKey, commentFormatKey, commentFormatDefault), + BranchDelimiter = _vsSettingsProvider.GetString(collectionKey, branchDelimiterKey, branchDelimiterDefault), + DiscardFormat = _vsSettingsProvider.GetString(collectionKey, commentFormatDiscardKey, commentFormatDiscardDefault) + }; } - - return new CommentFormat - { - Format = commentFormat, - BranchDelimiter = branchDelimiter, - DiscardFormat = commentFormatDiscard - }; - } private MergeMode LastMergeOperationGet() @@ -99,13 +84,9 @@ private MergeMode LastMergeOperationGet() { if (!_lastMergeOperation.HasValue) { - string stringValue; - if (!_settingProvider.TryReadValue(lastMergeOperationKey, out stringValue)) - { - stringValue = mergeModeMergeAndCheckin; - } - - _lastMergeOperation = ToMergeMode(stringValue); + _lastMergeOperation = + ToMergeMode(_vsSettingsProvider.GetString(collectionKey, lastMergeOperationKey, + mergeModeMergeAndCheckin)); } result = _lastMergeOperation.Value; @@ -123,7 +104,7 @@ private void LastMergeOperationSet(MergeMode mergeMode) if (_lastMergeOperation != mergeMode) { var stringValue = ToString(mergeMode); - _settingProvider.WriteValue(lastMergeOperationKey, stringValue); + _vsSettingsProvider.SetString(collectionKey, lastMergeOperationKey, stringValue); _lastMergeOperation = mergeMode; } } @@ -150,15 +131,12 @@ private static string ToString(MergeMode mergeMode) private string MergeOperationDefaultGet() { - string mergeOperationDefaultValue; - if (!_settingProvider.TryReadValue(mergeOperationDefaultKey, out mergeOperationDefaultValue)) - { - mergeOperationDefaultValue = mergeOperationDefaultLast; - _settingProvider.WriteValue(mergeOperationDefaultKey, mergeOperationDefaultValue); - } + var mergeOperationDefaultValue = _vsSettingsProvider.GetString(collectionKey, mergeOperationDefaultKey, mergeOperationDefaultLast); if (!_mergeOperationDefaultValues.Contains(mergeOperationDefaultValue)) - mergeOperationDefaultValue = "mergeOperationDefaultLast"; + mergeOperationDefaultValue = mergeOperationDefaultLast; + + _vsSettingsProvider.SetString(collectionKey, mergeOperationDefaultKey, mergeOperationDefaultValue); return mergeOperationDefaultValue; } diff --git a/src/AutoMerge/source.extension.vsixmanifest b/src/AutoMerge/source.extension.vsixmanifest index 60d1017..3031b4a 100644 --- a/src/AutoMerge/source.extension.vsixmanifest +++ b/src/AutoMerge/source.extension.vsixmanifest @@ -1,11 +1,11 @@  - + Auto Merge for Visual Studio 2013 Easy way to merge changeset LICENSE.txt - RELEASE_NOTES.md + https://github.com/CDuke/AutoMerge/blob/master/RELEASE_NOTES.md Resources/merge.png Resources/preview.png merge code, merge, merging, branch, changeset, merge by work item, tfs From aa288a2d5a5df25c0ffc8b325ff552e8f47f1d27 Mon Sep 17 00:00:00 2001 From: Manuel-S Date: Wed, 22 Jun 2016 15:21:17 +0200 Subject: [PATCH 2/2] Add ability to override branch names Implemented https://github.com/CDuke/AutoMerge/issues/13. As there is no Settings UI yet, it can only be changed at HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{Visual Studio Version}\AutoMerge. The setting is saved under the key "branch_overrides" and takes JSON as described in the issue. --- src/AutoMerge/AutoMerge.csproj | 1 + src/AutoMerge/Branches/BranchFactory.cs | 8 +++- src/AutoMerge/Branches/BranchesViewModel.cs | 10 +++-- src/AutoMerge/Branches/MergeInfoViewModel.cs | 11 ++++-- src/AutoMerge/CommentFormater.cs | 13 ++++--- .../Configuration/BranchNameMatch.cs | 14 +++++++ src/AutoMerge/Configuration/Settings.cs | 39 +++++++++++++++++-- src/AutoMerge/Helpers/BranchHelper.cs | 31 ++++++++++----- .../RecentChangesets/ChangesetProviderBase.cs | 13 +++++-- .../RecentChangesets/ChangesetViewModel.cs | 12 +++--- 10 files changed, 118 insertions(+), 34 deletions(-) create mode 100644 src/AutoMerge/Configuration/BranchNameMatch.cs diff --git a/src/AutoMerge/AutoMerge.csproj b/src/AutoMerge/AutoMerge.csproj index b1bf92e..2782745 100644 --- a/src/AutoMerge/AutoMerge.csproj +++ b/src/AutoMerge/AutoMerge.csproj @@ -216,6 +216,7 @@ + diff --git a/src/AutoMerge/Branches/BranchFactory.cs b/src/AutoMerge/Branches/BranchFactory.cs index 2cb119a..974558f 100644 --- a/src/AutoMerge/Branches/BranchFactory.cs +++ b/src/AutoMerge/Branches/BranchFactory.cs @@ -11,18 +11,21 @@ public class BranchFactory private readonly ChangesetVersionSpec _changesetVersion; private readonly BranchValidator _branchValidator; private readonly IEventAggregator _eventAggregator; + private readonly Settings _settings; public BranchFactory(string sourceBranch, string sourceFolder, ChangesetVersionSpec changesetVersion, BranchValidator branchValidator, - IEventAggregator eventAggregator) + IEventAggregator eventAggregator, + Settings settings) { _sourceBranch = sourceBranch; _sourceFolder = sourceFolder; _changesetVersion = changesetVersion; _branchValidator = branchValidator; _eventAggregator = eventAggregator; + _settings = settings; } public MergeInfoViewModel CreateTargetBranchInfo(ItemIdentifier targetBranch, ItemIdentifier targetPath) @@ -37,7 +40,7 @@ public MergeInfoViewModel CreateSourceBranch() private MergeInfoViewModel CreateBranch(string targetBranch, string targetPath) { - var mergeInfo = new MergeInfoViewModel(_eventAggregator) + var mergeInfo = new MergeInfoViewModel(_eventAggregator, _settings.BranchNameMatches) { SourceBranch = _sourceBranch, TargetBranch = targetBranch, @@ -45,6 +48,7 @@ private MergeInfoViewModel CreateBranch(string targetBranch, string targetPath) TargetPath = targetPath, ChangesetVersionSpec = _changesetVersion, ValidationResult = BranchValidationResult.Success, + Aliases = _settings.BranchNameMatches }; if (_sourceBranch != targetBranch) diff --git a/src/AutoMerge/Branches/BranchesViewModel.cs b/src/AutoMerge/Branches/BranchesViewModel.cs index 634fd12..fa946f6 100644 --- a/src/AutoMerge/Branches/BranchesViewModel.cs +++ b/src/AutoMerge/Branches/BranchesViewModel.cs @@ -311,6 +311,8 @@ private ObservableCollection GetBranches(ITeamFoundationCont var sourceTopFolder = CalculateTopFolder(changes); var mergesRelationships = GetMergesRelationships(sourceTopFolder, versionControl); + + if (mergesRelationships.Count > 0) { var sourceBranchIdentifier = changesetViewModel.Branches.Select(b => new ItemIdentifier(b)).First(); @@ -327,7 +329,7 @@ private ObservableCollection GetBranches(ITeamFoundationCont var branchValidator = new BranchValidator(workspace, trackMerges); var branchFactory = new BranchFactory(sourceBranch, sourceTopFolder, changesetVersionSpec, branchValidator, - _eventAggregator); + _eventAggregator, _settings); var sourceBranchInfo = versionControl.QueryBranchObjects(sourceBranchIdentifier, RecursionType.None)[0]; if (sourceBranchInfo.Properties != null && sourceBranchInfo.Properties.ParentBranch != null @@ -619,8 +621,8 @@ private async Task MergeAndCheckInExecute(bool checkInIfSuccess) Message = string.Empty }; var mergePath = string.Format("MERGE {0} -> {1}", - BranchHelper.GetShortBranchName(resultModel.BranchInfo.SourceBranch), - BranchHelper.GetShortBranchName(resultModel.BranchInfo.TargetBranch)); + BranchHelper.GetShortBranchName(resultModel.BranchInfo.SourceBranch, _settings.BranchNameMatches), + BranchHelper.GetShortBranchName(resultModel.BranchInfo.TargetBranch, _settings.BranchNameMatches)); switch (resultModel.MergeResult) { case MergeResult.CheckInEvaluateFail: @@ -773,7 +775,7 @@ private List MergeExecuteInternal(bool checkInIfSuccess) var pendingChanges = GetChangesetPendingChanges(changeset.Changes); var mergeRelationships = GetMergeRelationships(pendingChanges, targetBranches, versionControl); - var commentFormater = new CommentFormater(_settings.CommentFormat); + var commentFormater = new CommentFormater(_settings.CommentFormat, _settings.BranchNameMatches); foreach (var mergeInfo in mergeInfos.Where(b => b.Checked)) { var mergeResultModel = new MergeResultModel diff --git a/src/AutoMerge/Branches/MergeInfoViewModel.cs b/src/AutoMerge/Branches/MergeInfoViewModel.cs index 5dbf1ab..7a8f55b 100644 --- a/src/AutoMerge/Branches/MergeInfoViewModel.cs +++ b/src/AutoMerge/Branches/MergeInfoViewModel.cs @@ -1,4 +1,5 @@ using System; +using AutoMerge.Configuration; using AutoMerge.Events; using AutoMerge.Prism.Events; using Microsoft.TeamFoundation.VersionControl.Client; @@ -8,11 +9,13 @@ namespace AutoMerge public class MergeInfoViewModel { private readonly IEventAggregator _eventAggregator; + private readonly BranchNameMatch[] _aliases; internal bool _checked; - public MergeInfoViewModel(IEventAggregator eventAggregator) + public MergeInfoViewModel(IEventAggregator eventAggregator, BranchNameMatch[] aliases) { _eventAggregator = eventAggregator; + _aliases = aliases; } public bool Checked @@ -43,7 +46,7 @@ public string DisplayBranchName { get { - return BranchHelper.GetShortBranchName(TargetBranch); + return BranchHelper.GetShortBranchName(TargetBranch, _aliases); } } @@ -58,5 +61,7 @@ public bool IsSourceBranch return string.Equals(SourceBranch, TargetBranch, StringComparison.OrdinalIgnoreCase); } } - } + + public Configuration.BranchNameMatch[] Aliases { get; set; } + } } diff --git a/src/AutoMerge/CommentFormater.cs b/src/AutoMerge/CommentFormater.cs index 2445a7c..1b952ca 100644 --- a/src/AutoMerge/CommentFormater.cs +++ b/src/AutoMerge/CommentFormater.cs @@ -1,27 +1,30 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using AutoMerge.Configuration; namespace AutoMerge { public class CommentFormater { private readonly CommentFormat _format; + private readonly BranchNameMatch[] _aliases; - public CommentFormater(CommentFormat format) + public CommentFormater(CommentFormat format, BranchNameMatch[] aliases) { _format = format; + _aliases = aliases; } public string Format(TrackMergeInfo trackMergeInfo, string targetBranch, MergeOption mergeOption) { var comment = mergeOption == MergeOption.KeepTarget ? _format.DiscardFormat : _format.Format; comment = comment - .Replace("{OriginalBranch}", BranchHelper.GetShortBranchName(trackMergeInfo.OriginaBranch)) + .Replace("{OriginalBranch}", BranchHelper.GetShortBranchName(trackMergeInfo.OriginaBranch, _aliases)) .Replace("{OriginalBranchFull}", trackMergeInfo.OriginaBranch) - .Replace("{SourceBranch}", BranchHelper.GetShortBranchName(trackMergeInfo.SourceBranch)) + .Replace("{SourceBranch}", BranchHelper.GetShortBranchName(trackMergeInfo.SourceBranch, _aliases)) .Replace("{SourceBranchFull}", trackMergeInfo.SourceBranch) - .Replace("{TargetBranch}", BranchHelper.GetShortBranchName(targetBranch)) + .Replace("{TargetBranch}", BranchHelper.GetShortBranchName(targetBranch, _aliases)) .Replace("{TargetBranchFull}", targetBranch) .Replace("{FromOriginalToTarget}", FromOriginalToTarget(trackMergeInfo, targetBranch)) .Replace("{FromOriginalToTargetFull}", FromOriginalToTargetFull(trackMergeInfo, targetBranch)) @@ -41,7 +44,7 @@ private string GetWorkItemIds(List sourceWorkItemIds) private string FromOriginalToTarget(TrackMergeInfo trackMergeInfo, string targetBranch) { var mergePath = trackMergeInfo.FromOriginalToSourceBranches.Concat(new[] { trackMergeInfo.SourceBranch, targetBranch }) - .Select(fullBranchName => BranchHelper.GetShortBranchName(fullBranchName)); + .Select(fullBranchName => BranchHelper.GetShortBranchName(fullBranchName, _aliases)); var mergePathString = string.Join(_format.BranchDelimiter, mergePath); return mergePathString; } diff --git a/src/AutoMerge/Configuration/BranchNameMatch.cs b/src/AutoMerge/Configuration/BranchNameMatch.cs new file mode 100644 index 0000000..8933e3b --- /dev/null +++ b/src/AutoMerge/Configuration/BranchNameMatch.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoMerge.Configuration +{ + public class BranchNameMatch + { + public string match { get; set; } + public string alias { get; set; } + } +} diff --git a/src/AutoMerge/Configuration/Settings.cs b/src/AutoMerge/Configuration/Settings.cs index f38d943..cf98a58 100644 --- a/src/AutoMerge/Configuration/Settings.cs +++ b/src/AutoMerge/Configuration/Settings.cs @@ -1,9 +1,13 @@ -using System; -using System.ComponentModel.Composition; +using System.ComponentModel.Composition; +using System.IO; using System.Linq; +using System.Web.Script.Serialization; +using AutoMerge.Configuration; +using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Settings; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Settings; +using IServiceProvider = System.IServiceProvider; namespace AutoMerge { @@ -13,8 +17,9 @@ public class Settings private MergeMode? _lastMergeOperation; private readonly string[] _mergeOperationDefaultValues; private readonly WritableSettingsStore _vsSettingsProvider; + private BranchNameMatch[] _aliases; - private const string collectionKey = "AutoMerge"; + private const string collectionKey = "AutoMerge"; private const string lastMergeOperationKey = "last_operation"; private const string mergeModeMerge = "merge"; @@ -31,6 +36,7 @@ public class Settings private const string commentFormatDiscardDefault = "DISCARD {" + commentFormatKey + "}"; private const string branchDelimiterKey = "branch_delimiter"; private const string branchDelimiterDefault = " -> "; + private const string branchNameMatchesKey = "branch_overrides"; private static WritableSettingsStore GetWritableSettingsStore(IServiceProvider vsServiceProvider) { @@ -49,6 +55,8 @@ public Settings(SVsServiceProvider serviceProvider) } _mergeOperationDefaultValues = new[] { mergeOperationDefaultLast, mergeOperationDefaultMerge, mergeOperationDefaultMergeCheckin }; + + BranchNameMatches = BranchNameMatches ?? new BranchNameMatch[0]; } public MergeMode LastMergeOperation @@ -76,6 +84,31 @@ public CommentFormat CommentFormat } } + public BranchNameMatch[] BranchNameMatches + { + get + { + if (_aliases != null) + return _aliases; + + var json = _vsSettingsProvider.GetString(collectionKey, branchNameMatchesKey, ""); + if (string.IsNullOrWhiteSpace(json)) + return null; + + var serializer = new JavaScriptSerializer(); + var result = serializer.Deserialize(json); + _aliases = result; + return result; + } + set + { + _aliases = value; + var serializer = new JavaScriptSerializer(); + var result = serializer.Serialize(_aliases); + _vsSettingsProvider.SetString(collectionKey, branchNameMatchesKey, result); + } + } + private MergeMode LastMergeOperationGet() { MergeMode result; diff --git a/src/AutoMerge/Helpers/BranchHelper.cs b/src/AutoMerge/Helpers/BranchHelper.cs index 870d090..c9990f7 100644 --- a/src/AutoMerge/Helpers/BranchHelper.cs +++ b/src/AutoMerge/Helpers/BranchHelper.cs @@ -1,26 +1,39 @@ using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using AutoMerge.Configuration; namespace AutoMerge { internal static class BranchHelper { - public static string GetShortBranchName(string branchFullName) - { - var pos = branchFullName.LastIndexOf('/'); - var name = branchFullName.Substring(pos + 1); - return name; - } + public static string GetShortBranchName(string branchFullName, BranchNameMatch[] aliases) + { + + foreach (var branchNameMatch in (aliases ?? new BranchNameMatch[0]) + .Concat(new[] { new BranchNameMatch { match = "/([^/]+)$", alias = "$1" } })) // default match + { + var regex = new Regex(branchNameMatch.match); + var match = regex.Match(branchFullName); + if (match.Success) + { + return match.Result(branchNameMatch.alias); //return first match + } + } + + return branchFullName; // return full name if nothing matched + } - public static string GetDisplayBranchName(List branches) + public static string GetDisplayBranchName(List branches, BranchNameMatch[] aliases) { if (branches == null || branches.Count == 0) return string.Empty; if (branches.Count == 1) { - return GetShortBranchName(branches[0]); + return GetShortBranchName(branches[0], aliases); } return "multi"; } } -} \ No newline at end of file +} diff --git a/src/AutoMerge/RecentChangesets/ChangesetProviderBase.cs b/src/AutoMerge/RecentChangesets/ChangesetProviderBase.cs index 17627e5..a762657 100644 --- a/src/AutoMerge/RecentChangesets/ChangesetProviderBase.cs +++ b/src/AutoMerge/RecentChangesets/ChangesetProviderBase.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.TeamFoundation.VersionControl.Client; +using Microsoft.VisualStudio.ComponentModelHost; namespace AutoMerge { @@ -10,11 +11,15 @@ public abstract class ChangesetProviderBase : IChangesetProvider { private readonly IServiceProvider _serviceProvider; private readonly Lazy _changesetService; + private readonly Settings _settings; protected ChangesetProviderBase(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; _changesetService = new Lazy(InitChangesetService); + + var componentModel = (IComponentModel)_serviceProvider.GetService(typeof (SComponentModel)); + _settings = componentModel.DefaultExportProvider.GetExportedValue(); } public Task> GetChangesets(string userLogin) @@ -26,13 +31,15 @@ public Task> GetChangesets(string userLogin) protected ChangesetViewModel ToChangesetViewModel(Changeset tfsChangeset, ChangesetService changesetService) { + var branches = changesetService.GetAssociatedBranches(tfsChangeset.ChangesetId) + .Select(i => i.Item) + .ToList(); var changesetViewModel = new ChangesetViewModel { ChangesetId = tfsChangeset.ChangesetId, Comment = tfsChangeset.Comment, - Branches = changesetService.GetAssociatedBranches(tfsChangeset.ChangesetId) - .Select(i => i.Item) - .ToList() + Branches = branches, + DisplayBranchName = BranchHelper.GetDisplayBranchName(branches, _settings.BranchNameMatches) }; return changesetViewModel; diff --git a/src/AutoMerge/RecentChangesets/ChangesetViewModel.cs b/src/AutoMerge/RecentChangesets/ChangesetViewModel.cs index 244e551..a466c82 100644 --- a/src/AutoMerge/RecentChangesets/ChangesetViewModel.cs +++ b/src/AutoMerge/RecentChangesets/ChangesetViewModel.cs @@ -4,15 +4,17 @@ namespace AutoMerge { public class ChangesetViewModel { + public ChangesetViewModel() + { + + } + public int ChangesetId { get; set; } public string Comment { get; set; } public List Branches { get; set; } - public string DisplayBranchName - { - get { return BranchHelper.GetDisplayBranchName(Branches); } - } + public string DisplayBranchName { get; set; } } -} \ No newline at end of file +}