diff options
author | BlueWall | 2010-08-31 17:02:36 -0400 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-09-04 02:12:21 +0100 |
commit | 1e44ec84bd90ec9078027d1d9d78e83c7d305f2a (patch) | |
tree | e34db5ced4bc7bf59b98ff9fb72271dda0f25a33 /Prebuild/src/Core/Kernel.cs | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC_OLD-1e44ec84bd90ec9078027d1d9d78e83c7d305f2a.zip opensim-SC_OLD-1e44ec84bd90ec9078027d1d9d78e83c7d305f2a.tar.gz opensim-SC_OLD-1e44ec84bd90ec9078027d1d9d78e83c7d305f2a.tar.bz2 opensim-SC_OLD-1e44ec84bd90ec9078027d1d9d78e83c7d305f2a.tar.xz |
Build system upgrade:
Upgrading Prebuild.exe to correctly construct build solutions
for crossplatform tools such as xbuild, monodevelop and nant.
NOTE: Module prebuild files will need modification to work,
as the prebuild must correctly define the reference path for
all assemblies shipped in the OpenSimulator ./bin directory.
These include assemblies such as XMLRPC.dll, OpenMetaverse.dll,
Nini.dll, etc. . The entries should follow the form:
<Reference name="Nini" path="../../../bin/"/>
See the distributed prebuild.xml for further examples.
Crossplatform tools: xbuild and monodevelop use the
vs2008 OpenSim.sln and the .csproj files in each namespace.
Changes to the Prebuild.exe are against svn 322 and are included
in a patch attached to the mantis. And the dnpb source are
available@ svn co https://dnpb.svn.sourceforge.net/svnroot/dnpb dnpb
The patches are pending application by the dnpb team. After which,
the un-modified upstream Prebuild.exe will work as expected.
Diffstat (limited to '')
-rw-r--r-- | Prebuild/src/Core/Kernel.cs | 831 |
1 files changed, 0 insertions, 831 deletions
diff --git a/Prebuild/src/Core/Kernel.cs b/Prebuild/src/Core/Kernel.cs deleted file mode 100644 index 95ef04e..0000000 --- a/Prebuild/src/Core/Kernel.cs +++ /dev/null | |||
@@ -1,831 +0,0 @@ | |||
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 | using System; | ||
40 | using System.Collections.Generic; | ||
41 | using System.Diagnostics; | ||
42 | using System.Collections; | ||
43 | using System.Collections.Specialized; | ||
44 | using System.IO; | ||
45 | using System.Reflection; | ||
46 | using System.Xml; | ||
47 | using System.Xml.Schema; | ||
48 | using System.Text; | ||
49 | |||
50 | using Prebuild.Core.Attributes; | ||
51 | using Prebuild.Core.Interfaces; | ||
52 | using Prebuild.Core.Nodes; | ||
53 | using Prebuild.Core.Parse; | ||
54 | using Prebuild.Core.Utilities; | ||
55 | |||
56 | namespace Prebuild.Core | ||
57 | { | ||
58 | /// <summary> | ||
59 | /// | ||
60 | /// </summary> | ||
61 | public class Kernel : IDisposable | ||
62 | { | ||
63 | #region Inner Classes | ||
64 | |||
65 | private struct NodeEntry | ||
66 | { | ||
67 | public Type Type; | ||
68 | public DataNodeAttribute Attribute; | ||
69 | } | ||
70 | |||
71 | #endregion | ||
72 | |||
73 | #region Fields | ||
74 | |||
75 | private static readonly Kernel m_Instance = new Kernel(); | ||
76 | |||
77 | /// <summary> | ||
78 | /// This must match the version of the schema that is embeeded | ||
79 | /// </summary> | ||
80 | private const string m_SchemaVersion = "1.7"; | ||
81 | private const string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd"; | ||
82 | private const string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema; | ||
83 | bool disposed; | ||
84 | private Version m_Version; | ||
85 | private const string m_Revision = ""; | ||
86 | private CommandLineCollection m_CommandLine; | ||
87 | private Log m_Log; | ||
88 | private CurrentDirectory m_CurrentWorkingDirectory; | ||
89 | private XmlSchemaCollection m_Schemas; | ||
90 | |||
91 | private Hashtable m_Targets; | ||
92 | private Hashtable m_Nodes; | ||
93 | |||
94 | readonly List<SolutionNode> m_Solutions = new List<SolutionNode>(); | ||
95 | string m_Target; | ||
96 | string m_Clean; | ||
97 | string[] m_RemoveDirectories; | ||
98 | XmlDocument m_CurrentDoc; | ||
99 | bool m_PauseAfterFinish; | ||
100 | string[] m_ProjectGroups; | ||
101 | |||
102 | #endregion | ||
103 | |||
104 | #region Constructors | ||
105 | |||
106 | private Kernel() | ||
107 | { | ||
108 | } | ||
109 | |||
110 | #endregion | ||
111 | |||
112 | #region Properties | ||
113 | |||
114 | /// <summary> | ||
115 | /// Gets a value indicating whether [pause after finish]. | ||
116 | /// </summary> | ||
117 | /// <value><c>true</c> if [pause after finish]; otherwise, <c>false</c>.</value> | ||
118 | public bool PauseAfterFinish | ||
119 | { | ||
120 | get | ||
121 | { | ||
122 | return m_PauseAfterFinish; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | /// <summary> | ||
127 | /// Gets the instance. | ||
128 | /// </summary> | ||
129 | /// <value>The instance.</value> | ||
130 | public static Kernel Instance | ||
131 | { | ||
132 | get | ||
133 | { | ||
134 | return m_Instance; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /// <summary> | ||
139 | /// Gets the version. | ||
140 | /// </summary> | ||
141 | /// <value>The version.</value> | ||
142 | public string Version | ||
143 | { | ||
144 | get | ||
145 | { | ||
146 | return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | /// <summary> | ||
151 | /// Gets the command line. | ||
152 | /// </summary> | ||
153 | /// <value>The command line.</value> | ||
154 | public CommandLineCollection CommandLine | ||
155 | { | ||
156 | get | ||
157 | { | ||
158 | return m_CommandLine; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | /// <summary> | ||
163 | /// Gets the targets. | ||
164 | /// </summary> | ||
165 | /// <value>The targets.</value> | ||
166 | public Hashtable Targets | ||
167 | { | ||
168 | get | ||
169 | { | ||
170 | return m_Targets; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /// <summary> | ||
175 | /// Gets the log. | ||
176 | /// </summary> | ||
177 | /// <value>The log.</value> | ||
178 | public Log Log | ||
179 | { | ||
180 | get | ||
181 | { | ||
182 | return m_Log; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /// <summary> | ||
187 | /// Gets the current working directory. | ||
188 | /// </summary> | ||
189 | /// <value>The current working directory.</value> | ||
190 | public CurrentDirectory CurrentWorkingDirectory | ||
191 | { | ||
192 | get | ||
193 | { | ||
194 | return m_CurrentWorkingDirectory; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /// <summary> | ||
199 | /// Gets the solutions. | ||
200 | /// </summary> | ||
201 | /// <value>The solutions.</value> | ||
202 | public List<SolutionNode> Solutions | ||
203 | { | ||
204 | get | ||
205 | { | ||
206 | return m_Solutions; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /// <summary> | ||
211 | /// Gets the XmlDocument object representing the prebuild.xml | ||
212 | /// being processed | ||
213 | /// </summary> | ||
214 | /// <value>The XmlDocument object</value> | ||
215 | public XmlDocument CurrentDoc | ||
216 | { | ||
217 | get | ||
218 | { | ||
219 | return m_CurrentDoc; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | #endregion | ||
224 | |||
225 | #region Private Methods | ||
226 | |||
227 | private static void RemoveDirectories(string rootDir, string[] dirNames) | ||
228 | { | ||
229 | foreach(string dir in Directory.GetDirectories(rootDir)) | ||
230 | { | ||
231 | string simpleName = Path.GetFileName(dir); | ||
232 | |||
233 | if(Array.IndexOf(dirNames, simpleName) != -1) | ||
234 | { | ||
235 | //delete if the name matches one of the directory names to delete | ||
236 | string fullDirPath = Path.GetFullPath(dir); | ||
237 | Directory.Delete(fullDirPath,true); | ||
238 | } | ||
239 | else//not a match, so check children | ||
240 | { | ||
241 | RemoveDirectories(dir,dirNames); | ||
242 | //recurse, checking children for them | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | // private void RemoveDirectoryMatches(string rootDir, string dirPattern) | ||
248 | // { | ||
249 | // foreach(string dir in Directory.GetDirectories(rootDir)) | ||
250 | // { | ||
251 | // foreach(string match in Directory.GetDirectories(dir)) | ||
252 | // {//delete all child directories that match | ||
253 | // Directory.Delete(Path.GetFullPath(match),true); | ||
254 | // } | ||
255 | // //recure through the rest checking for nested matches to delete | ||
256 | // RemoveDirectoryMatches(dir,dirPattern); | ||
257 | // } | ||
258 | // } | ||
259 | |||
260 | private void LoadSchema() | ||
261 | { | ||
262 | Assembly assembly = this.GetType().Assembly; | ||
263 | Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema); | ||
264 | if(stream == null) | ||
265 | { | ||
266 | //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET | ||
267 | stream = assembly.GetManifestResourceStream(m_Schema); | ||
268 | if(stream == null) | ||
269 | { | ||
270 | throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema)); | ||
271 | } | ||
272 | } | ||
273 | XmlReader schema = new XmlTextReader(stream); | ||
274 | |||
275 | m_Schemas = new XmlSchemaCollection(); | ||
276 | m_Schemas.Add(m_SchemaURI, schema); | ||
277 | } | ||
278 | |||
279 | private void CacheVersion() | ||
280 | { | ||
281 | m_Version = Assembly.GetEntryAssembly().GetName().Version; | ||
282 | } | ||
283 | |||
284 | private void CacheTargets(Assembly assm) | ||
285 | { | ||
286 | foreach(Type t in assm.GetTypes()) | ||
287 | { | ||
288 | TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget)); | ||
289 | |||
290 | if(ta == null) | ||
291 | continue; | ||
292 | |||
293 | if (t.IsAbstract) | ||
294 | continue; | ||
295 | |||
296 | ITarget target = (ITarget)assm.CreateInstance(t.FullName); | ||
297 | if (target == null) | ||
298 | { | ||
299 | throw new MissingMethodException("Could not create ITarget instance"); | ||
300 | } | ||
301 | |||
302 | m_Targets[ta.Name] = target; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | private void CacheNodeTypes(Assembly assm) | ||
307 | { | ||
308 | foreach(Type t in assm.GetTypes()) | ||
309 | { | ||
310 | foreach (DataNodeAttribute dna in t.GetCustomAttributes(typeof(DataNodeAttribute), true)) | ||
311 | { | ||
312 | NodeEntry ne = new NodeEntry(); | ||
313 | ne.Type = t; | ||
314 | ne.Attribute = dna; | ||
315 | m_Nodes[dna.Name] = ne; | ||
316 | } | ||
317 | } | ||
318 | } | ||
319 | |||
320 | private void LogBanner() | ||
321 | { | ||
322 | m_Log.Write("Prebuild v" + this.Version); | ||
323 | m_Log.Write("Copyright (c) 2004-2008"); | ||
324 | m_Log.Write("Matthew Holmes (matthew@wildfiregames.com),"); | ||
325 | m_Log.Write("Dan Moorehead (dan05a@gmail.com),"); | ||
326 | m_Log.Write("David Hudson (jendave@yahoo.com),"); | ||
327 | m_Log.Write("Rob Loach (http://www.robloach.net),"); | ||
328 | m_Log.Write("C.J. Adams-Collier (cjac@colliertech.org),"); | ||
329 | |||
330 | m_Log.Write("See 'prebuild /usage' for help"); | ||
331 | m_Log.Write(); | ||
332 | } | ||
333 | |||
334 | |||
335 | |||
336 | private void ProcessFile(string file) | ||
337 | { | ||
338 | ProcessFile(file, this.m_Solutions); | ||
339 | } | ||
340 | |||
341 | public void ProcessFile(ProcessNode node, SolutionNode parent) | ||
342 | { | ||
343 | if (node.IsValid) | ||
344 | { | ||
345 | List<SolutionNode> list = new List<SolutionNode>(); | ||
346 | ProcessFile(node.Path, list); | ||
347 | |||
348 | foreach (SolutionNode solution in list) | ||
349 | parent.SolutionsTable[solution.Name] = solution; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | /// <summary> | ||
354 | /// | ||
355 | /// </summary> | ||
356 | /// <param name="file"></param> | ||
357 | /// <param name="solutions"></param> | ||
358 | /// <returns></returns> | ||
359 | public void ProcessFile(string file, IList<SolutionNode> solutions) | ||
360 | { | ||
361 | m_CurrentWorkingDirectory.Push(); | ||
362 | |||
363 | string path = file; | ||
364 | try | ||
365 | { | ||
366 | try | ||
367 | { | ||
368 | path = Helper.ResolvePath(path); | ||
369 | } | ||
370 | catch(ArgumentException) | ||
371 | { | ||
372 | m_Log.Write("Could not open Prebuild file: " + path); | ||
373 | m_CurrentWorkingDirectory.Pop(); | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | Helper.SetCurrentDir(Path.GetDirectoryName(path)); | ||
378 | |||
379 | XmlTextReader reader = new XmlTextReader(path); | ||
380 | |||
381 | Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor(); | ||
382 | |||
383 | //register command line arguments as XML variables | ||
384 | IDictionaryEnumerator dict = m_CommandLine.GetEnumerator(); | ||
385 | while (dict.MoveNext()) | ||
386 | { | ||
387 | string name = dict.Key.ToString().Trim(); | ||
388 | if (name.Length > 0) | ||
389 | pre.RegisterVariable(name, dict.Value.ToString()); | ||
390 | } | ||
391 | |||
392 | string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML | ||
393 | |||
394 | // See if the user put into a pseudo target of "prebuild:preprocessed-input" to indicate they want to see the | ||
395 | // output before the system processes it. | ||
396 | if (m_CommandLine.WasPassed("ppi")) | ||
397 | { | ||
398 | // Get the filename if there is one, otherwise use a default. | ||
399 | string ppiFile = m_CommandLine["ppi"]; | ||
400 | if (ppiFile == null || ppiFile.Trim().Length == 0) | ||
401 | { | ||
402 | ppiFile = "preprocessed-input.xml"; | ||
403 | } | ||
404 | |||
405 | // Write out the string to the given stream. | ||
406 | try | ||
407 | { | ||
408 | using (StreamWriter ppiWriter = new StreamWriter(ppiFile)) | ||
409 | { | ||
410 | ppiWriter.WriteLine(xml); | ||
411 | } | ||
412 | } | ||
413 | catch(IOException ex) | ||
414 | { | ||
415 | Console.WriteLine("Could not write PPI file '{0}': {1}", ppiFile, ex.Message); | ||
416 | } | ||
417 | |||
418 | // Finish processing this special tag. | ||
419 | return; | ||
420 | } | ||
421 | |||
422 | m_CurrentDoc = new XmlDocument(); | ||
423 | try | ||
424 | { | ||
425 | XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml))); | ||
426 | |||
427 | //validate while reading from string into XmlDocument DOM structure in memory | ||
428 | foreach(XmlSchema schema in m_Schemas) | ||
429 | { | ||
430 | validator.Schemas.Add(schema); | ||
431 | } | ||
432 | m_CurrentDoc.Load(validator); | ||
433 | } | ||
434 | catch(XmlException e) | ||
435 | { | ||
436 | throw new XmlException(e.ToString()); | ||
437 | } | ||
438 | |||
439 | //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details | ||
440 | if(m_CommandLine.WasPassed("ppo")) | ||
441 | { | ||
442 | string ppoFile = m_CommandLine["ppo"]; | ||
443 | if(ppoFile == null || ppoFile.Trim().Length < 1) | ||
444 | { | ||
445 | ppoFile = "preprocessed.xml"; | ||
446 | } | ||
447 | |||
448 | StreamWriter writer = null; | ||
449 | try | ||
450 | { | ||
451 | writer = new StreamWriter(ppoFile); | ||
452 | writer.Write(xml); | ||
453 | } | ||
454 | catch(IOException ex) | ||
455 | { | ||
456 | Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message); | ||
457 | } | ||
458 | finally | ||
459 | { | ||
460 | if(writer != null) | ||
461 | { | ||
462 | writer.Close(); | ||
463 | } | ||
464 | } | ||
465 | return; | ||
466 | } | ||
467 | //start reading the xml config file | ||
468 | XmlElement rootNode = m_CurrentDoc.DocumentElement; | ||
469 | //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0"); | ||
470 | Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false); | ||
471 | |||
472 | foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions | ||
473 | { | ||
474 | IDataNode dataNode = ParseNode(node, null); | ||
475 | if(dataNode is ProcessNode) | ||
476 | { | ||
477 | ProcessNode proc = (ProcessNode)dataNode; | ||
478 | if(proc.IsValid) | ||
479 | { | ||
480 | ProcessFile(proc.Path); | ||
481 | } | ||
482 | } | ||
483 | else if(dataNode is SolutionNode) | ||
484 | { | ||
485 | solutions.Add((SolutionNode)dataNode); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | catch(XmlSchemaException xse) | ||
490 | { | ||
491 | m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}", | ||
492 | xse.LineNumber, path, xse.Message); | ||
493 | } | ||
494 | finally | ||
495 | { | ||
496 | m_CurrentWorkingDirectory.Pop(); | ||
497 | } | ||
498 | } | ||
499 | |||
500 | #endregion | ||
501 | |||
502 | #region Public Methods | ||
503 | |||
504 | /// <summary> | ||
505 | /// Allows the project. | ||
506 | /// </summary> | ||
507 | /// <param name="projectGroupsFlags">The project groups flags.</param> | ||
508 | /// <returns></returns> | ||
509 | public bool AllowProject(string projectGroupsFlags) | ||
510 | { | ||
511 | if(m_ProjectGroups != null && m_ProjectGroups.Length > 0) | ||
512 | { | ||
513 | if(projectGroupsFlags != null && projectGroupsFlags.Length == 0) | ||
514 | { | ||
515 | foreach(string group in projectGroupsFlags.Split('|')) | ||
516 | { | ||
517 | if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list | ||
518 | { | ||
519 | return true; | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | return false;//not included in the list or no groups specified for the project | ||
524 | } | ||
525 | return true;//no filter specified in the command line args | ||
526 | } | ||
527 | |||
528 | /// <summary> | ||
529 | /// Gets the type of the node. | ||
530 | /// </summary> | ||
531 | /// <param name="node">The node.</param> | ||
532 | /// <returns></returns> | ||
533 | public Type GetNodeType(XmlNode node) | ||
534 | { | ||
535 | if( node == null ) | ||
536 | { | ||
537 | throw new ArgumentNullException("node"); | ||
538 | } | ||
539 | if(!m_Nodes.ContainsKey(node.Name)) | ||
540 | { | ||
541 | return null; | ||
542 | } | ||
543 | |||
544 | NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; | ||
545 | return ne.Type; | ||
546 | } | ||
547 | |||
548 | /// <summary> | ||
549 | /// | ||
550 | /// </summary> | ||
551 | /// <param name="node"></param> | ||
552 | /// <param name="parent"></param> | ||
553 | /// <returns></returns> | ||
554 | public IDataNode ParseNode(XmlNode node, IDataNode parent) | ||
555 | { | ||
556 | return ParseNode(node, parent, null); | ||
557 | } | ||
558 | |||
559 | //Create an instance of the data node type that is mapped to the name of the xml DOM node | ||
560 | /// <summary> | ||
561 | /// Parses the node. | ||
562 | /// </summary> | ||
563 | /// <param name="node">The node.</param> | ||
564 | /// <param name="parent">The parent.</param> | ||
565 | /// <param name="preNode">The pre node.</param> | ||
566 | /// <returns></returns> | ||
567 | public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode) | ||
568 | { | ||
569 | IDataNode dataNode; | ||
570 | |||
571 | try | ||
572 | { | ||
573 | if( node == null ) | ||
574 | { | ||
575 | throw new ArgumentNullException("node"); | ||
576 | } | ||
577 | if(preNode == null) | ||
578 | { | ||
579 | if(!m_Nodes.ContainsKey(node.Name)) | ||
580 | { | ||
581 | //throw new XmlException("Unknown XML node: " + node.Name); | ||
582 | return null; | ||
583 | } | ||
584 | |||
585 | NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; | ||
586 | Type type = ne.Type; | ||
587 | //DataNodeAttribute dna = ne.Attribute; | ||
588 | |||
589 | dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName); | ||
590 | if(dataNode == null) | ||
591 | { | ||
592 | throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName); | ||
593 | } | ||
594 | } | ||
595 | else | ||
596 | dataNode = preNode; | ||
597 | |||
598 | dataNode.Parent = parent; | ||
599 | dataNode.Parse(node); | ||
600 | } | ||
601 | catch(WarningException wex) | ||
602 | { | ||
603 | m_Log.Write(LogType.Warning, wex.Message); | ||
604 | return null; | ||
605 | } | ||
606 | catch(FatalException fex) | ||
607 | { | ||
608 | m_Log.WriteException(LogType.Error, fex); | ||
609 | throw; | ||
610 | } | ||
611 | catch(Exception ex) | ||
612 | { | ||
613 | m_Log.WriteException(LogType.Error, ex); | ||
614 | throw; | ||
615 | } | ||
616 | |||
617 | return dataNode; | ||
618 | } | ||
619 | |||
620 | /// <summary> | ||
621 | /// Initializes the specified target. | ||
622 | /// </summary> | ||
623 | /// <param name="target">The target.</param> | ||
624 | /// <param name="args">The args.</param> | ||
625 | public void Initialize(LogTargets target, string[] args) | ||
626 | { | ||
627 | m_Targets = new Hashtable(); | ||
628 | CacheTargets(this.GetType().Assembly); | ||
629 | m_Nodes = new Hashtable(); | ||
630 | CacheNodeTypes(this.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.Contains(target)) { | ||
754 | m_Log.Write(LogType.Error, "Unknown Target \"{0}\"", target); | ||
755 | return; | ||
756 | } | ||
757 | ITarget targ = (ITarget)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 (!this.disposed) | ||
797 | { | ||
798 | if (disposing) | ||
799 | { | ||
800 | if (this.m_Log != null) | ||
801 | { | ||
802 | this.m_Log.Close(); | ||
803 | this.m_Log = null; | ||
804 | } | ||
805 | } | ||
806 | } | ||
807 | this.disposed = true; | ||
808 | } | ||
809 | |||
810 | /// <summary> | ||
811 | /// | ||
812 | /// </summary> | ||
813 | ~Kernel() | ||
814 | { | ||
815 | this.Dispose(false); | ||
816 | } | ||
817 | |||
818 | /// <summary> | ||
819 | /// Closes and destroys this object | ||
820 | /// </summary> | ||
821 | /// <remarks> | ||
822 | /// Same as Dispose(true) | ||
823 | /// </remarks> | ||
824 | public void Close() | ||
825 | { | ||
826 | Dispose(); | ||
827 | } | ||
828 | |||
829 | #endregion | ||
830 | } | ||
831 | } | ||