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