+using System;\r
+using System.IO;\r
+using System.Diagnostics;\r
+using System.Configuration;\r
+using System.Web.Mail;\r
+using System.Collections;\r
+using System.Collections.Specialized;\r
+\r
+namespace ReactOS.Verify\r
+{\r
+ public class MainClass\r
+ {\r
+ /// <summary>\r
+ /// Run the application.\r
+ /// </summary>\r
+ /// <param name="script">Script to run.</param>\r
+ /// <param name="args">Arguments to pass to script.</param>\r
+ /// <param name="workingDirectory">Working directory.</param>\r
+ /// <param name="standardOutput">Receives standard output.</param>\r
+ /// <param name="standardError">Receives standard error.</param>\r
+ /// <returns>\r
+ /// Exit code.\r
+ /// </returns>\r
+ private static int RunScript(string script,\r
+ string args,\r
+ string workingDirectory,\r
+ StringDictionary environmentVarables,\r
+ out string standardOutput,\r
+ out string standardError)\r
+ {\r
+ ProcessStartInfo scriptProcessStartInfo = new ProcessStartInfo(script,\r
+ args);\r
+ scriptProcessStartInfo.CreateNoWindow = true;\r
+ /*\r
+ * All standard streams must be redirected.\r
+ * Otherwise DuplicateHandle() will fail.\r
+ */\r
+ scriptProcessStartInfo.RedirectStandardInput = true;\r
+ scriptProcessStartInfo.RedirectStandardError = true;\r
+ scriptProcessStartInfo.RedirectStandardOutput = true;\r
+ scriptProcessStartInfo.UseShellExecute = false;\r
+ scriptProcessStartInfo.WorkingDirectory = workingDirectory;\r
+ if (environmentVarables != null)\r
+ {\r
+ foreach (DictionaryEntry de in environmentVarables)\r
+ scriptProcessStartInfo.EnvironmentVariables.Add(de.Key as string, de.Value as string);\r
+ }\r
+ RedirectableProcess redirectableProcess = new RedirectableProcess(scriptProcessStartInfo);\r
+ standardOutput = redirectableProcess.ProcessOutput;\r
+ standardError = redirectableProcess.ProcessError;\r
+ return redirectableProcess.ExitCode;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Retrieve value of configuration from configuration file.\r
+ /// </summary>\r
+ /// <param name="name">Name of configuration option.</param>\r
+ /// <param name="defaultValue">\r
+ /// Default value to be returned if the option does not exist.\r
+ /// </param>\r
+ /// <returns>\r
+ /// Value of configuration option or null if the option does not\r
+ /// exist and no default value is provided.\r
+ /// </returns>\r
+ private static string GetConfigurationOption(string name,\r
+ string defaultValue)\r
+ {\r
+ if (ConfigurationSettings.AppSettings[name] != null)\r
+ {\r
+ string s = ConfigurationSettings.AppSettings[name].Trim();\r
+ return s.Equals(String.Empty) ? defaultValue : s;\r
+ }\r
+ else\r
+ return defaultValue;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Send an email.\r
+ /// </summary>\r
+ /// <param name="subject">Subject of the email.</param>\r
+ /// <param name="body">Content of the email.</param>\r
+ private static void SendErrorMail(string subject, string body)\r
+ {\r
+ try\r
+ {\r
+ string smtpServer = GetConfigurationOption("smtpServer", "localhost");\r
+ string email = GetConfigurationOption("errorEmail", null);\r
+ if (email == null)\r
+ return;\r
+ MailMessage mm = new MailMessage();\r
+ mm.Priority = MailPriority.Normal;\r
+ mm.From = email;\r
+ mm.To = email;\r
+ mm.Subject = subject;\r
+ mm.Body += body;\r
+ mm.Body += "<br>";\r
+ mm.BodyFormat = MailFormat.Html;\r
+ SmtpMail.SmtpServer = smtpServer;\r
+ SmtpMail.Send(mm);\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ Console.Error.WriteLine(ex.Message);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Fail with an error message.\r
+ /// </summary>\r
+ /// <param name="text">Error message.</param>\r
+ private static void Fail(string text)\r
+ {\r
+ Console.WriteLine(text);\r
+ }\r
+ \r
+ /// <summary>\r
+ /// Paths to fast disk for temporary files.\r
+ /// </summary>\r
+ private static string TemporaryFastDisk\r
+ {\r
+ get\r
+ {\r
+ string temporaryFastDisk = GetConfigurationOption("temporaryFastDisk", null);\r
+ if (temporaryFastDisk == null || temporaryFastDisk.Trim().Equals(String.Empty))\r
+ return null;\r
+ return temporaryFastDisk.Trim();\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Paths to fast disk for intermediate files.\r
+ /// </summary>\r
+ private static string IntermediateFastDisk\r
+ {\r
+ get\r
+ {\r
+ string intermediateFastDisk = GetConfigurationOption("intermediateFastDisk", null);\r
+ if (intermediateFastDisk == null || intermediateFastDisk.Trim().Equals(String.Empty))\r
+ return null;\r
+ return intermediateFastDisk.Trim();\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Paths to fast disk for output files.\r
+ /// </summary>\r
+ private static string OutputFastDisk\r
+ {\r
+ get\r
+ {\r
+ string outputFastDisk = GetConfigurationOption("outputFastDisk", null);\r
+ if (outputFastDisk == null || outputFastDisk.Trim().Equals(String.Empty))\r
+ return null;\r
+ return outputFastDisk.Trim();\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Return collection of environment variables.\r
+ /// </summary>\r
+ /// <returns>Collection of environment variables or null if there is none.</returns>\r
+ private static StringDictionary GetEnvironmentVarables()\r
+ {\r
+ StringDictionary environmentVarables = new StringDictionary();\r
+ if (TemporaryFastDisk != null)\r
+ environmentVarables.Add("ROS_TEMPORARY", TemporaryFastDisk);\r
+ if (IntermediateFastDisk != null)\r
+ environmentVarables.Add("ROS_INTERMEDIATE", IntermediateFastDisk);\r
+ if (OutputFastDisk != null)\r
+ environmentVarables.Add("ROS_OUTPUT", OutputFastDisk);\r
+ return environmentVarables;\r
+ }\r
+ \r
+ /// <summary>\r
+ /// Run make.\r
+ /// </summary>\r
+ /// <param name="arguments">Arguments.</param>\r
+ /// <param name="standardOutput">Receives standard output.</param>\r
+ /// <param name="standardError">Receives standard error.</param>\r
+ /// <returns>Make exit code.</returns>\r
+ private static int RunMake(string arguments,\r
+ out string standardOutput,\r
+ out string standardError)\r
+ {\r
+ string make = "mingw32-make";\r
+ string makeParameters = GetConfigurationOption("makeParameters", "");\r
+ string reactosDirectory = Path.Combine(System.Environment.CurrentDirectory,\r
+ "reactos");\r
+ return RunScript(make,\r
+ makeParameters + " " + arguments,\r
+ reactosDirectory,\r
+ GetEnvironmentVarables(),\r
+ out standardOutput,\r
+ out standardError);\r
+ }\r
+ \r
+ /// <summary>\r
+ /// Verify a revision of ReactOS by building it all.\r
+ /// </summary>\r
+ private static int VerifyFull()\r
+ {\r
+ string standardOutput;\r
+ string standardError;\r
+ int exitCode = RunMake("bootcd",\r
+ out standardOutput,\r
+ out standardError);\r
+ if (exitCode != 0)\r
+ {\r
+ Fail(String.Format("make bootcd failed: (error: {0}) {1}",\r
+ standardError,\r
+ standardOutput));\r
+ return exitCode;\r
+ }\r
+ \r
+ string reactosDirectory = Path.Combine(System.Environment.CurrentDirectory,\r
+ "reactos");\r
+ string isoFilename = Path.Combine(reactosDirectory,\r
+ "ReactOS.iso");\r
+ if (!File.Exists(isoFilename))\r
+ Fail("make bootcd produced no ReactOS.iso");\r
+\r
+ return exitCode;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Verify a revision of ReactOS by building parts.\r
+ /// </summary>\r
+ /// <param name="components">Comma separated list of components to build.</param>\r
+ private static int VerifyPartial(string components)\r
+ {\r
+ string standardOutput;\r
+ string standardError;\r
+ string componentParameters = "\"" + components.Replace(",", "\" \"") + "\"";\r
+ int exitCode = RunMake(componentParameters,\r
+ out standardOutput,\r
+ out standardError);\r
+ if (exitCode != 0)\r
+ Fail(String.Format("make failed for targets {0}: (error: {1}) {2}",\r
+ componentParameters,\r
+ standardError,\r
+ standardOutput));\r
+ return exitCode;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Verify a revision of ReactOS.\r
+ /// </summary>\r
+ /// <param name="args">Arguments from command line.</param>\r
+ private static int Verify(string[] args)\r
+ {\r
+ if (args.Length > 0)\r
+ return VerifyPartial(args[0]);\r
+ else\r
+ return VerifyFull();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Program entry point.\r
+ /// </summary>\r
+ /// <param name="args">Arguments from command line.</param>\r
+ /// <remarks>\r
+ /// If exit code is 0, then the commit was processed successfully.\r
+ /// If exit code is 1, then the commit was not processed successfully.\r
+ /// </remarks>\r
+ public static void Main(string[] args)\r
+ {\r
+ try\r
+ {\r
+ System.Environment.ExitCode = Verify(args);\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ string text = String.Format("Exception: {0}", ex);\r
+ SendErrorMail("ReactOS Verify Error", text);\r
+ System.Environment.ExitCode = 1;\r
+ }\r
+ }\r
+ }\r
+}\r