Skip to content

Commit 503e9da

Browse files
dfev77RussKie
authored andcommitted
(split from main repo) Gerrit: fix server version parsing (#7559)
* Gerrit: add configuration for gerrit version Connecting to gerrit and retrieving configuration requires too many configurations to work properly due to possible configuration combinations (api port, http/https, etc.). Instead just allow the user to configure the desired Gerrit version. Extract code that is dependent on Gerrit version into separate classes (list of publish types and logic for composing command) in order to be able to test it. * Gerrit: Don't close window is unsuccessful So that user can change values and retry
1 parent 31cd7c0 commit 503e9da

9 files changed

+206
-99
lines changed

FormGerritBase.cs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
using System;
22
using GitUI;
33
using GitUIPluginInterfaces;
4-
using RestSharp;
54

65
namespace Gerrit
76
{
87
public class FormGerritBase : GitExtensionsForm
98
{
109
protected GerritSettings Settings { get; private set; }
11-
protected Version Version { get; private set; }
12-
protected readonly RestClient client = new RestClient();
1310
protected readonly IGitUICommands UICommands;
1411
protected IGitModule Module => UICommands.GitModule;
1512

@@ -39,34 +36,7 @@ protected override void OnLoad(EventArgs e)
3936
return;
4037
}
4138

42-
SetRestClientUrl();
43-
Version = GetGerritVersion();
44-
4539
base.OnLoad(e);
4640
}
47-
48-
private void SetRestClientUrl()
49-
{
50-
string host = Settings.Host;
51-
52-
if (!host.StartsWith("http://") || !host.StartsWith("https://"))
53-
{
54-
host = "https://" + host;
55-
}
56-
57-
if (!host.EndsWith("/"))
58-
{
59-
host += "/";
60-
}
61-
62-
client.BaseUrl = new Uri(host);
63-
}
64-
65-
private Version GetGerritVersion()
66-
{
67-
RestRequest request = new RestRequest("/config/server/version");
68-
IRestResponse response = client.Execute(request);
69-
return Version.Parse(response.Content.Replace(")]}'", "").Replace("\n", "").Replace("\"", "").Split('-')[0]);
70-
}
7141
}
7242
}

