PageRenderTime 118ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Plugins/BuildServerIntegration/TfsIntegration/TfsAdapter.cs

https://github.com/vbjay/gitextensions
C# | 173 lines | 147 code | 22 blank | 4 comment | 16 complexity | 41791c3cd21c670e62f2c7a724be4032 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. using System;
  2. using System.ComponentModel.Composition;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Reactive;
  6. using System.Reactive.Concurrency;
  7. using System.Reactive.Linq;
  8. using System.Reflection;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using GitCommands.Settings;
  12. using GitCommands.Utils;
  13. using GitUIPluginInterfaces;
  14. using GitUIPluginInterfaces.BuildServerIntegration;
  15. using TfsInterop.Interface;
  16. namespace TfsIntegration
  17. {
  18. [MetadataAttribute]
  19. [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
  20. public class TfsIntegrationMetadata : BuildServerAdapterMetadataAttribute
  21. {
  22. public TfsIntegrationMetadata(string buildServerType)
  23. : base(buildServerType)
  24. {
  25. }
  26. public override string CanBeLoaded
  27. {
  28. get
  29. {
  30. if (EnvUtils.IsNet4FullOrHigher())
  31. return null;
  32. return ".Net 4 full freamwork required";
  33. }
  34. }
  35. }
  36. [Export(typeof(IBuildServerAdapter))]
  37. [TfsIntegrationMetadata("Team Foundation Server")]
  38. [PartCreationPolicy(CreationPolicy.NonShared)]
  39. internal class TfsAdapter : IBuildServerAdapter
  40. {
  41. private IBuildServerWatcher _buildServerWatcher;
  42. private ITfsHelper _tfsHelper;
  43. string _tfsServer;
  44. string _tfsTeamCollectionName;
  45. string _projectName;
  46. string _tfsBuildDefinitionName;
  47. public void Initialize(IBuildServerWatcher buildServerWatcher, ISettingsSource config)
  48. {
  49. if (_buildServerWatcher != null)
  50. throw new InvalidOperationException("Already initialized");
  51. _buildServerWatcher = buildServerWatcher;
  52. _tfsServer = config.GetString("TfsServer", null);
  53. _tfsTeamCollectionName = config.GetString("TfsTeamCollectionName", null);
  54. _projectName = config.GetString("ProjectName", null);
  55. _tfsBuildDefinitionName = config.GetString("TfsBuildDefinitionName", null);
  56. if (!string.IsNullOrEmpty(_tfsServer)
  57. && !string.IsNullOrEmpty(_tfsTeamCollectionName)
  58. && !string.IsNullOrEmpty(_projectName))
  59. {
  60. _tfsHelper = LoadAssemblyAndConnectToServer("TfsInterop.Vs2013")
  61. ?? LoadAssemblyAndConnectToServer("TfsInterop.Vs2012");
  62. if (_tfsHelper == null)
  63. {
  64. Trace.WriteLine("fail to load the good interop assembly :(");
  65. }
  66. }
  67. }
  68. private ITfsHelper LoadAssemblyAndConnectToServer(string assembly)
  69. {
  70. try
  71. {
  72. Trace.WriteLine("Try loading " + assembly + ".dll ...");
  73. var loadedAssembly = Assembly.Load(assembly);
  74. var tfsHelper = loadedAssembly.CreateInstance("TfsInterop.TfsHelper") as ITfsHelper;
  75. Trace.WriteLine("Create instance... OK");
  76. if (tfsHelper != null && tfsHelper.IsDependencyOk())
  77. {
  78. tfsHelper.ConnectToTfsServer(_tfsServer, _tfsTeamCollectionName, _projectName, _tfsBuildDefinitionName);
  79. Trace.WriteLine("Connection... OK");
  80. return tfsHelper;
  81. }
  82. }
  83. catch (Exception ex)
  84. {
  85. Trace.WriteLine(ex.Message);
  86. }
  87. return null;
  88. }
  89. /// <summary>
  90. /// Gets a unique key which identifies this build server.
  91. /// </summary>
  92. public string UniqueKey
  93. {
  94. get { return _tfsServer + "/" + _tfsTeamCollectionName + "/" + _projectName; }
  95. }
  96. public IObservable<BuildInfo> GetFinishedBuildsSince(IScheduler scheduler, DateTime? sinceDate = null)
  97. {
  98. return GetBuilds(scheduler, sinceDate, false);
  99. }
  100. public IObservable<BuildInfo> GetRunningBuilds(IScheduler scheduler)
  101. {
  102. return GetBuilds(scheduler, null, true);
  103. }
  104. public IObservable<BuildInfo> GetBuilds(IScheduler scheduler, DateTime? sinceDate = null, bool? running = null)
  105. {
  106. if (_tfsHelper == null)
  107. return Observable.Empty<BuildInfo>();
  108. return Observable.Create<BuildInfo>((observer, cancellationToken) =>
  109. Task<IDisposable>.Factory.StartNew(
  110. () => scheduler.Schedule(() => ObserveBuilds(sinceDate, running, observer, cancellationToken))));
  111. }
  112. private void ObserveBuilds(DateTime? sinceDate, bool? running, IObserver<BuildInfo> observer, CancellationToken cancellationToken)
  113. {
  114. try
  115. {
  116. var builds = _tfsHelper.QueryBuilds().AsQueryable();
  117. if (sinceDate.HasValue)
  118. builds = builds.Where(b => b.StartDate > sinceDate.Value);
  119. if (running.HasValue)
  120. builds = builds.Where(b => b.IsFinished != running.Value);
  121. Parallel.ForEach(builds, detail => { observer.OnNext(CreateBuildInfo(detail)); });
  122. }
  123. catch (OperationCanceledException)
  124. {
  125. // Do nothing, the observer is already stopped
  126. }
  127. catch (Exception ex)
  128. {
  129. observer.OnError(ex);
  130. }
  131. }
  132. private static BuildInfo CreateBuildInfo(IBuild buildDetail)
  133. {
  134. string sha = buildDetail.Revision.Substring(buildDetail.Revision.LastIndexOf(":") + 1);
  135. var buildInfo = new BuildInfo
  136. {
  137. Id = buildDetail.Label,
  138. StartDate = buildDetail.StartDate,
  139. Status = (BuildInfo.BuildStatus)buildDetail.Status,
  140. Description = buildDetail.Label + " (" + buildDetail.Description + ")",
  141. CommitHashList = new[] { sha },
  142. Url = buildDetail.Url
  143. };
  144. return buildInfo;
  145. }
  146. public void Dispose()
  147. {
  148. GC.SuppressFinalize(this);
  149. }
  150. }
  151. }