PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/GitCommands/GitExtLinks/GitExtLinkDef.cs

https://github.com/vbjay/gitextensions
C# | 222 lines | 177 code | 26 blank | 19 comment | 14 complexity | f10b302e5af69bd6ddb3cf43e912f377 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Xml.Serialization;
  8. using GitCommands.Config;
  9. using GitCommands.Core;
  10. namespace GitCommands.GitExtLinks
  11. {
  12. public class GitExtLinkDef : SimpleStructured
  13. {
  14. //revision's parts that can be searched for candidates for a link
  15. public enum RevisionPart
  16. {
  17. Message,
  18. LocalBranches,
  19. RemoteBranches
  20. }
  21. /// <summary>Short name for this link def</summary>
  22. public string Name { get; set; }
  23. /// <summary></summary>
  24. public HashSet<RevisionPart> SearchInParts = new HashSet<RevisionPart>();
  25. private string _SearchPattern;
  26. /// <summary>
  27. /// RegEx for revision parts that have to be transformed into links
  28. /// empty string stands for unconditionally always added link
  29. /// </summary>
  30. public string SearchPattern
  31. {
  32. get
  33. {
  34. return _SearchPattern;
  35. }
  36. set
  37. {
  38. _SearchPattern = value;
  39. SearchPatternRegex = new Lazy<Regex>(() =>
  40. {
  41. try
  42. {
  43. return new Regex(SearchPattern, RegexOptions.Compiled);
  44. }
  45. catch(Exception e)
  46. {
  47. System.Diagnostics.Debug.Print(e.ToStringWithData());
  48. return null;
  49. }
  50. }
  51. );
  52. }
  53. }
  54. /// <summary>Compiled SearchPattern</summary>
  55. [XmlIgnore]
  56. public Lazy<Regex> SearchPatternRegex { get; private set; }
  57. private string _NestedSearchPattern;
  58. /// <summary>
  59. /// RegEx for revision parts that have to be transformed into links
  60. /// empty string stands for unconditionally always added link
  61. /// </summary>
  62. public string NestedSearchPattern
  63. {
  64. get
  65. {
  66. return _NestedSearchPattern;
  67. }
  68. set
  69. {
  70. _NestedSearchPattern = value;
  71. NestedSearchPatternRegex = new Lazy<Regex>(() =>
  72. {
  73. try
  74. {
  75. return new Regex(NestedSearchPattern, RegexOptions.Compiled);
  76. }
  77. catch (Exception e)
  78. {
  79. System.Diagnostics.Debug.Print(e.ToStringWithData());
  80. return null;
  81. }
  82. }
  83. );
  84. }
  85. }
  86. /// <summary>Compiled SearchPattern</summary>
  87. [XmlIgnore]
  88. public Lazy<Regex> NestedSearchPatternRegex { get; private set; }
  89. /// <summary>
  90. /// Non-local link def can be locally disabled
  91. /// </summary>
  92. public bool Enabled { get; set; }
  93. /// <summary>
  94. /// List of formats to be applied for each revision part matched by SearchPattern
  95. /// </summary>
  96. public BindingList<GitExtLinkFormat> LinkFormats = new BindingList<GitExtLinkFormat>();
  97. public GitExtLinkDef()
  98. {
  99. }
  100. public IEnumerable<GitExtLink> Parse(GitRevision revision)
  101. {
  102. List<IEnumerable<GitExtLink>> links = new List<IEnumerable<GitExtLink>>();
  103. if (SearchInParts.Contains(RevisionPart.LocalBranches))
  104. foreach (var head in revision.Refs.Where(b => !b.IsRemote))
  105. links.Add(ParsePart(head.LocalName, revision));
  106. if (SearchInParts.Contains(RevisionPart.RemoteBranches))
  107. foreach (var head in revision.Refs.Where(b => b.IsRemote))
  108. links.Add(ParsePart(head.LocalName, revision));
  109. if (SearchInParts.Contains(RevisionPart.Message))
  110. links.Add(ParsePart(revision.Body, revision));
  111. return links.Unwrap();
  112. }
  113. public IEnumerable<GitExtLink> ParsePart(string part, GitRevision revision)
  114. {
  115. if (SearchPattern.IsNullOrEmpty() || SearchPatternRegex.Value == null)
  116. yield break;
  117. IList<Match> allMatches = new List<Match>();
  118. MatchCollection matches = SearchPatternRegex.Value.Matches(part);
  119. for (var i = 0; i < matches.Count; i++)
  120. {
  121. var match = matches[i];
  122. if (NestedSearchPattern.IsNullOrEmpty())
  123. {
  124. allMatches.Add(match);
  125. }
  126. else if (NestedSearchPatternRegex.Value != null)
  127. {
  128. MatchCollection nestedMatches = NestedSearchPatternRegex.Value.Matches(match.Value);
  129. for (var n = 0; n < nestedMatches.Count; n++)
  130. {
  131. allMatches.Add(nestedMatches[n]);
  132. }
  133. }
  134. }
  135. foreach (var match in allMatches.Where(m => m.Success))
  136. {
  137. foreach (var format in LinkFormats)
  138. {
  139. yield return format.ToGitExtLink(match, revision);
  140. }
  141. }
  142. }
  143. protected internal override IEnumerable<object> InlinedStructure()
  144. {
  145. yield return Name;
  146. yield return SearchPattern;
  147. yield return SearchInParts;
  148. yield return NestedSearchPattern;
  149. yield return Enabled;
  150. yield return LinkFormats;
  151. }
  152. public override int GetHashCode()
  153. {
  154. return Name.GetHashCode();
  155. }
  156. public void RemoveEmptyFormats()
  157. {
  158. var toRemove = LinkFormats.Where(f => f.Caption.IsNullOrWhiteSpace() && f.Format.IsNullOrWhiteSpace()).ToArray();
  159. toRemove.ForEach(f => LinkFormats.Remove(f));
  160. }
  161. }
  162. public class GitExtLinkFormat : SimpleStructured
  163. {
  164. public string Caption { get; set; }
  165. public string Format { get; set; }
  166. [XmlIgnore]
  167. public bool IsValid { get; private set; }
  168. public GitExtLink ToGitExtLink(Match match, GitRevision revision)
  169. {
  170. GitExtLink link = new GitExtLink();
  171. try
  172. {
  173. var groups = new List<string>();
  174. for (int i = match.Groups.Count > 1 ? 1 : 0; i < match.Groups.Count; i++)
  175. {
  176. groups.Add(match.Groups[i].Value);
  177. }
  178. link.Caption = string.Format(Caption, groups.ToArray());
  179. link.URI = Format.Replace("%COMMIT_HASH%", revision.Guid);
  180. link.URI = string.Format(link.URI, groups.ToArray());
  181. IsValid = true;
  182. }
  183. catch (Exception e)
  184. {
  185. link.URI = e.Message + ": " + Format + " " + match.Value;
  186. IsValid = false;
  187. }
  188. return link;
  189. }
  190. protected internal override IEnumerable<object> InlinedStructure()
  191. {
  192. yield return Caption;
  193. yield return Format;
  194. }
  195. }
  196. }