PageRenderTime 31ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/NugetPublisher.Desktop.UI/Form1.cs

https://gitlab.com/developer9/nuget-publisher
C# | 276 lines | 211 code | 63 blank | 2 comment | 30 complexity | e7d489b458ad5d561eb9cf99c31a8550 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Net;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. namespace NugetPublisher.Desktop.UI
  11. {
  12. public partial class Form1 : Form
  13. {
  14. private string[] _fileNames;
  15. private readonly string _nugetPath;
  16. private readonly string _nugetPackagesPath;
  17. private readonly Regex _assemblyNameRegex;
  18. private readonly Regex _nuspecSanityRegex;
  19. private readonly Regex _assemblyVersionRegex;
  20. public Form1()
  21. {
  22. InitializeComponent();
  23. _nugetPath = string.Format(@"{0}Nuget\nuget.exe", Path.GetPathRoot(Environment.SystemDirectory));
  24. _nugetPackagesPath = string.Format(@"{0}Nuget\Packages", Path.GetPathRoot(Environment.SystemDirectory));
  25. StatusLabel.Text = @"Idle";
  26. _assemblyNameRegex = new Regex(@"^(?:[a-z]:(?:\\\w+?\.?\w+)+)?\\(?:((?:\w+\.?)+)\.dll)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
  27. _nuspecSanityRegex = new Regex(@"\s*(?:<\w+>https?:\/\/\w+\<\/\w+>|<tags>.*<\/tags>|.*<\/?dependenc.*>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
  28. _assemblyVersionRegex = new Regex(@"(?:<version>([\d\.]+)<\/version>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
  29. }
  30. private void textBox1_TextChanged(object sender, EventArgs e)
  31. {
  32. PushToServerButton.Enabled = Regex.IsMatch(ServerUrlTextBox.Text, @"https?://\w+\:?\d{0,5}\/?.*");
  33. }
  34. private void SelectArtifactsButton_Click(object sender, EventArgs e)
  35. {
  36. var dialog = new OpenFileDialog
  37. {
  38. Multiselect = true,
  39. DefaultExt = ".dll",
  40. AddExtension = true,
  41. Filter = @".NET Assemblies (*.dll) | *.dll"
  42. };
  43. var result = dialog.ShowDialog();
  44. if (!Directory.Exists(_nugetPackagesPath + @"\lib"))
  45. {
  46. Directory.CreateDirectory(_nugetPackagesPath + @"\lib");
  47. }
  48. _fileNames = new string[dialog.FileNames.Length];
  49. if (result == DialogResult.OK)
  50. {
  51. ArtifactsListView.Items.Clear();
  52. for (int idx = 0; idx < dialog.SafeFileNames.Length; ++idx)
  53. {
  54. var fileName = dialog.SafeFileNames[idx];
  55. _fileNames[idx] = string.Format(@"{0}\lib\{1}", _nugetPackagesPath, fileName);
  56. if (dialog.FileNames[idx] != _fileNames[idx]) // avoids circular copying
  57. {
  58. File.Copy(dialog.FileNames[idx], _fileNames[idx], true);
  59. }
  60. ArtifactsListView.Items.Add(fileName);
  61. }
  62. //CreateNuspecButton.Enabled = true;
  63. CreatePackageButton.Enabled = true;
  64. }
  65. }
  66. private async void CreatePackageButton_Click(object sender, EventArgs e)
  67. {
  68. var controlManager = new FormControlManager(this);
  69. await controlManager.ToggleControlsOfType<Button>(async () =>
  70. {
  71. StatusLabel.Text = @"Generating packages...";
  72. if (!await RunNuget(@"spec -a ""lib\{0}.dll"" -force{1}", _fileNames))
  73. {
  74. StatusLabel.Text = @"Error generating NuSpec file(s)";
  75. return;
  76. }
  77. var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
  78. Parallel.ForEach(_fileNames, options, async fileName =>
  79. {
  80. var match = _assemblyNameRegex.Match(fileName);
  81. if (!match.Success) return;
  82. var nuspecFile = string.Format(@"{0}\{1}.nuspec", _nugetPackagesPath, match.Groups[1].Value);
  83. if (!File.Exists(nuspecFile)) return;
  84. var fileText = File.ReadAllText(nuspecFile);
  85. if (!string.IsNullOrEmpty(fileText))
  86. {
  87. using (var writer = File.CreateText(nuspecFile))
  88. {
  89. var sanitizedNuspecMarkup = _nuspecSanityRegex.Replace(fileText, string.Empty);
  90. await writer.WriteAsync(sanitizedNuspecMarkup);
  91. }
  92. }
  93. });
  94. if (await RunNuget(@"pack ""{0}.nuspec""{1}", _fileNames))
  95. {
  96. StatusLabel.Text = @"Package(s) generated successfully.";
  97. return;
  98. }
  99. StatusLabel.Text = @"Unable to generate all packages. Check folder write permissions.";
  100. },
  101. new HashSet<Button> { CreateNuspecButton });
  102. }
  103. private async void CreateNuspecButton_Click(object sender, EventArgs e)
  104. {
  105. StatusLabel.Text = @"Generating spec files...";
  106. if (await RunNuget(@"spec -a ""lib\{0}.dll"" -force{1}", _fileNames))
  107. {
  108. StatusLabel.Text = @"NuSpec file(s) generated successfully.";
  109. return;
  110. }
  111. StatusLabel.Text = @"Unable to generate all nuspec file(s). Check folder write permissions.";
  112. }
  113. private async void PushToServerButton_Click(object sender, EventArgs e)
  114. {
  115. var controlManager = new FormControlManager(this);
  116. await controlManager.ToggleControlsOfType<Button>(async () =>
  117. {
  118. StatusLabel.Text = @"Publishing packages to " + ServerUrlTextBox.Text + @"...";
  119. if (ArtifactsListView.Items.Count == 0)
  120. {
  121. StatusLabel.Text = @"Please select your artifacts first";
  122. return;
  123. }
  124. if (string.IsNullOrEmpty(ApiKeyTextBox.Text))
  125. {
  126. StatusLabel.Text = @"Please specify an API key";
  127. return;
  128. }
  129. if (await RunNuget(@"push ""{0}.nupkg"" -Source " + ServerUrlTextBox.Text + " -ApiKey " + ApiKeyTextBox.Text + " -DisableBuffering" + "{1}", _fileNames, true))
  130. {
  131. StatusLabel.Text = @"Packages successfully published.";
  132. return;
  133. }
  134. StatusLabel.Text = @"Unable to publish all packages. Check your Internet Connection, Nuget URL and ApiKey.";
  135. },
  136. new HashSet<Button> { CreateNuspecButton });
  137. }
  138. private async Task<bool> RunNuget(string argumentFormat, string[] fileNames, bool detectAssemblyVersion = false)
  139. {
  140. Task downloadTask = DownloadNugetIfNotExist();
  141. return await downloadTask.ContinueWith((antecedent) =>
  142. {
  143. argumentFormat = string.Format("{0} {1}", _nugetPath, argumentFormat);
  144. var commands = new StringBuilder();
  145. var length = fileNames.Length;
  146. for (var idx = 0; idx < length; ++idx)
  147. {
  148. if (File.ReadAllBytes(fileNames[idx]).Length == 0) continue;
  149. var match = _assemblyNameRegex.Match(fileNames[idx]);
  150. if (!match.Success) continue;
  151. var packageName = match.Groups[1].Value;
  152. var nuspecPath = string.Format(@"{0}\{1}.nuspec", _nugetPackagesPath, packageName);
  153. if (detectAssemblyVersion && File.Exists(nuspecPath)) // when pushing to my nuget server
  154. {
  155. match = _assemblyVersionRegex.Match(File.ReadAllText(nuspecPath));
  156. if (!match.Success) continue;
  157. var version = match.Groups[1].Value;
  158. if (version.EndsWith(".0.0.0"))
  159. {
  160. version = version.Substring(0, version.Length - 2);
  161. }
  162. packageName = string.Format(@"{0}.{1}", packageName, version);
  163. }
  164. commands.Append(string.Format(argumentFormat, packageName, length > 1 && idx < length - 1 ? " & " : string.Empty));
  165. }
  166. var successCount = 0;
  167. using (var process = new Process())
  168. {
  169. var startInfo = new ProcessStartInfo
  170. {
  171. UseShellExecute = false,
  172. WindowStyle = ProcessWindowStyle.Hidden,
  173. FileName = "cmd.exe",
  174. Arguments =
  175. "/c cd " + _nugetPackagesPath + " & " + commands +
  176. (detectAssemblyVersion ? " & del /f /a:- *.nuspec && del /f /a:- *.nupkg" : string.Empty),
  177. RedirectStandardOutput = true,
  178. CreateNoWindow = true,
  179. };
  180. process.StartInfo = startInfo;
  181. process.Start();
  182. while (!process.StandardOutput.EndOfStream)
  183. {
  184. string result = (process.StandardOutput.ReadLine() ?? string.Empty).ToLower();
  185. if (result.Contains("success") || result.Contains("package was pushed"))
  186. {
  187. ++successCount;
  188. }
  189. }
  190. }
  191. return successCount == _fileNames.Length;
  192. });
  193. }
  194. private async Task DownloadNugetIfNotExist()
  195. {
  196. if (File.Exists(_nugetPath)) return;
  197. StatusLabel.Text = @"Downloading nuget...";
  198. //var address = @"https://dist.nuget.org/win-x86-commandline/v3.4.4/NuGet.exe";
  199. var address = @"https://dist.nuget.org/win-x86-commandline/v3.5.0-rc1/NuGet.exe";
  200. try
  201. {
  202. using (var client = new WebClient())
  203. {
  204. await client.DownloadFileTaskAsync(address, _nugetPath);
  205. }
  206. }
  207. catch (Exception exception)
  208. {
  209. StatusLabel.Text = @"Fatal: " + exception.Message;
  210. }
  211. }
  212. }
  213. }