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