PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Mercurial.Net/CloneCommand.cs

#
C# | 431 lines | 188 code | 34 blank | 209 comment | 3 complexity | 1f4825631084a1c01068d30788a38ba1 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using Mercurial.Attributes;
  7. namespace Mercurial
  8. {
  9. /// <summary>
  10. /// This class implements the "hg clone" command (<see href="http://www.selenic.com/mercurial/hg.1.html#clone"/>):
  11. /// make a copy of an existing repository.
  12. /// </summary>
  13. public sealed class CloneCommand : MercurialCommandBase<CloneCommand>
  14. {
  15. /// <summary>
  16. /// This is the backing field for the <see cref="Branches"/> property.
  17. /// </summary>
  18. private readonly List<string> _Branches = new List<string>();
  19. /// <summary>
  20. /// This is the backing field for the <see cref="Revisions"/> property.
  21. /// </summary>
  22. private readonly List<RevSpec> _Revisions = new List<RevSpec>();
  23. /// <summary>
  24. /// This is the backing field for the <see cref="Source"/> property.
  25. /// </summary>
  26. private string _Source = string.Empty;
  27. /// <summary>
  28. /// This is the backing field for the <see cref="SshCommand"/> property.
  29. /// </summary>
  30. private string _SshCommand = string.Empty;
  31. /// <summary>
  32. /// This is the backing field for the <see cref="RemoteCommand"/> property.
  33. /// </summary>
  34. private string _RemoteCommand = string.Empty;
  35. /// <summary>
  36. /// This is the backing field for the <see cref="VerifyServerCertificate"/> property.
  37. /// </summary>
  38. private bool _VerifyServerCertificate = true;
  39. /// <summary>
  40. /// Initializes a new instance of the <see cref="CloneCommand"/> class.
  41. /// </summary>
  42. public CloneCommand()
  43. : base("clone")
  44. {
  45. Update = true;
  46. CompressedTransfer = true;
  47. }
  48. /// <summary>
  49. /// Gets or sets the source path or Uri to clone from.
  50. /// </summary>
  51. [DefaultValue("")]
  52. public string Source
  53. {
  54. get
  55. {
  56. return _Source;
  57. }
  58. set
  59. {
  60. _Source = (value ?? string.Empty).Trim();
  61. }
  62. }
  63. /// <summary>
  64. /// Gets or sets a value indicating whether to update the clone with a working folder.
  65. /// Default is <c>true</c>.
  66. /// </summary>
  67. [BooleanArgument(FalseOption = "--noupdate")]
  68. [DefaultValue(true)]
  69. public bool Update
  70. {
  71. get;
  72. set;
  73. }
  74. /// <summary>
  75. /// Gets or sets a value indicating whether to verify the server certificate. If set to <c>false</c>, will ignore web.cacerts configuration.
  76. /// Default value is <c>true</c>.
  77. /// </summary>
  78. [BooleanArgument(FalseOption = "--insecure")]
  79. [DefaultValue(true)]
  80. public bool VerifyServerCertificate
  81. {
  82. get
  83. {
  84. return _VerifyServerCertificate;
  85. }
  86. set
  87. {
  88. RequiresVersion(new Version(1, 7, 5), "VerifyServerCertificate property of the CloneCommand class");
  89. _VerifyServerCertificate = value;
  90. }
  91. }
  92. /// <summary>
  93. /// Sets the <see cref="VerifyServerCertificate"/> property to the specified value and
  94. /// returns this <see cref="CloneCommand"/> instance.
  95. /// </summary>
  96. /// <param name="value">
  97. /// The new value for the <see cref="VerifyServerCertificate"/> property.
  98. /// </param>
  99. /// <returns>
  100. /// This <see cref="CloneCommand"/> instance.
  101. /// </returns>
  102. /// <remarks>
  103. /// This method is part of the fluent interface.
  104. /// </remarks>
  105. public CloneCommand WithVerifyServerCertificate(bool value)
  106. {
  107. VerifyServerCertificate = value;
  108. return this;
  109. }
  110. /// <summary>
  111. /// Gets or sets the <see cref="Revisions"/> to update the working
  112. /// folder to, or <c>null</c> to update to the tip. Default is <c>null</c>.
  113. /// </summary>
  114. [NullableArgument(NonNullOption = "--updaterev")]
  115. [DefaultValue(null)]
  116. public RevSpec UpdateToRevision
  117. {
  118. get;
  119. set;
  120. }
  121. /// <summary>
  122. /// Gets or sets a value indicating whether to use compressed transfer or not. Over LAN, uncompressed is faster, otherwise
  123. /// compressed is most likely faster. Default is <c>true</c>.
  124. /// </summary>
  125. [BooleanArgument(FalseOption = "--uncompressed")]
  126. [DefaultValue(true)]
  127. public bool CompressedTransfer
  128. {
  129. get;
  130. set;
  131. }
  132. /// <summary>
  133. /// Gets the collection of revisions to include in the clone. If empty, include every changeset
  134. /// from the source repository. Default is empty.
  135. /// </summary>
  136. [RepeatableArgument(Option = "--rev")]
  137. public Collection<RevSpec> Revisions
  138. {
  139. get
  140. {
  141. return new Collection<RevSpec>(_Revisions);
  142. }
  143. }
  144. /// <summary>
  145. /// Gets the collection of branches to include in the clone. If empty, include every branch
  146. /// from the source repository. Default is empty.
  147. /// </summary>
  148. [RepeatableArgument(Option = "--branch")]
  149. public Collection<string> Branches
  150. {
  151. get
  152. {
  153. return new Collection<string>(_Branches);
  154. }
  155. }
  156. /// <summary>
  157. /// Gets or sets a value indicating whether to use pull protocol to copy metadata.
  158. /// Default value is <c>false</c>.
  159. /// </summary>
  160. [DefaultValue(false)]
  161. public bool UsePull
  162. {
  163. get;
  164. set;
  165. }
  166. /// <summary>
  167. /// Sets the <see cref="UsePull"/> property to the specified value and
  168. /// returns this <see cref="CloneCommand"/> instance.
  169. /// </summary>
  170. /// <param name="value">
  171. /// The new value for the <see cref="UsePull"/> property.
  172. /// </param>
  173. /// <returns>
  174. /// This <see cref="CloneCommand"/> instance.
  175. /// </returns>
  176. /// <remarks>
  177. /// This method is part of the fluent interface.
  178. /// </remarks>
  179. public CloneCommand WithUsePull(bool value)
  180. {
  181. UsePull = value;
  182. return this;
  183. }
  184. /// <summary>
  185. /// Gets or sets the ssh command to use when cloning.
  186. /// Default is <see cref="string.Empty"/>.
  187. /// </summary>
  188. [NullableArgument(NonNullOption = "--ssh")]
  189. [DefaultValue("")]
  190. public string SshCommand
  191. {
  192. get
  193. {
  194. return _SshCommand;
  195. }
  196. set
  197. {
  198. _SshCommand = (value ?? string.Empty).Trim();
  199. }
  200. }
  201. /// <summary>
  202. /// Gets or sets the hg command to run on the remote side.
  203. /// Default is <see cref="string.Empty"/>.
  204. /// </summary>
  205. [NullableArgument(NonNullOption = "--remotecmd")]
  206. [DefaultValue("")]
  207. public string RemoteCommand
  208. {
  209. get
  210. {
  211. return _RemoteCommand;
  212. }
  213. set
  214. {
  215. _RemoteCommand = (value ?? string.Empty).Trim();
  216. }
  217. }
  218. /// <summary>
  219. /// Gets all the arguments to the <see cref="CommandBase{T}.Command"/>, or an
  220. /// empty array if there are none.
  221. /// </summary>
  222. /// <value></value>
  223. public override IEnumerable<string> Arguments
  224. {
  225. get
  226. {
  227. return base.Arguments.Concat(
  228. new[]
  229. {
  230. "\"" + Source + "\"", ".",
  231. });
  232. }
  233. }
  234. /// <summary>
  235. /// Sets the <see cref="Source"/> property to the specified value and
  236. /// returns this <see cref="CloneCommand"/> instance.
  237. /// </summary>
  238. /// <param name="value">
  239. /// The new value for the <see cref="Source"/> property.
  240. /// </param>
  241. /// <returns>
  242. /// This <see cref="CloneCommand"/> instance.
  243. /// </returns>
  244. /// <remarks>
  245. /// This method is part of the fluent interface.
  246. /// </remarks>
  247. public CloneCommand WithSource(string value)
  248. {
  249. Source = value;
  250. return this;
  251. }
  252. /// <summary>
  253. /// Sets the <see cref="SshCommand"/> property to the specified value and
  254. /// returns this <see cref="CloneCommand"/> instance.
  255. /// </summary>
  256. /// <param name="value">
  257. /// The new value for the <see cref="SshCommand"/> property.
  258. /// </param>
  259. /// <returns>
  260. /// This <see cref="CloneCommand"/> instance.
  261. /// </returns>
  262. /// <remarks>
  263. /// This method is part of the fluent interface.
  264. /// </remarks>
  265. public CloneCommand WithSshCommand(string value)
  266. {
  267. SshCommand = value;
  268. return this;
  269. }
  270. /// <summary>
  271. /// Sets the <see cref="RemoteCommand"/> property to the specified value and
  272. /// returns this <see cref="CloneCommand"/> instance.
  273. /// </summary>
  274. /// <param name="value">
  275. /// The new value for the <see cref="RemoteCommand"/> property.
  276. /// </param>
  277. /// <returns>
  278. /// This <see cref="CloneCommand"/> instance.
  279. /// </returns>
  280. /// <remarks>
  281. /// This method is part of the fluent interface.
  282. /// </remarks>
  283. public CloneCommand WithRemoteCommand(string value)
  284. {
  285. RemoteCommand = value;
  286. return this;
  287. }
  288. /// <summary>
  289. /// Sets the <see cref="Update"/> property to the specified value and
  290. /// returns this <see cref="CloneCommand"/> instance.
  291. /// </summary>
  292. /// <param name="value">
  293. /// The new value for the <see cref="Update"/> property.
  294. /// </param>
  295. /// <returns>
  296. /// This <see cref="CloneCommand"/> instance.
  297. /// </returns>
  298. /// <remarks>
  299. /// This method is part of the fluent interface.
  300. /// </remarks>
  301. public CloneCommand WithUpdate(bool value)
  302. {
  303. Update = value;
  304. return this;
  305. }
  306. /// <summary>
  307. /// Sets the <see cref="UpdateToRevision"/> property to the specified value and
  308. /// returns this <see cref="CloneCommand"/> instance.
  309. /// </summary>
  310. /// <param name="value">
  311. /// The new value for the <see cref="UpdateToRevision"/> property.
  312. /// </param>
  313. /// <returns>
  314. /// This <see cref="CloneCommand"/> instance.
  315. /// </returns>
  316. /// <remarks>
  317. /// This method is part of the fluent interface.
  318. /// </remarks>
  319. public CloneCommand WithUpdateToRevision(RevSpec value)
  320. {
  321. UpdateToRevision = value;
  322. return this;
  323. }
  324. /// <summary>
  325. /// Sets the <see cref="CompressedTransfer"/> property to the specified value and
  326. /// returns this <see cref="CloneCommand"/> instance.
  327. /// </summary>
  328. /// <param name="value">
  329. /// The new value for the <see cref="CompressedTransfer"/> property.
  330. /// </param>
  331. /// <returns>
  332. /// This <see cref="CloneCommand"/> instance.
  333. /// </returns>
  334. /// <remarks>
  335. /// This method is part of the fluent interface.
  336. /// </remarks>
  337. public CloneCommand WithCompressedTransfer(bool value)
  338. {
  339. CompressedTransfer = value;
  340. return this;
  341. }
  342. /// <summary>
  343. /// Adds the value to the <see cref="Revisions"/> collection property and
  344. /// returns this <see cref="CloneCommand"/> instance.
  345. /// </summary>
  346. /// <param name="value">
  347. /// The value to add to the <see cref="Revisions"/> collection property.
  348. /// </param>
  349. /// <returns>
  350. /// This <see cref="CloneCommand"/> instance.
  351. /// </returns>
  352. /// <remarks>
  353. /// This method is part of the fluent interface.
  354. /// </remarks>
  355. public CloneCommand WithRevision(RevSpec value)
  356. {
  357. Revisions.Add(value);
  358. return this;
  359. }
  360. /// <summary>
  361. /// Adds the value to the <see cref="Branches"/> collection property and
  362. /// returns this <see cref="CloneCommand"/> instance.
  363. /// </summary>
  364. /// <param name="value">
  365. /// The value to add to the <see cref="Branches"/> collection property.
  366. /// </param>
  367. /// <returns>
  368. /// This <see cref="CloneCommand"/> instance.
  369. /// </returns>
  370. /// <remarks>
  371. /// This method is part of the fluent interface.
  372. /// </remarks>
  373. public CloneCommand WithBranch(string value)
  374. {
  375. Branches.Add(value);
  376. return this;
  377. }
  378. /// <summary>
  379. /// Validates the command configuration. This method should throw the necessary
  380. /// exceptions to signal missing or incorrect configuration (like attempting to
  381. /// add files to the repository without specifying which files to add.)
  382. /// </summary>
  383. /// <exception cref="InvalidOperationException">
  384. /// <para>The 'clone' command requires <see cref="Source"/> to be specified.</para>
  385. /// <para>- or -</para>
  386. /// <para>The <see cref="VerifyServerCertificate"/> command was used with Mercurial 1.7.4 or older.</para>
  387. /// </exception>
  388. public override void Validate()
  389. {
  390. base.Validate();
  391. if (!VerifyServerCertificate && ClientExecutable.CurrentVersion < new Version(1, 7, 5))
  392. throw new InvalidOperationException("The 'VerifyServerCertificate' property is only available in Mercurial 1.7.5 and newer");
  393. if (StringEx.IsNullOrWhiteSpace(Source))
  394. throw new InvalidOperationException("The 'clone' command requires Source to be specified");
  395. }
  396. }
  397. }