FormGerritPublish.cs

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Linq;
45
using System.Windows.Forms;
6+
using Gerrit.Server;
57
using GitCommands;
68
using GitExtUtils;
79
using GitExtUtils.GitUI.Theming;
@@ -14,42 +16,34 @@ namespace Gerrit
1416
{
1517
public partial class FormGerritPublish : FormGerritBase
1618
{
17-
private string _currentBranchRemote;
18-
1919
#region Translation
2020
private readonly TranslationString _publishGerritChangeCaption = new TranslationString("Publish Gerrit Change");
2121

2222
private readonly TranslationString _publishCaption = new TranslationString("Publish change");
2323

2424
private readonly TranslationString _selectRemote = new TranslationString("Please select a remote repository");
2525
private readonly TranslationString _selectBranch = new TranslationString("Please enter a branch");
26-
27-
private readonly TranslationString _publishTypeReview = new TranslationString("For Review");
28-
private readonly TranslationString _publishTypeWip = new TranslationString("Work-in-Progress");
29-
private readonly TranslationString _publishTypePrivate = new TranslationString("Private");
3026
#endregion
3127

32-
public FormGerritPublish(IGitUICommands uiCommand)
28+
private string _currentBranchRemote;
29+
private GerritCapabilities _capabilities;
30+
31+
public FormGerritPublish(IGitUICommands uiCommand, GerritCapabilities capabilities)
3332
: base(uiCommand)
3433
{
34+
_capabilities = capabilities;
3535
InitializeComponent();
3636
Publish.Image = Images.Push.AdaptLightness();
3737
InitializeComplete();
38-
PublishType.Items.AddRange(new object[]
39-
{
40-
new KeyValuePair<string, string>(_publishTypeReview.Text, ""),
41-
new KeyValuePair<string, string>(_publishTypeWip.Text, "wip")
42-
});
43-
PublishType.SelectedIndex = 0;
4438
}
4539

4640
protected override void OnLoad(EventArgs e)
4741
{
4842
base.OnLoad(e);
49-
if (Version >= Version.Parse("2.15"))
50-
{
51-
PublishType.Items.Add(new KeyValuePair<string, string>(_publishTypePrivate.Text, "private"));
52-
}
43+
44+
_capabilities.PublishTypes.ForEach(
45+
item => PublishType.Items.Add(item));
46+
PublishType.SelectedIndex = 0;
5347
}
5448

5549
private void PublishClick(object sender, EventArgs e)
@@ -88,59 +82,17 @@ private bool PublishChange(IWin32Window owner)
8882

8983
GerritUtil.StartAgent(owner, Module, _NO_TRANSLATE_Remotes.Text);
9084

91-
List<string> additionalOptions = new List<string>();
92-
93-
string reviewers = _NO_TRANSLATE_Reviewers.Text.Trim();
94-
if (!string.IsNullOrEmpty(reviewers))
95-
{
96-
additionalOptions.AddRange(reviewers.Split(new[] { ' ', ',', ';', '|' })
97-
.Where(r => !string.IsNullOrEmpty(r))
98-
.Select(r => "r=" + r));
99-
}
100-
101-
string cc = _NO_TRANSLATE_Cc.Text.Trim();
102-
if (!string.IsNullOrEmpty(cc))
103-
{
104-
additionalOptions.AddRange(cc.Split(new[] { ' ', ',', ';', '|' })
105-
.Where(r => !string.IsNullOrEmpty(r))
106-
.Select(r => "cc=" + r));
107-
}
108-
109-
string topic = _NO_TRANSLATE_Topic.Text.Trim();
110-
if (!string.IsNullOrEmpty(topic))
111-
{
112-
additionalOptions.Add("topic=" + topic);
113-
}
114-
115-
string hashtag = _NO_TRANSLATE_Hashtag.Text.Trim();
116-
if (!string.IsNullOrEmpty(hashtag))
117-
{
118-
additionalOptions.Add("hashtag=" + hashtag);
119-
}
120-
121-
additionalOptions = additionalOptions.Where(r => !string.IsNullOrEmpty(r)).ToList();
122-
123-
string publishType = ((KeyValuePair<string, string>)PublishType.SelectedItem).Value;
124-
string targetRef = "for";
125-
if (Version >= Version.Parse("2.15"))
126-
{
127-
additionalOptions.Add(publishType);
128-
}
129-
else if (publishType == "wip")
130-
{
131-
targetRef = "drafts";
132-
}
133-
134-
string targetBranch = $"refs/{targetRef}/{branch}";
135-
if (additionalOptions.Count > 0)
136-
{
137-
targetBranch += "%" + string.Join(",", additionalOptions);
138-
}
85+
var builder = _capabilities.NewBuilder()
86+
.WithReviewers(_NO_TRANSLATE_Reviewers.Text)
87+
.WithCC(_NO_TRANSLATE_Cc.Text)
88+
.WithTopic(_NO_TRANSLATE_Topic.Text)
89+
.WithHashTag(_NO_TRANSLATE_Hashtag.Text)
90+
.WithPublishType(((KeyValuePair<string, string>)PublishType.SelectedItem).Value);
13991

14092
var pushCommand = UICommands.CreateRemoteCommand();
14193
pushCommand.CommandText = PushCmd(
14294
_NO_TRANSLATE_Remotes.Text,
143-
targetBranch);
95+
builder.Build(branch));
14496

14597
pushCommand.Remote = _NO_TRANSLATE_Remotes.Text;
14698
pushCommand.Title = _publishCaption.Text;
@@ -176,7 +128,7 @@ private bool PublishChange(IWin32Window owner)
176128
}
177129
}
178130

179-
return true;
131+
return !pushCommand.ErrorOccurred;
180132
}
181133

182134
[CanBeNull]

Gerrit.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@
9696
<DesignTime>True</DesignTime>
9797
<DependentUpon>Resources.resx</DependentUpon>
9898
</Compile>
99+
<Compile Include="Server\CommandBuilder.cs" />
100+
<Compile Include="Server\CommandBuilderWithDraftSupport.cs" />
101+
<Compile Include="Server\CommandBuilderWithPrivateSupport.cs" />
102+
<Compile Include="Server\GerritCapabilities.cs" />
99103
</ItemGroup>
100104
<ItemGroup>
101105
<ProjectReference Include="..\..\GitCommands\GitCommands.csproj">
@@ -157,5 +161,6 @@
157161
<Content Include="Resources\GerritInstallHook.png" />
158162
<None Include="Resources\IconGerrit.png" />
159163
</ItemGroup>
164+
<ItemGroup />
160165
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
161166
</Project>

GerritPlugin.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading.Tasks;
88
using System.Windows.Forms;
99
using Gerrit.Properties;
10+
using Gerrit.Server;
1011
using GitUI;
1112
using GitUIPluginInterfaces;
1213
using JetBrains.Annotations;
@@ -28,6 +29,13 @@ public class GerritPlugin : GitPluginBase, IGitPluginForRepository
2829
private readonly TranslationString _installCommitMsgHookDownloadFileFailed = new TranslationString("Could not download the commit-msg file. Please install the commit-msg hook manually.");
2930
#endregion
3031

32+
private const string DefaultGerritVersion = "2.15 or newer";
33+
34+
private readonly ChoiceSetting _predefinedGerritVersion = new ChoiceSetting(
35+
"Treat Gerrit as having version",
36+
new[] { DefaultGerritVersion, "Older then 2.15" },
37+
DefaultGerritVersion);
38+
3139
private static readonly Dictionary<string, bool> _validatedHooks = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
3240
private static readonly object _syncRoot = new object();
3341

