mirror of
https://github.com/reactos/reactos.git
synced 2025-02-20 15:35:04 +00:00
ReactOS Sin Custom Revision Action (Revision ISO Creator)
svn path=/trunk/; revision=19491
This commit is contained in:
parent
f250d1638b
commit
a98cfa1b66
5 changed files with 443 additions and 0 deletions
10
cis/ReactOS.CustomRevisionAction/App.config
Normal file
10
cis/ReactOS.CustomRevisionAction/App.config
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="publishPath" value="c:\iso" />
|
||||
<add key="smtpServer" value="localhost" />
|
||||
<add key="errorEmail" value="mailbox@somewhere-on-the-net" />
|
||||
<add key="makeParameters" value="" />
|
||||
<add key="fastDisk" value="" />
|
||||
</appSettings>
|
||||
</configuration>
|
14
cis/ReactOS.CustomRevisionAction/AssemblyInfo.cs
Normal file
14
cis/ReactOS.CustomRevisionAction/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: AssemblyTitle("ReactOS Sin Custom Revision Action")]
|
||||
[assembly: AssemblyDescription("ReactOS Sin Custom Revision Action")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ReactOS Project")]
|
||||
[assembly: AssemblyProduct("React Operating System")]
|
||||
[assembly: AssemblyCopyright("Copyright 2005 ReactOS Project")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
20
cis/ReactOS.CustomRevisionAction/Default.build
Normal file
20
cis/ReactOS.CustomRevisionAction/Default.build
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
<project name="ReactOS.CustomRevisionAction" default="build">
|
||||
|
||||
<property name="output.dir" value="bin" />
|
||||
|
||||
<target name="build" description="Build component">
|
||||
<mkdir dir="${output.dir}" />
|
||||
<csc target="exe"
|
||||
output="${output.dir}\ReactOS.CustomRevisionAction.exe"
|
||||
optimize="true"
|
||||
debug="true"
|
||||
doc="${output.dir}\ReactOS.CustomRevisionAction.xml"
|
||||
warninglevel="0">
|
||||
<sources>
|
||||
<include name="*.cs" />
|
||||
</sources>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
</project>
|
254
cis/ReactOS.CustomRevisionAction/Main.cs
Normal file
254
cis/ReactOS.CustomRevisionAction/Main.cs
Normal file
|
@ -0,0 +1,254 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Configuration;
|
||||
using System.Web.Mail;
|
||||
|
||||
namespace ReactOS.CustomRevisionAction
|
||||
{
|
||||
public class MainClass
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to store published binaries at.
|
||||
/// </summary>
|
||||
private static string publishPath;
|
||||
|
||||
/// <summary>
|
||||
/// Run the application.
|
||||
/// </summary>
|
||||
/// <param name="script">Script to run.</param>
|
||||
/// <param name="args">Arguments to pass to script.</param>
|
||||
/// <param name="workingDirectory">Working directory.</param>
|
||||
/// <param name="standardOutput">Receives standard output.</param>
|
||||
/// <param name="standardError">Receives standard error.</param>
|
||||
/// <returns>
|
||||
/// Exit code.
|
||||
/// </returns>
|
||||
private static int RunScript(string script,
|
||||
string args,
|
||||
string workingDirectory,
|
||||
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;
|
||||
RedirectableProcess redirectableProcess = new RedirectableProcess(scriptProcessStartInfo);
|
||||
standardOutput = redirectableProcess.ProcessOutput;
|
||||
standardError = redirectableProcess.ProcessError;
|
||||
return redirectableProcess.ExitCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve value of configuration from configuration file.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of configuration option.</param>
|
||||
/// <param name="defaultValue">
|
||||
/// Default value to be returned if the option does not exist.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Value of configuration option or null if the option does not
|
||||
/// exist and no default value is provided.
|
||||
/// </returns>
|
||||
private static string GetConfigurationOption(string name,
|
||||
string defaultValue)
|
||||
{
|
||||
if (ConfigurationSettings.AppSettings[name] != null)
|
||||
return ConfigurationSettings.AppSettings[name];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an email.
|
||||
/// </summary>
|
||||
/// <param name="subject">Subject of the email.</param>
|
||||
/// <param name="body">Content of the email.</param>
|
||||
private static void SendErrorMail(string subject, string body)
|
||||
{
|
||||
try
|
||||
{
|
||||
string smtpServer = GetConfigurationOption("smtpServer", "localhost");
|
||||
string toEmail = GetConfigurationOption("errorEmail", null);
|
||||
if (toEmail == null)
|
||||
return;
|
||||
string fromEmail = GetConfigurationOption("fromEmail", null);
|
||||
if (fromEmail == null)
|
||||
fromEmail = toEmail;
|
||||
MailMessage mm = new MailMessage();
|
||||
mm.Priority = MailPriority.Normal;
|
||||
mm.From = toEmail;
|
||||
mm.To = toEmail;
|
||||
mm.Subject = subject;
|
||||
mm.Body += body;
|
||||
mm.Body += "<br>";
|
||||
mm.BodyFormat = MailFormat.Html;
|
||||
SmtpMail.SmtpServer = smtpServer;
|
||||
SmtpMail.Send(mm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fail with an error message.
|
||||
/// </summary>
|
||||
/// <param name="revision">Repository revision.</param>
|
||||
/// <param name="text">Error message.</param>
|
||||
private static void Fail(int revision,
|
||||
string text)
|
||||
{
|
||||
Console.WriteLine(text);
|
||||
Console.Error.WriteLine(text);
|
||||
SendErrorMail(String.Format("[{0}] ReactOS Publish Error", revision), text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fail with an error message.
|
||||
/// </summary>
|
||||
/// <param name="text">Error message.</param>
|
||||
private static void Fail(string text)
|
||||
{
|
||||
Console.WriteLine(text);
|
||||
Console.Error.WriteLine(text);
|
||||
SendErrorMail("ReactOS Publish Error", text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate filename of distribution.
|
||||
/// </summary>
|
||||
/// <param name="branch">Branch.</param>
|
||||
/// <param name="revision">Revision.</param>
|
||||
private static string GetDistributionFilename(string branch,
|
||||
int revision)
|
||||
{
|
||||
return String.Format("ReactOS-{0}-r{1}.iso",
|
||||
branch,
|
||||
revision);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy ISO to the destination.
|
||||
/// </summary>
|
||||
/// <param name="sourceFilename">Name of source ISO file to copy.</param>
|
||||
/// <param name="branch">Branch.</param>
|
||||
/// <param name="revision">Revision.</param>
|
||||
/// <remarks>
|
||||
/// Structure is <branch>\ReactOS-<branch>-r<revision>.iso.
|
||||
/// </remarks>
|
||||
private static void CopyISOToDestination(string sourceFilename,
|
||||
string branch,
|
||||
int revision)
|
||||
{
|
||||
string distributionFilename = GetDistributionFilename(branch,
|
||||
revision);
|
||||
string destinationDirectory = Path.Combine(publishPath,
|
||||
branch);
|
||||
string destinationFilename = Path.Combine(destinationDirectory,
|
||||
distributionFilename);
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
Directory.CreateDirectory(destinationDirectory);
|
||||
File.Copy(sourceFilename,
|
||||
destinationFilename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publish a revision of ReactOS.
|
||||
/// </summary>
|
||||
/// <param name="text">Error message.</param>
|
||||
private static int Publish(string branch,
|
||||
int revision,
|
||||
string workingDirectory)
|
||||
{
|
||||
string make = "mingw32-make";
|
||||
string makeParameters = GetConfigurationOption("makeParameters", "");
|
||||
string reactosDirectory = Path.Combine(workingDirectory,
|
||||
"reactos");
|
||||
Console.WriteLine(String.Format("ReactOS directory is {0}",
|
||||
reactosDirectory));
|
||||
string standardOutput;
|
||||
string standardError;
|
||||
int exitCode = RunScript(make,
|
||||
makeParameters + " bootcd",
|
||||
reactosDirectory,
|
||||
out standardOutput,
|
||||
out standardError);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
Fail(revision,
|
||||
String.Format("make bootcd failed: (error: {0}) {1}",
|
||||
standardError,
|
||||
standardOutput));
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
string sourceFilename = Path.Combine(reactosDirectory,
|
||||
"ReactOS.iso");
|
||||
if (File.Exists(sourceFilename))
|
||||
CopyISOToDestination(sourceFilename,
|
||||
branch,
|
||||
revision);
|
||||
else
|
||||
{
|
||||
Fail(revision,
|
||||
"make bootcd produced no ReactOS.iso");
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Program entry point.
|
||||
/// </summary>
|
||||
/// <param name="args">Arguments from command line.</param>
|
||||
/// <remarks>
|
||||
/// If exit code is 0, then the commit was processed successfully.
|
||||
/// If exit code is 1, then the commit was not processed successfully.
|
||||
/// </remarks>
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Environment.ExitCode = 1;
|
||||
|
||||
publishPath = ConfigurationSettings.AppSettings["publishPath"];
|
||||
if (publishPath == null)
|
||||
{
|
||||
Fail("PublishPath option not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Length < 3)
|
||||
{
|
||||
Fail("Usage: ReactOS.CustomRevisionAction action branch revision");
|
||||
return;
|
||||
}
|
||||
|
||||
string action = args[0]; /* bootcd */
|
||||
string branch = args[1];
|
||||
int revision = Int32.Parse(args[2]);
|
||||
|
||||
System.Environment.ExitCode = Publish(branch,
|
||||
revision,
|
||||
System.Environment.CurrentDirectory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Fail(String.Format("Exception: {0}", ex));
|
||||
System.Environment.ExitCode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
145
cis/ReactOS.CustomRevisionAction/RedirectableProcess.cs
Normal file
145
cis/ReactOS.CustomRevisionAction/RedirectableProcess.cs
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* When using the ProcessStartInfo.RedirectStandardXxx properties there is a chance of
|
||||
* the parent and child process blocking due to a race condition. This class handles the
|
||||
* problem.
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdiagnosticsprocessstartinfoclassredirectstandardoutputtopic.asp
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ReactOS.CustomRevisionAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Process that redirects standard output and standard error streams.
|
||||
/// </summary>
|
||||
public class RedirectableProcess
|
||||
{
|
||||
/// <summary>
|
||||
/// Process.
|
||||
/// </summary>
|
||||
private Process process;
|
||||
|
||||
/// <summary>
|
||||
/// Redirected standard error stream.
|
||||
/// </summary>
|
||||
private string processError;
|
||||
|
||||
/// <summary>
|
||||
/// Redirected standard output stream.
|
||||
/// </summary>
|
||||
private string processOutput;
|
||||
|
||||
/// <summary>
|
||||
/// Exit code.
|
||||
/// </summary>
|
||||
private int exitCode;
|
||||
|
||||
/// <summary>
|
||||
/// Redirected standard error stream.
|
||||
/// </summary>
|
||||
public string ProcessError
|
||||
{
|
||||
get
|
||||
{
|
||||
return processError;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redirected standard output stream.
|
||||
/// </summary>
|
||||
public string ProcessOutput
|
||||
{
|
||||
get
|
||||
{
|
||||
return processOutput;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit code.
|
||||
/// </summary>
|
||||
public int ExitCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run an excutable and redirect standard error and/or standard output safely.
|
||||
/// </summary>
|
||||
public RedirectableProcess(ProcessStartInfo processStartInfo)
|
||||
{
|
||||
Run(processStartInfo, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run an excutable and redirect standard error and/or standard output safely.
|
||||
/// </summary>
|
||||
public RedirectableProcess(ProcessStartInfo processStartInfo, string input)
|
||||
{
|
||||
Run(processStartInfo, input);
|
||||
}
|
||||
|
||||
private void Run(ProcessStartInfo processStartInfo, string input)
|
||||
{
|
||||
process = new Process();
|
||||
process.StartInfo = processStartInfo;
|
||||
process.Start();
|
||||
if (processStartInfo.RedirectStandardInput && input != null)
|
||||
{
|
||||
process.StandardInput.AutoFlush = true;
|
||||
process.StandardInput.WriteLine(input);
|
||||
}
|
||||
Thread readStandardError = null;
|
||||
if (processStartInfo.RedirectStandardError)
|
||||
{
|
||||
readStandardError = new Thread(new ThreadStart(ReadStandardError));
|
||||
readStandardError.Start();
|
||||
}
|
||||
Thread readStandardOutput = null;
|
||||
if (processStartInfo.RedirectStandardOutput)
|
||||
{
|
||||
readStandardOutput = new Thread(new ThreadStart(ReadStandardOutput));
|
||||
readStandardOutput.Start();
|
||||
}
|
||||
if (processStartInfo.RedirectStandardError)
|
||||
{
|
||||
readStandardError.Join();
|
||||
}
|
||||
if (processStartInfo.RedirectStandardOutput)
|
||||
{
|
||||
readStandardOutput.Join();
|
||||
}
|
||||
process.WaitForExit();
|
||||
exitCode = process.ExitCode;
|
||||
process = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read standard error thread entry-point.
|
||||
/// </summary>
|
||||
private void ReadStandardError()
|
||||
{
|
||||
if (process != null)
|
||||
{
|
||||
processError = process.StandardError.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read standard output thread entry-point.
|
||||
/// </summary>
|
||||
private void ReadStandardOutput()
|
||||
{
|
||||
if (process != null)
|
||||
{
|
||||
processOutput = process.StandardOutput.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue