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