@@ -42,7 +50,7 @@ public class GerritPlugin : GitPluginBase, IGitPluginForRepository
4250
private ToolStripButton _installCommitMsgMenuItem;
4351

4452
// public only because of FormTranslate
45-
public GerritPlugin() : base(false)
53+
public GerritPlugin() : base(true)
4654
{
4755
SetNameAndDescription("Gerrit Code Review");
4856
Translate();
@@ -248,7 +256,11 @@ private void Initialize(Form form)
248256

249257
private void publishMenuItem_Click(object sender, EventArgs e)
250258
{
251-
using (var form = new FormGerritPublish(_gitUiCommands))
259+
var capabilities = _predefinedGerritVersion.ValueOrDefault(Settings) == DefaultGerritVersion
260+
? GerritCapabilities.Version2_15
261+
: GerritCapabilities.OldestVersion;
262+
263+
using (var form = new FormGerritPublish(_gitUiCommands, capabilities))
252264
{
253265
form.ShowDialog(_mainForm);
254266
}
@@ -421,5 +433,10 @@ public override bool Execute(GitUIEventArgs args)
421433

422434
return false;
423435
}
436+
437+
public override IEnumerable<ISetting> GetSettings()
438+
{
439+
yield return _predefinedGerritVersion;
440+
}
424441
}
425442
}

Properties/AssemblyInfo.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
using System.Reflection;
2+
using System.Runtime.CompilerServices;
23

34
[assembly: AssemblyDescription("GitExtensions plugin for integration with Gerrit")]
5+
[assembly: InternalsVisibleTo("GerritTests")]

Server/CommandBuilder.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Gerrit.Server
6+
{
7+
public abstract class CommandBuilder
8+
{
9+
protected string TargetRef = "for";
10+
protected List<string> CommandArguments { get; } = new List<string>();
11+
12+
private static IEnumerable<string> SplitAndComposeArguments(string argumentName, string values)
13+
{
14+
values = values?.Trim();
15+
if (string.IsNullOrEmpty(values))
16+
{
17+
return Enumerable.Empty<string>();
18+
}
19+
20+
return ComposeArguments(argumentName, values.Split(new[] { ' ', ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries));
21+
}
22+
23+
private static IEnumerable<string> ComposeArguments(string argumentName, string[] values)
24+
{
25+
return values.Where(text => !string.IsNullOrEmpty(text))
26+
.Select(text => $"{argumentName}={text}");
27+
}
28+
29+
private static IEnumerable<string> ComposeArgument(string argumentName, string value)
30+
{
31+
return ComposeArguments(argumentName, new[] { value?.Trim() });
32+
}
33+
34+
public CommandBuilder WithReviewers(string text)
35+
{
36+
CommandArguments.AddRange(SplitAndComposeArguments("r", text));
37+
return this;
38+
}
39+
40+
public CommandBuilder WithCC(string text)
41+
{
42+
CommandArguments.AddRange(SplitAndComposeArguments("cc", text));
43+
return this;
44+
}
45+
46+
public CommandBuilder WithTopic(string topic)
47+
{
48+
CommandArguments.AddRange(ComposeArgument(@"topic", topic));
49+
return this;
50+
}
51+
52+
public CommandBuilder WithHashTag(string hashTag)
53+
{
54+
CommandArguments.AddRange(ComposeArgument(@"hashtag", hashTag));
55+
return this;
56+
}
57+
58+
public abstract CommandBuilder WithPublishType(string publishType);
59+
60+
public virtual string Build(string branch)
61+
{
62+
string targetBranch = $"refs/{TargetRef}/{branch}";
63+
if (CommandArguments.Count > 0)
64+
{
65+
targetBranch += "%" + string.Join(",", CommandArguments);
66+
}
67+
68+
return targetBranch;
69+
}
70+
}
71+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Gerrit.Server
2+
{
3+
public class CommandBuilderWithDraftSupport : CommandBuilder
4+
{
5+
public const string DraftsPublishType = @"drafts";
6+
7+
public override CommandBuilder WithPublishType(string publishType)
8+
{
9+
if (publishType == DraftsPublishType)
10+
{
11+
TargetRef = DraftsPublishType;
12+
}
13+
14+
return this;
15+
}
16+
}
17+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace Gerrit.Server
2+
{
3+
public class CommandBuilderWithPrivateSupport : CommandBuilder
4+
{
5+
private string _publishType;
6+
7+
public override CommandBuilder WithPublishType(string publishType)
8+
{
9+
_publishType = publishType?.Trim();
10+
11+
return this;
12+
}
13+
14+
public override string Build(string branch)
15+
{
16+
if (!string.IsNullOrEmpty(_publishType))
17+
{
18+
CommandArguments.Add(_publishType);
19+
}
20+
21+
return base.Build(branch);
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)