Kernel.cs 20 KB

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