PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Plugins/Gerrit/FormGerritDownload.cs

https://github.com/eisnerd/gitextensions
C# | 265 lines | 213 code | 50 blank | 2 comment | 25 complexity | 72da9263d0323d59bc00b3d8f7a727ac MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Windows.Forms;
  7. using GitCommands;
  8. using GitUIPluginInterfaces;
  9. using Newtonsoft.Json.Linq;
  10. using ResourceManager.Translation;
  11. namespace Gerrit
  12. {
  13. public partial class FormGerritDownload : FormGerritBase
  14. {
  15. private readonly IGitUICommands _uiCommand;
  16. private string _currentBranchRemote;
  17. #region Translation
  18. private readonly TranslationString _downloadGerritChangeCaption = new TranslationString("Download Gerrit Change");
  19. private readonly TranslationString _downloadCaption = new TranslationString("Download change {0}");
  20. private readonly TranslationString _selectRemote = new TranslationString("Please select a remote repository");
  21. private readonly TranslationString _selectChange = new TranslationString("Please enter a change");
  22. private readonly TranslationString _cannotGetChangeDetails = new TranslationString("Could not retrieve the change details");
  23. #endregion
  24. public FormGerritDownload(IGitUICommands uiCommand)
  25. {
  26. _uiCommand = uiCommand;
  27. InitializeComponent();
  28. Translate();
  29. }
  30. public void PushAndShowDialogWhenFailed(IWin32Window owner)
  31. {
  32. if (!DownloadChange(owner))
  33. ShowDialog(owner);
  34. }
  35. public void PushAndShowDialogWhenFailed()
  36. {
  37. PushAndShowDialogWhenFailed(null);
  38. }
  39. private void DownloadClick(object sender, EventArgs e)
  40. {
  41. if (DownloadChange(this))
  42. Close();
  43. }
  44. private bool DownloadChange(IWin32Window owner)
  45. {
  46. string change = _NO_TRANSLATE_Change.Text.Trim();
  47. if (string.IsNullOrEmpty(_NO_TRANSLATE_Remotes.Text))
  48. {
  49. MessageBox.Show(owner, _selectRemote.Text);
  50. return false;
  51. }
  52. if (string.IsNullOrEmpty(change))
  53. {
  54. MessageBox.Show(owner, _selectChange.Text);
  55. return false;
  56. }
  57. StartAgent(owner, _NO_TRANSLATE_Remotes.Text);
  58. var reviewInfo = LoadReviewInfo();
  59. if (reviewInfo == null || reviewInfo["id"] == null)
  60. {
  61. MessageBox.Show(owner, _cannotGetChangeDetails.Text);
  62. return false;
  63. }
  64. string topic = _NO_TRANSLATE_TopicBranch.Text.Trim();
  65. if (string.IsNullOrEmpty(topic))
  66. {
  67. var topicNode = (JValue)reviewInfo["topic"];
  68. topic = topicNode == null ? change : (string)topicNode.Value;
  69. }
  70. string authorValue = (string)((JValue)reviewInfo["owner"]["name"]).Value;
  71. string author = Regex.Replace(authorValue.ToLowerInvariant(), "\\W+", "_");
  72. string branchName = "review/" + author + "/" + topic;
  73. string refspec = (string)((JValue)reviewInfo["currentPatchSet"]["ref"]).Value;
  74. var fetchCommand = _uiCommand.CreateRemoteCommand();
  75. fetchCommand.CommandText = FetchCommand(_NO_TRANSLATE_Remotes.Text, refspec);
  76. if (!RunCommand(fetchCommand, change))
  77. return false;
  78. var checkoutCommand = _uiCommand.CreateRemoteCommand();
  79. checkoutCommand.CommandText = GitCommandHelpers.BranchCmd(branchName, "FETCH_HEAD", true);
  80. checkoutCommand.Completed += (s, e) =>
  81. {
  82. if (e.IsError)
  83. {
  84. if (e.Command.CommandText.Contains("already exists"))
  85. {
  86. // Recycle the current review branch.
  87. var recycleCommand = _uiCommand.CreateRemoteCommand();
  88. recycleCommand.CommandText = "checkout " + branchName;
  89. if (!RunCommand(recycleCommand, change))
  90. return;
  91. var resetCommand = _uiCommand.CreateRemoteCommand();
  92. resetCommand.CommandText = GitCommandHelpers.ResetHardCmd("FETCH_HEAD");
  93. if (!RunCommand(resetCommand, change))
  94. return;
  95. e.IsError = false;
  96. }
  97. }
  98. };
  99. return RunCommand(checkoutCommand, change);
  100. }
  101. private bool RunCommand(IGitRemoteCommand command, string change)
  102. {
  103. command.OwnerForm = this;
  104. command.Title = string.Format(_downloadCaption.Text, change);
  105. command.Remote = _NO_TRANSLATE_Remotes.Text;
  106. command.Execute();
  107. return !command.ErrorOccurred;
  108. }
  109. private string FetchCommand(string remote, string remoteBranch)
  110. {
  111. var progressOption = "";
  112. if (GitCommandHelpers.VersionInUse.FetchCanAskForProgress)
  113. progressOption = "--progress ";
  114. remote = FixPath(remote);
  115. //Remove spaces...
  116. if (remoteBranch != null)
  117. remoteBranch = remoteBranch.Replace(" ", "");
  118. return "fetch " + progressOption + "\"" + remote.Trim() + "\" " + remoteBranch;
  119. }
  120. private static string FixPath(string path)
  121. {
  122. path = path.Trim();
  123. return path.Replace('\\', '/');
  124. }
  125. private JObject LoadReviewInfo()
  126. {
  127. string remotes = GitCommands.Settings.Module.RunGitCmd("remote show -n \"" + _currentBranchRemote + "\"");
  128. string fetchUrlLine = remotes.Split('\n').Select(p => p.Trim()).First(p => p.StartsWith("Push"));
  129. var fetchUrl = new Uri(fetchUrlLine.Split(new[] { ':' }, 2)[1].Trim());
  130. string projectName = fetchUrl.AbsolutePath.TrimStart('/');
  131. if (projectName.EndsWith(".git"))
  132. projectName = projectName.Substring(0, projectName.Length - 4);
  133. var sshCmd = GitCommandHelpers.GetSsh();
  134. if (GitCommandHelpers.Plink())
  135. {
  136. sshCmd = GitCommands.Settings.Plink;
  137. }
  138. if (string.IsNullOrEmpty(sshCmd))
  139. {
  140. sshCmd = "ssh.exe";
  141. }
  142. string hostname = fetchUrl.Host;
  143. string username = fetchUrl.UserInfo;
  144. string portFlag = GitCommandHelpers.Plink() ? " -P " : " -p ";
  145. int port = fetchUrl.Port;
  146. if (port == -1 && fetchUrl.Scheme == "ssh")
  147. port = 22;
  148. var sb = new StringBuilder();
  149. sb.Append('"');
  150. if (!string.IsNullOrEmpty(username))
  151. {
  152. sb.Append(username);
  153. sb.Append('@');
  154. }
  155. sb.Append(hostname);
  156. sb.Append('"');
  157. sb.Append(portFlag);
  158. sb.Append(port);
  159. sb.Append(" \"gerrit query --format=JSON project:");
  160. sb.Append(projectName);
  161. sb.Append(" --current-patch-set change:");
  162. sb.Append(_NO_TRANSLATE_Change.Text);
  163. sb.Append('"');
  164. string change = GitCommands.Settings.Module.RunCmd(
  165. sshCmd,
  166. sb.ToString()
  167. );
  168. foreach (string line in change.Split('\n'))
  169. {
  170. try
  171. {
  172. return JObject.Parse(line);
  173. }
  174. catch
  175. {
  176. // Ignore exceptions.
  177. }
  178. }
  179. return null;
  180. }
  181. private void FormGerritDownloadLoad(object sender, EventArgs e)
  182. {
  183. RestorePosition("download-gerrit-change");
  184. _NO_TRANSLATE_Remotes.DataSource = GitCommands.Settings.Module.GetRemotes();
  185. _currentBranchRemote = Settings.DefaultRemote;
  186. IList<string> remotes = (IList<string>)_NO_TRANSLATE_Remotes.DataSource;
  187. int i = remotes.IndexOf(_currentBranchRemote);
  188. _NO_TRANSLATE_Remotes.SelectedIndex = i >= 0 ? i : 0;
  189. _NO_TRANSLATE_Change.Select();
  190. Text = string.Concat(_downloadGerritChangeCaption.Text, " (", GitCommands.Settings.WorkingDir, ")");
  191. }
  192. private void AddRemoteClick(object sender, EventArgs e)
  193. {
  194. _uiCommand.StartRemotesDialog();
  195. _NO_TRANSLATE_Remotes.DataSource = GitCommands.Settings.Module.GetRemotes();
  196. }
  197. private void FormGerritDownload_FormClosing(object sender, FormClosingEventArgs e)
  198. {
  199. SavePosition("download-gerrit-change");
  200. }
  201. }
  202. }