Kernel.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. #region BSD License
  2. /*
  3. Copyright (c) 2004-2008
  4. Matthew Holmes ([email protected]),
  5. Dan Moorehead ([email protected]),
  6. Rob Loach (http://www.robloach.net),
  7. C.J. Adams-Collier ([email protected])
  8. Redistribution and use in source and binary forms, with or without
  9. modification, are permitted provided that the following conditions are
  10. met:
  11. * Redistributions of source code must retain the above copyright
  12. notice, this list of conditions and the following disclaimer.
  13. * Redistributions in binary form must reproduce the above copyright
  14. notice, this list of conditions and the following disclaimer in the
  15. documentation and/or other materials provided with the distribution.
  16. * The name of the author may not be used to endorse or promote
  17. products derived from this software without specific prior written
  18. permission.
  19. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  23. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  28. IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #endregion
  32. #define NO_VALIDATE
  33. using System;
  34. using System.Collections.Generic;
  35. using System.IO;
  36. using System.Reflection;
  37. using System.Xml;
  38. using System.Xml.Schema;
  39. using Prebuild.Core.Attributes;
  40. using Prebuild.Core.Interfaces;
  41. using Prebuild.Core.Nodes;
  42. using Prebuild.Core.Utilities;
  43. namespace Prebuild.Core
  44. {
  45. /// <summary>
  46. ///
  47. /// </summary>
  48. public class Kernel : IDisposable
  49. {
  50. #region Inner Classes
  51. private struct NodeEntry
  52. {
  53. public Type Type;
  54. public DataNodeAttribute Attribute;
  55. }
  56. #endregion
  57. #region Fields
  58. private static readonly Kernel m_Instance = new Kernel();
  59. /// <summary>
  60. /// This must match the version of the schema that is embeeded
  61. /// </summary>
  62. private const string m_SchemaVersion = "1.10";
  63. private const string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd";
  64. private const string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema;
  65. bool disposed;
  66. private Version m_Version;
  67. private const string m_Revision = "w";
  68. private CommandLineCollection m_CommandLine;
  69. private Log m_Log;
  70. private CurrentDirectory m_CurrentWorkingDirectory;
  71. private XmlSchemaCollection m_Schemas;
  72. private readonly Dictionary<string, ITarget> m_Targets = new Dictionary<string, ITarget>();
  73. private readonly Dictionary<string, NodeEntry> m_Nodes = new Dictionary<string, NodeEntry>();
  74. readonly List<SolutionNode> m_Solutions = new List<SolutionNode>();
  75. string m_Target;
  76. bool cmdlineTargetFramework;
  77. FrameworkVersion m_TargetFramework; //Overrides all project settings
  78. string m_Conditionals; //Adds to all project settings
  79. public string ForcedConditionals { get { return m_Conditionals; } }
  80. string m_Clean;
  81. string[] m_RemoveDirectories;
  82. XmlDocument m_CurrentDoc;
  83. bool m_PauseAfterFinish;
  84. string[] m_ProjectGroups;
  85. #endregion
  86. #region Constructors
  87. private Kernel()
  88. {
  89. }
  90. #endregion
  91. #region Properties
  92. /// <summary>
  93. /// Gets a value indicating whether [pause after finish].
  94. /// </summary>
  95. /// <value><c>true</c> if [pause after finish]; otherwise, <c>false</c>.</value>
  96. public bool PauseAfterFinish
  97. {
  98. get
  99. {
  100. return m_PauseAfterFinish;
  101. }
  102. }
  103. /// <summary>
  104. /// Gets the instance.
  105. /// </summary>
  106. /// <value>The instance.</value>
  107. public static Kernel Instance
  108. {
  109. get
  110. {
  111. return m_Instance;
  112. }
  113. }
  114. /// <summary>
  115. /// Gets the version.
  116. /// </summary>
  117. /// <value>The version.</value>
  118. public string Version
  119. {
  120. get
  121. {
  122. return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision);
  123. }
  124. }
  125. /// <summary>
  126. /// Gets the command line.
  127. /// </summary>
  128. /// <value>The command line.</value>
  129. public CommandLineCollection CommandLine
  130. {
  131. get
  132. {
  133. return m_CommandLine;
  134. }
  135. }
  136. /// <summary>
  137. /// Gets the targets.
  138. /// </summary>
  139. /// <value>The targets.</value>
  140. public Dictionary<string, ITarget> Targets
  141. {
  142. get
  143. {
  144. return m_Targets;
  145. }
  146. }
  147. /// <summary>
  148. /// Gets the log.
  149. /// </summary>
  150. /// <value>The log.</value>
  151. public Log Log
  152. {
  153. get
  154. {
  155. return m_Log;
  156. }
  157. }
  158. /// <summary>
  159. /// Gets the current working directory.
  160. /// </summary>
  161. /// <value>The current working directory.</value>
  162. public CurrentDirectory CurrentWorkingDirectory
  163. {
  164. get
  165. {
  166. return m_CurrentWorkingDirectory;
  167. }
  168. }
  169. /// <summary>
  170. /// Gets the solutions.
  171. /// </summary>
  172. /// <value>The solutions.</value>
  173. public List<SolutionNode> Solutions
  174. {
  175. get
  176. {
  177. return m_Solutions;
  178. }
  179. }
  180. /// <summary>
  181. /// Gets the XmlDocument object representing the prebuild.xml
  182. /// being processed
  183. /// </summary>
  184. /// <value>The XmlDocument object</value>
  185. public XmlDocument CurrentDoc
  186. {
  187. get
  188. {
  189. return m_CurrentDoc;
  190. }
  191. }
  192. #endregion
  193. #region Private Methods
  194. private static void RemoveDirectories(string rootDir, string[] dirNames)
  195. {
  196. foreach(string dir in Directory.GetDirectories(rootDir))
  197. {
  198. string simpleName = Path.GetFileName(dir);
  199. if(Array.IndexOf(dirNames, simpleName) != -1)
  200. {
  201. //delete if the name matches one of the directory names to delete
  202. string fullDirPath = Path.GetFullPath(dir);
  203. Directory.Delete(fullDirPath,true);
  204. }
  205. else//not a match, so check children
  206. {
  207. RemoveDirectories(dir,dirNames);
  208. //recurse, checking children for them
  209. }
  210. }
  211. }
  212. // private void RemoveDirectoryMatches(string rootDir, string dirPattern)
  213. // {
  214. // foreach(string dir in Directory.GetDirectories(rootDir))
  215. // {
  216. // foreach(string match in Directory.GetDirectories(dir))
  217. // {//delete all child directories that match
  218. // Directory.Delete(Path.GetFullPath(match),true);
  219. // }
  220. // //recure through the rest checking for nested matches to delete
  221. // RemoveDirectoryMatches(dir,dirPattern);
  222. // }
  223. // }
  224. private void LoadSchema()
  225. {
  226. Assembly assembly = GetType().Assembly;
  227. Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema);
  228. if(stream == null)
  229. {
  230. //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET
  231. stream = assembly.GetManifestResourceStream(m_Schema);
  232. if(stream == null)
  233. {
  234. throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema));
  235. }
  236. }
  237. XmlReader schema = new XmlTextReader(stream);
  238. m_Schemas = new XmlSchemaCollection();
  239. m_Schemas.Add(m_SchemaURI, schema);
  240. }
  241. private void CacheVersion()
  242. {
  243. m_Version = Assembly.GetEntryAssembly().GetName().Version;
  244. }
  245. private void CacheTargets(Assembly assm)
  246. {
  247. foreach(Type t in assm.GetTypes())
  248. {
  249. TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget));
  250. if(ta == null)
  251. continue;
  252. if (t.IsAbstract)
  253. continue;
  254. ITarget target = (ITarget)assm.CreateInstance(t.FullName);
  255. if (target == null)
  256. {
  257. throw new MissingMethodException("Could not create ITarget instance");
  258. }
  259. m_Targets[ta.Name] = target;
  260. }
  261. }
  262. private void CacheNodeTypes(Assembly assm)
  263. {
  264. foreach(Type t in assm.GetTypes())
  265. {
  266. foreach (DataNodeAttribute dna in t.GetCustomAttributes(typeof(DataNodeAttribute), true))
  267. {
  268. NodeEntry ne = new NodeEntry();
  269. ne.Type = t;
  270. ne.Attribute = dna;
  271. m_Nodes[dna.Name] = ne;
  272. }
  273. }
  274. }
  275. private void LogBanner()
  276. {
  277. m_Log.Write("Prebuild v" + Version);
  278. m_Log.Write("Copyright (c) 2004-2010");
  279. m_Log.Write("Matthew Holmes ([email protected]),");
  280. m_Log.Write("Dan Moorehead ([email protected]),");
  281. m_Log.Write("David Hudson ([email protected]),");
  282. m_Log.Write("Rob Loach (http://www.robloach.net),");
  283. m_Log.Write("C.J. Adams-Collier ([email protected]),");
  284. m_Log.Write("John Hurliman ([email protected]),");
  285. m_Log.Write("WhiteCore build 2015 ([email protected]),");
  286. m_Log.Write("OpenSim build 2017 Ubit Umarov,");
  287. m_Log.Write ("");
  288. m_Log.Write("See 'prebuild /usage' for help");
  289. m_Log.Write();
  290. }
  291. private void ProcessFile(string file)
  292. {
  293. ProcessFile(file, m_Solutions);
  294. }
  295. public void ProcessFile(ProcessNode node, SolutionNode parent)
  296. {
  297. if (node.IsValid)
  298. {
  299. List<SolutionNode> list = new List<SolutionNode>();
  300. ProcessFile(node.Path, list);
  301. foreach (SolutionNode solution in list)
  302. parent.SolutionsTable[solution.Name] = solution;
  303. }
  304. }
  305. /// <summary>
  306. ///
  307. /// </summary>
  308. /// <param name="file"></param>
  309. /// <param name="solutions"></param>
  310. /// <returns></returns>
  311. public void ProcessFile(string file, IList<SolutionNode> solutions)
  312. {
  313. m_CurrentWorkingDirectory.Push();
  314. string path = file;
  315. try
  316. {
  317. try
  318. {
  319. path = Helper.ResolvePath(path);
  320. }
  321. catch(ArgumentException)
  322. {
  323. m_Log.Write("Could not open Prebuild file: " + path);
  324. m_CurrentWorkingDirectory.Pop();
  325. return;
  326. }
  327. Helper.SetCurrentDir(Path.GetDirectoryName(path));
  328. XmlTextReader reader = new XmlTextReader(path);
  329. Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor();
  330. //register command line arguments as XML variables
  331. IEnumerator<KeyValuePair<string, string>> dict = m_CommandLine.GetEnumerator();
  332. while (dict.MoveNext())
  333. {
  334. string name = dict.Current.Key.Trim();
  335. if (name.Length > 0)
  336. pre.RegisterVariable(name, dict.Current.Value);
  337. }
  338. string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML
  339. // See if the user put into a pseudo target of "prebuild:preprocessed-input" to indicate they want to see the
  340. // output before the system processes it.
  341. if (m_CommandLine.WasPassed("ppi"))
  342. {
  343. // Get the filename if there is one, otherwise use a default.
  344. string ppiFile = m_CommandLine["ppi"];
  345. if (ppiFile == null || ppiFile.Trim().Length == 0)
  346. {
  347. ppiFile = "preprocessed-input.xml";
  348. }
  349. // Write out the string to the given stream.
  350. try
  351. {
  352. using (StreamWriter ppiWriter = new StreamWriter(ppiFile))
  353. {
  354. ppiWriter.WriteLine(xml);
  355. }
  356. }
  357. catch(IOException ex)
  358. {
  359. Console.WriteLine("Could not write PPI file '{0}': {1}", ppiFile, ex.Message);
  360. }
  361. // Finish processing this special tag.
  362. return;
  363. }
  364. m_CurrentDoc = new XmlDocument();
  365. try
  366. {
  367. #if NO_VALIDATE
  368. XmlReader validator = XmlReader.Create(new StringReader(xml));
  369. m_CurrentDoc.Load(validator);
  370. #else
  371. XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml)));
  372. //validate while reading from string into XmlDocument DOM structure in memory
  373. foreach(XmlSchema schema in m_Schemas)
  374. {
  375. validator.Schemas.Add(schema);
  376. }
  377. m_CurrentDoc.Load(validator);
  378. #endif
  379. }
  380. catch(XmlException e)
  381. {
  382. throw new XmlException(e.ToString());
  383. }
  384. //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details
  385. if(m_CommandLine.WasPassed("ppo"))
  386. {
  387. string ppoFile = m_CommandLine["ppo"];
  388. if(ppoFile == null || ppoFile.Trim().Length < 1)
  389. {
  390. ppoFile = "preprocessed.xml";
  391. }
  392. StreamWriter writer = null;
  393. try
  394. {
  395. writer = new StreamWriter(ppoFile);
  396. writer.Write(xml);
  397. }
  398. catch(IOException ex)
  399. {
  400. Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message);
  401. }
  402. finally
  403. {
  404. if(writer != null)
  405. {
  406. writer.Close();
  407. }
  408. }
  409. return;
  410. }
  411. //start reading the xml config file
  412. XmlElement rootNode = m_CurrentDoc.DocumentElement;
  413. //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0");
  414. Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false);
  415. foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions
  416. {
  417. IDataNode dataNode = ParseNode(node, null);
  418. if(dataNode is ProcessNode)
  419. {
  420. ProcessNode proc = (ProcessNode)dataNode;
  421. if(proc.IsValid)
  422. {
  423. ProcessFile(proc.Path);
  424. }
  425. }
  426. else if(dataNode is SolutionNode)
  427. {
  428. solutions.Add((SolutionNode)dataNode);
  429. }
  430. }
  431. }
  432. catch(XmlSchemaException xse)
  433. {
  434. m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}",
  435. xse.LineNumber, path, xse.Message);
  436. }
  437. finally
  438. {
  439. m_CurrentWorkingDirectory.Pop();
  440. }
  441. }
  442. #endregion
  443. #region Public Methods
  444. /// <summary>
  445. /// Allows the project.
  446. /// </summary>
  447. /// <param name="projectGroupsFlags">The project groups flags.</param>
  448. /// <returns></returns>
  449. public bool AllowProject(string projectGroupsFlags)
  450. {
  451. if(m_ProjectGroups != null && m_ProjectGroups.Length > 0)
  452. {
  453. if(projectGroupsFlags != null && projectGroupsFlags.Length == 0)
  454. {
  455. foreach(string group in projectGroupsFlags.Split('|'))
  456. {
  457. if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list
  458. {
  459. return true;
  460. }
  461. }
  462. }
  463. return false;//not included in the list or no groups specified for the project
  464. }
  465. return true;//no filter specified in the command line args
  466. }
  467. /// <summary>
  468. /// Gets the type of the node.
  469. /// </summary>
  470. /// <param name="node">The node.</param>
  471. /// <returns></returns>
  472. public Type GetNodeType(XmlNode node)
  473. {
  474. if( node == null )
  475. {
  476. throw new ArgumentNullException("node");
  477. }
  478. if(!m_Nodes.ContainsKey(node.Name))
  479. {
  480. return null;
  481. }
  482. NodeEntry ne = m_Nodes[node.Name];
  483. return ne.Type;
  484. }
  485. /// <summary>
  486. ///
  487. /// </summary>
  488. /// <param name="node"></param>
  489. /// <param name="parent"></param>
  490. /// <returns></returns>
  491. public IDataNode ParseNode(XmlNode node, IDataNode parent)
  492. {
  493. return ParseNode(node, parent, null);
  494. }
  495. //Create an instance of the data node type that is mapped to the name of the xml DOM node
  496. /// <summary>
  497. /// Parses the node.
  498. /// </summary>
  499. /// <param name="node">The node.</param>
  500. /// <param name="parent">The parent.</param>
  501. /// <param name="preNode">The pre node.</param>
  502. /// <returns></returns>
  503. public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode)
  504. {
  505. IDataNode dataNode;
  506. try
  507. {
  508. if( node == null )
  509. {
  510. throw new ArgumentNullException("node");
  511. }
  512. if(preNode == null)
  513. {
  514. if(!m_Nodes.ContainsKey(node.Name))
  515. {
  516. Console.WriteLine("WARNING: Unknown XML node: " + node.Name);
  517. return null;
  518. }
  519. NodeEntry ne = m_Nodes[node.Name];
  520. Type type = ne.Type;
  521. //DataNodeAttribute dna = ne.Attribute;
  522. dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName);
  523. if(dataNode == null)
  524. {
  525. throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName);
  526. }
  527. }
  528. else
  529. dataNode = preNode;
  530. dataNode.Parent = parent;
  531. if (cmdlineTargetFramework && dataNode is ProjectNode)
  532. {
  533. ((ProjectNode)dataNode).FrameworkVersion = m_TargetFramework;
  534. }
  535. dataNode.Parse(node);
  536. }
  537. catch(WarningException wex)
  538. {
  539. m_Log.Write(LogType.Warning, wex.Message);
  540. return null;
  541. }
  542. catch(FatalException fex)
  543. {
  544. m_Log.WriteException(LogType.Error, fex);
  545. throw;
  546. }
  547. catch(Exception ex)
  548. {
  549. m_Log.WriteException(LogType.Error, ex);
  550. throw;
  551. }
  552. return dataNode;
  553. }
  554. /// <summary>
  555. /// Initializes the specified target.
  556. /// </summary>
  557. /// <param name="target">The target.</param>
  558. /// <param name="args">The args.</param>
  559. public void Initialize(LogTargets target, string[] args)
  560. {
  561. CacheTargets(GetType().Assembly);
  562. CacheNodeTypes(GetType().Assembly);
  563. CacheVersion();
  564. m_CommandLine = new CommandLineCollection(args);
  565. string logFile = null;
  566. if(m_CommandLine.WasPassed("log"))
  567. {
  568. logFile = m_CommandLine["log"];
  569. if(logFile != null && logFile.Length == 0)
  570. {
  571. logFile = "Prebuild.log";
  572. }
  573. }
  574. else
  575. {
  576. target = target & ~LogTargets.File; //dont output to a file
  577. }
  578. m_Log = new Log(target, logFile);
  579. LogBanner();
  580. m_CurrentWorkingDirectory = new CurrentDirectory();
  581. m_Target = m_CommandLine["target"];
  582. m_Conditionals = m_CommandLine["conditionals"];
  583. if(m_CommandLine["targetframework"] != null)
  584. {
  585. m_TargetFramework = (FrameworkVersion)Enum.Parse (typeof (FrameworkVersion), m_CommandLine["targetframework"]);
  586. cmdlineTargetFramework = true;
  587. }
  588. m_Clean = m_CommandLine["clean"];
  589. string removeDirs = m_CommandLine["removedir"];
  590. if(removeDirs != null && removeDirs.Length == 0)
  591. {
  592. m_RemoveDirectories = removeDirs.Split('|');
  593. }
  594. string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include
  595. if(flags != null && flags.Length == 0)
  596. {
  597. m_ProjectGroups = flags.Split('|');
  598. }
  599. m_PauseAfterFinish = m_CommandLine.WasPassed("pause");
  600. LoadSchema();
  601. }
  602. /// <summary>
  603. /// Processes this instance.
  604. /// </summary>
  605. public void Process()
  606. {
  607. bool perfomedOtherTask = false;
  608. if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0)
  609. {
  610. try
  611. {
  612. RemoveDirectories(".",m_RemoveDirectories);
  613. }
  614. catch(IOException e)
  615. {
  616. m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories);
  617. m_Log.WriteException(LogType.Error,e);
  618. }
  619. catch(UnauthorizedAccessException e)
  620. {
  621. m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories);
  622. m_Log.WriteException(LogType.Error,e);
  623. }
  624. perfomedOtherTask = true;
  625. }
  626. if(m_Target != null && m_Clean != null)
  627. {
  628. m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together");
  629. return;
  630. }
  631. if(m_Target == null && m_Clean == null)
  632. {
  633. if(perfomedOtherTask) //finished
  634. {
  635. return;
  636. }
  637. m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file");
  638. return;
  639. }
  640. string file = "./prebuild.xml";
  641. if(m_CommandLine.WasPassed("file"))
  642. {
  643. file = m_CommandLine["file"];
  644. }
  645. ProcessFile(file);
  646. string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower());
  647. bool clean = (m_Target == null);
  648. if(clean && target != null && target.Length == 0)
  649. {
  650. target = "all";
  651. }
  652. if(clean && target == "all")//default to all if no target was specified for clean
  653. {
  654. //check if they passed yes
  655. if (!m_CommandLine.WasPassed("yes"))
  656. {
  657. Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):");
  658. string ret = Console.ReadLine();
  659. if(ret == null)
  660. {
  661. return;
  662. }
  663. ret = ret.Trim().ToLower();
  664. if((ret.ToLower() != "y" && ret.ToLower() != "yes"))
  665. {
  666. return;
  667. }
  668. }
  669. //clean all targets (just cleaning vs2002 target didn't clean nant)
  670. foreach(ITarget targ in m_Targets.Values)
  671. {
  672. targ.Clean(this);
  673. }
  674. }
  675. else
  676. {
  677. if (!m_Targets.ContainsKey(target)) {
  678. m_Log.Write(LogType.Error, "Unknown Target \"{0}\"", target);
  679. return;
  680. }
  681. ITarget targ = m_Targets[target];
  682. if(clean)
  683. {
  684. targ.Clean(this);
  685. }
  686. else
  687. {
  688. targ.Write(this);
  689. }
  690. }
  691. m_Log.Flush();
  692. }
  693. #endregion
  694. #region IDisposable Members
  695. /// <summary>
  696. ///
  697. /// </summary>
  698. public void Dispose()
  699. {
  700. Dispose(true);
  701. GC.SuppressFinalize(this);
  702. }
  703. /// <summary>
  704. /// Dispose objects
  705. /// </summary>
  706. /// <param name="disposing">
  707. /// If true, it will dispose close the handle
  708. /// </param>
  709. /// <remarks>
  710. /// Will dispose managed and unmanaged resources.
  711. /// </remarks>
  712. protected virtual void Dispose(bool disposing)
  713. {
  714. if (!disposed)
  715. {
  716. if (disposing)
  717. {
  718. GC.SuppressFinalize(this);
  719. if (m_Log != null)
  720. {
  721. m_Log.Close();
  722. m_Log = null;
  723. }
  724. }
  725. }
  726. disposed = true;
  727. }
  728. /// <summary>
  729. ///
  730. /// </summary>
  731. ~Kernel()
  732. {
  733. Dispose(false);
  734. }
  735. /// <summary>
  736. /// Closes and destroys this object
  737. /// </summary>
  738. /// <remarks>
  739. /// Same as Dispose(true)
  740. /// </remarks>
  741. public void Close()
  742. {
  743. Dispose();
  744. }
  745. #endregion
  746. }
  747. }