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