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