mirror of
https://github.com/reactos/reactos.git
synced 2025-06-26 21:19:45 +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…
Add table
Add a link
Reference in a new issue