ProjectNode.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. #region BSD License
  2. /*
  3. Copyright (c) 2004-2005 Matthew Holmes ([email protected]), Dan Moorehead ([email protected])
  4. Redistribution and use in source and binary forms, with or without modification, are permitted
  5. provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright notice, this list of conditions
  7. and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
  9. and the following disclaimer in the documentation and/or other materials provided with the
  10. distribution.
  11. * The name of the author may not be used to endorse or promote products derived from this software
  12. without specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  14. BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  15. ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  16. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  17. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  18. OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  19. IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20. */
  21. #endregion
  22. using System;
  23. using System.Collections.Generic;
  24. using System.IO;
  25. using System.Xml;
  26. using Prebuild.Core.Attributes;
  27. using Prebuild.Core.Interfaces;
  28. using Prebuild.Core.Utilities;
  29. namespace Prebuild.Core.Nodes
  30. {
  31. /// <summary>
  32. /// A set of values that the Project's type can be
  33. /// </summary>
  34. public enum ProjectType
  35. {
  36. /// <summary>
  37. /// The project is a console executable
  38. /// </summary>
  39. Exe,
  40. /// <summary>
  41. /// The project is a windows executable
  42. /// </summary>
  43. WinExe,
  44. /// <summary>
  45. /// The project is a library
  46. /// </summary>
  47. Library,
  48. /// <summary>
  49. /// The project is a website
  50. /// </summary>
  51. Web,
  52. }
  53. /// <summary>
  54. ///
  55. /// </summary>
  56. public enum ClrRuntime
  57. {
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. Microsoft,
  62. /// <summary>
  63. ///
  64. /// </summary>
  65. Mono
  66. }
  67. /// <summary>
  68. /// The version of the .NET framework to use (Required for VS2008)
  69. /// <remarks>We don't need .NET 1.1 in here, it'll default when using vs2003.</remarks>
  70. /// </summary>
  71. public enum FrameworkVersion
  72. {
  73. /// <summary>
  74. /// .NET 2.0
  75. /// </summary>
  76. v2_0,
  77. /// <summary>
  78. /// .NET 3.0
  79. /// </summary>
  80. v3_0,
  81. /// <summary>
  82. /// .NET 3.5
  83. /// </summary>
  84. v3_5,
  85. /// <summary>
  86. /// .NET 4.0
  87. /// </summary>
  88. v4_0,
  89. /// <summary>
  90. /// .NET 4.5
  91. /// </summary>
  92. v4_5,
  93. /// <summary>
  94. /// .NET 4.5.1
  95. /// </summary>
  96. v4_5_1,
  97. v4_5_2,
  98. /// <summary>
  99. /// .NET 4.6
  100. /// </summary>
  101. v4_6,
  102. /// <summary>
  103. /// .NET 4.6.1
  104. /// </summary>
  105. v4_6_1,
  106. v4_6_2,
  107. v4_7,
  108. v4_7_1,
  109. v4_7_2,
  110. v4_8
  111. }
  112. /// <summary>
  113. /// The Node object representing /Prebuild/Solution/Project elements
  114. /// </summary>
  115. [DataNode("Project")]
  116. public class ProjectNode : DataNode, IComparable
  117. {
  118. #region Fields
  119. private string m_Name = "unknown";
  120. private string m_Path = "";
  121. private string m_FullPath = "";
  122. private string m_AssemblyName;
  123. private string m_AppIcon = "";
  124. private string m_ApplicationManifest = "";
  125. private string m_ConfigFile = "";
  126. private string m_DesignerFolder = "";
  127. private string m_Language = "C#";
  128. private ProjectType m_Type = ProjectType.Exe;
  129. private ClrRuntime m_Runtime = ClrRuntime.Microsoft;
  130. private FrameworkVersion m_Framework = FrameworkVersion.v2_0;
  131. private bool m_useFramework = true;
  132. private string m_StartupObject = "";
  133. private string m_RootNamespace;
  134. private string m_FilterGroups = "";
  135. private string m_Version = "";
  136. private Guid m_Guid;
  137. private string m_DebugStartParameters;
  138. private readonly Dictionary<string, ConfigurationNode> m_Configurations = new Dictionary<string, ConfigurationNode>();
  139. private readonly List<ReferencePathNode> m_ReferencePaths = new List<ReferencePathNode>();
  140. private readonly List<ReferenceNode> m_References = new List<ReferenceNode>();
  141. private readonly List<AuthorNode> m_Authors = new List<AuthorNode>();
  142. private FilesNode m_Files;
  143. #endregion
  144. #region Properties
  145. /// <summary>
  146. /// Gets the name.
  147. /// </summary>
  148. /// <value>The name.</value>
  149. public string Name
  150. {
  151. get
  152. {
  153. return m_Name;
  154. }
  155. }
  156. /// <summary>
  157. /// The version of the .NET Framework to compile under
  158. /// </summary>
  159. public FrameworkVersion FrameworkVersion
  160. {
  161. get
  162. {
  163. return m_Framework;
  164. }
  165. set
  166. {
  167. m_Framework = value;
  168. m_useFramework = false;
  169. }
  170. }
  171. /// <summary>
  172. /// Gets the path.
  173. /// </summary>
  174. /// <value>The path.</value>
  175. public string Path
  176. {
  177. get
  178. {
  179. return m_Path;
  180. }
  181. }
  182. /// <summary>
  183. /// Gets the filter groups.
  184. /// </summary>
  185. /// <value>The filter groups.</value>
  186. public string FilterGroups
  187. {
  188. get
  189. {
  190. return m_FilterGroups;
  191. }
  192. }
  193. /// <summary>
  194. /// Gets the project's version
  195. /// </summary>
  196. /// <value>The project's version.</value>
  197. public string Version
  198. {
  199. get
  200. {
  201. return m_Version;
  202. }
  203. }
  204. /// <summary>
  205. /// Gets the full path.
  206. /// </summary>
  207. /// <value>The full path.</value>
  208. public string FullPath
  209. {
  210. get
  211. {
  212. return m_FullPath;
  213. }
  214. }
  215. /// <summary>
  216. /// Gets the name of the assembly.
  217. /// </summary>
  218. /// <value>The name of the assembly.</value>
  219. public string AssemblyName
  220. {
  221. get
  222. {
  223. return m_AssemblyName;
  224. }
  225. }
  226. /// <summary>
  227. /// Gets the app icon.
  228. /// </summary>
  229. /// <value>The app icon.</value>
  230. public string AppIcon
  231. {
  232. get
  233. {
  234. return m_AppIcon;
  235. }
  236. }
  237. /// <summary>
  238. /// Gets the Application Manifest.
  239. /// </summary>
  240. /// <value>The Application Manifest.</value>
  241. public string ApplicationManifest
  242. {
  243. get
  244. {
  245. return m_ApplicationManifest;
  246. }
  247. }
  248. /// <summary>
  249. /// Gets the app icon.
  250. /// </summary>
  251. /// <value>The app icon.</value>
  252. public string ConfigFile
  253. {
  254. get
  255. {
  256. return m_ConfigFile;
  257. }
  258. }
  259. /// <summary>
  260. ///
  261. /// </summary>
  262. public string DesignerFolder
  263. {
  264. get
  265. {
  266. return m_DesignerFolder;
  267. }
  268. }
  269. /// <summary>
  270. /// Gets the language.
  271. /// </summary>
  272. /// <value>The language.</value>
  273. public string Language
  274. {
  275. get
  276. {
  277. return m_Language;
  278. }
  279. }
  280. /// <summary>
  281. /// Gets the type.
  282. /// </summary>
  283. /// <value>The type.</value>
  284. public ProjectType Type
  285. {
  286. get
  287. {
  288. return m_Type;
  289. }
  290. }
  291. /// <summary>
  292. /// Gets the runtime.
  293. /// </summary>
  294. /// <value>The runtime.</value>
  295. public ClrRuntime Runtime
  296. {
  297. get
  298. {
  299. return m_Runtime;
  300. }
  301. }
  302. private bool m_GenerateAssemblyInfoFile;
  303. /// <summary>
  304. ///
  305. /// </summary>
  306. public bool GenerateAssemblyInfoFile
  307. {
  308. get
  309. {
  310. return m_GenerateAssemblyInfoFile;
  311. }
  312. set
  313. {
  314. m_GenerateAssemblyInfoFile = value;
  315. }
  316. }
  317. /// <summary>
  318. /// Gets the startup object.
  319. /// </summary>
  320. /// <value>The startup object.</value>
  321. public string StartupObject
  322. {
  323. get
  324. {
  325. return m_StartupObject;
  326. }
  327. }
  328. /// <summary>
  329. /// Gets the root namespace.
  330. /// </summary>
  331. /// <value>The root namespace.</value>
  332. public string RootNamespace
  333. {
  334. get
  335. {
  336. return m_RootNamespace;
  337. }
  338. }
  339. /// <summary>
  340. /// Gets the configurations.
  341. /// </summary>
  342. /// <value>The configurations.</value>
  343. public List<ConfigurationNode> Configurations
  344. {
  345. get
  346. {
  347. List<ConfigurationNode> tmp = new List<ConfigurationNode>(ConfigurationsTable.Values);
  348. tmp.Sort();
  349. return tmp;
  350. }
  351. }
  352. /// <summary>
  353. /// Gets the configurations table.
  354. /// </summary>
  355. /// <value>The configurations table.</value>
  356. public Dictionary<string, ConfigurationNode> ConfigurationsTable
  357. {
  358. get
  359. {
  360. return m_Configurations;
  361. }
  362. }
  363. /// <summary>
  364. /// Gets the reference paths.
  365. /// </summary>
  366. /// <value>The reference paths.</value>
  367. public List<ReferencePathNode> ReferencePaths
  368. {
  369. get
  370. {
  371. List<ReferencePathNode> tmp = new List<ReferencePathNode>(m_ReferencePaths);
  372. tmp.Sort();
  373. return tmp;
  374. }
  375. }
  376. /// <summary>
  377. /// Gets the references.
  378. /// </summary>
  379. /// <value>The references.</value>
  380. public List<ReferenceNode> References
  381. {
  382. get
  383. {
  384. List<ReferenceNode> tmp = new List<ReferenceNode>(m_References);
  385. tmp.Sort();
  386. return tmp;
  387. }
  388. }
  389. /// <summary>
  390. /// Gets the Authors list.
  391. /// </summary>
  392. /// <value>The list of the project's authors.</value>
  393. public List<AuthorNode> Authors
  394. {
  395. get
  396. {
  397. return m_Authors;
  398. }
  399. }
  400. /// <summary>
  401. /// Gets the files.
  402. /// </summary>
  403. /// <value>The files.</value>
  404. public FilesNode Files
  405. {
  406. get
  407. {
  408. return m_Files;
  409. }
  410. }
  411. /// <summary>
  412. /// Gets or sets the parent.
  413. /// </summary>
  414. /// <value>The parent.</value>
  415. public override IDataNode Parent
  416. {
  417. get
  418. {
  419. return base.Parent;
  420. }
  421. set
  422. {
  423. base.Parent = value;
  424. if(base.Parent is SolutionNode && m_Configurations.Count < 1)
  425. {
  426. SolutionNode parent = (SolutionNode)base.Parent;
  427. foreach(ConfigurationNode conf in parent.Configurations)
  428. {
  429. m_Configurations[conf.NameAndPlatform] = (ConfigurationNode) conf.Clone();
  430. }
  431. }
  432. }
  433. }
  434. /// <summary>
  435. /// Gets the GUID.
  436. /// </summary>
  437. /// <value>The GUID.</value>
  438. public Guid Guid
  439. {
  440. get
  441. {
  442. return m_Guid;
  443. }
  444. }
  445. public string DebugStartParameters
  446. {
  447. get
  448. {
  449. return m_DebugStartParameters;
  450. }
  451. }
  452. #endregion
  453. #region Private Methods
  454. private void HandleConfiguration(ConfigurationNode conf)
  455. {
  456. if(String.Compare(conf.Name, "all", true) == 0) //apply changes to all, this may not always be applied first,
  457. //so it *may* override changes to the same properties for configurations defines at the project level
  458. {
  459. foreach(ConfigurationNode confNode in m_Configurations.Values)
  460. {
  461. conf.CopyTo(confNode);//update the config templates defines at the project level with the overrides
  462. }
  463. }
  464. if(m_Configurations.ContainsKey(conf.NameAndPlatform))
  465. {
  466. ConfigurationNode parentConf = m_Configurations[conf.NameAndPlatform];
  467. conf.CopyTo(parentConf);//update the config templates defines at the project level with the overrides
  468. }
  469. else
  470. {
  471. m_Configurations[conf.NameAndPlatform] = conf;
  472. }
  473. }
  474. #endregion
  475. #region Public Methods
  476. /// <summary>
  477. /// Parses the specified node.
  478. /// </summary>
  479. /// <param name="node">The node.</param>
  480. public override void Parse(XmlNode node)
  481. {
  482. m_Name = Helper.AttributeValue(node, "name", m_Name);
  483. m_Path = Helper.AttributeValue(node, "path", m_Path);
  484. m_FilterGroups = Helper.AttributeValue(node, "filterGroups", m_FilterGroups);
  485. m_Version = Helper.AttributeValue(node, "version", m_Version);
  486. m_AppIcon = Helper.AttributeValue(node, "icon", m_AppIcon);
  487. m_ApplicationManifest = Helper.AttributeValue(node, "appmanifest", m_ApplicationManifest);
  488. m_ConfigFile = Helper.AttributeValue(node, "configFile", m_ConfigFile);
  489. m_DesignerFolder = Helper.AttributeValue(node, "designerFolder", m_DesignerFolder);
  490. m_AssemblyName = Helper.AttributeValue(node, "assemblyName", m_AssemblyName);
  491. m_Language = Helper.AttributeValue(node, "language", m_Language);
  492. m_Type = (ProjectType)Helper.EnumAttributeValue(node, "type", typeof(ProjectType), m_Type);
  493. m_Runtime = (ClrRuntime)Helper.EnumAttributeValue(node, "runtime", typeof(ClrRuntime), m_Runtime);
  494. if(m_useFramework)
  495. m_Framework = (FrameworkVersion)Helper.EnumAttributeValue(node, "frameworkVersion", typeof(FrameworkVersion), m_Framework);
  496. m_StartupObject = Helper.AttributeValue(node, "startupObject", m_StartupObject);
  497. m_RootNamespace = Helper.AttributeValue(node, "rootNamespace", m_RootNamespace);
  498. int hash = m_Name.GetHashCode();
  499. Guid guidByHash = new Guid(hash, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  500. string guid = Helper.AttributeValue(node, "guid", guidByHash.ToString());
  501. m_Guid = new Guid(guid);
  502. m_GenerateAssemblyInfoFile = Helper.ParseBoolean(node, "generateAssemblyInfoFile", false);
  503. m_DebugStartParameters = Helper.AttributeValue(node, "debugStartParameters", string.Empty);
  504. if(string.IsNullOrEmpty(m_AssemblyName))
  505. {
  506. m_AssemblyName = m_Name;
  507. }
  508. if(string.IsNullOrEmpty(m_RootNamespace))
  509. {
  510. m_RootNamespace = m_Name;
  511. }
  512. m_FullPath = m_Path;
  513. try
  514. {
  515. m_FullPath = Helper.ResolvePath(m_FullPath);
  516. }
  517. catch
  518. {
  519. throw new WarningException("Could not resolve Solution path: {0}", m_Path);
  520. }
  521. Kernel.Instance.CurrentWorkingDirectory.Push();
  522. try
  523. {
  524. Helper.SetCurrentDir(m_FullPath);
  525. if( node == null )
  526. {
  527. throw new ArgumentNullException("node");
  528. }
  529. foreach(XmlNode child in node.ChildNodes)
  530. {
  531. IDataNode dataNode = Kernel.Instance.ParseNode(child, this);
  532. if(dataNode is ConfigurationNode)
  533. {
  534. HandleConfiguration((ConfigurationNode)dataNode);
  535. }
  536. else if(dataNode is ReferencePathNode)
  537. {
  538. m_ReferencePaths.Add((ReferencePathNode)dataNode);
  539. }
  540. else if(dataNode is ReferenceNode)
  541. {
  542. m_References.Add((ReferenceNode)dataNode);
  543. }
  544. else if(dataNode is AuthorNode)
  545. {
  546. m_Authors.Add((AuthorNode)dataNode);
  547. }
  548. else if(dataNode is FilesNode)
  549. {
  550. m_Files = (FilesNode)dataNode;
  551. }
  552. }
  553. }
  554. finally
  555. {
  556. Kernel.Instance.CurrentWorkingDirectory.Pop();
  557. }
  558. }
  559. #endregion
  560. #region IComparable Members
  561. public int CompareTo(object obj)
  562. {
  563. ProjectNode that = (ProjectNode)obj;
  564. return m_Name.CompareTo(that.m_Name);
  565. }
  566. #endregion
  567. }
  568. }