ln.build/ln.build/CommandRunner.cs

127 lines
4.5 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using ln.logging;
namespace ln.build
{
public enum CRThrow { NEVER, NEGATIVE, NONZERO }
public class CommandRunner
{
public static CRThrow DefaultThrow { get; set; } = CRThrow.NONZERO;
public CRThrow Throw { get; set; } = DefaultThrow;
public string Executable { get; }
public string[] Arguments { get; set; }
public string WorkingDirectory { get; set; } = ".";
public Logger Logger { get; }
public CommandRunner(string executable,params string[] arguments) : this(Logger.Default, executable, arguments){}
public CommandRunner(Logger logger, string executable,params string[] arguments)
{
Logger = logger;
Executable = executable;
Arguments = arguments;
}
public string FindFileInPath(string filename)
{
Logger.Log(LogLevel.DEBUG, "Looking up {0} in paths {1}", filename, Environment.GetEnvironmentVariable("PATH"));
foreach (string path in Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator))
{
string fullpath = Path.Combine(path,filename);
if (File.Exists(fullpath))
return fullpath;
}
return filename;
}
public int Run() => Run(Logger, null, null);
public int Run(Stream stdout, Stream stderr) => Run(Logger, stdout, stderr);
public int Run(Logger logger, Stream stdout) => Run(logger, stdout, stdout);
public int Run(Logger logger, Stream stdout, Stream stderr)
{
ProcessStartInfo psi = new ProcessStartInfo(FindFileInPath(Executable), string.Join(' ', Arguments))
{
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
WorkingDirectory = this.WorkingDirectory
};
psi.EnvironmentVariables.Remove("LANG");
logger.Log(LogLevel.INFO, "Executing: {0} {1}", psi.FileName, psi.Arguments);
Process process = Process.Start(psi);
process.WaitForExit();
if (stdout != null)
process.StandardOutput.BaseStream.CopyTo(stdout);
if (stderr != null)
process.StandardError.BaseStream.CopyTo(stderr);
logger.Log(LogLevel.INFO, "Result: {0}", process.ExitCode);
if (
((Throw == CRThrow.NEGATIVE) && (process.ExitCode < 0)) ||
((Throw == CRThrow.NONZERO) && (process.ExitCode != 0))
)
throw new Exception(String.Format("{0} execution gave result {1}", psi.FileName, process.ExitCode));
return process.ExitCode;
}
public int Run(out string stdout,out string stderr) => Run(Logger, out stdout, out stderr);
public int Run(Logger logger, out string stdout,out string stderr)
{
MemoryStream outstream,errstream;
outstream = new MemoryStream();
errstream = new MemoryStream();
int status = Run(logger, outstream, errstream);
using (StreamReader sr = new StreamReader(outstream))
stdout = sr.ReadToEnd();
using (StreamReader sr = new StreamReader(errstream))
stderr = sr.ReadToEnd();
return status;
}
/*
public static int Run(string executable,out Stream stdout,out Stream stderr,params string[] arguments)
{
CommandRunner runner = new CommandRunner(executable,arguments);
return runner.Run(out stdout,out stderr);
}
public static int Run(string executable,out string stdout,out string stderr,params string[] arguments) => Run(Logger.Default, executable, out stdout, out stderr, arguments);
public static int Run(Logger logger, string executable, out string stdout, out string stderr, params string[] arguments)
{
CommandRunner runner = new CommandRunner(logger, executable, arguments);
int result = runner.Run(out stdout, out stderr);
return result;
}
public static int Run(string executable,params string[] arguments) => Run(executable,out Stream stdout,out Stream stderr,arguments);
public static int Run(Logger logger, string executable, params string[] arguments){
return Run(executable,out Stream stdout,out Stream stderr,arguments);
}
*/
}
}