Skip to content

Instantly share code, notes, and snippets.

@theor
Last active June 29, 2016 16:55
Show Gist options
  • Save theor/20ecaf85adfba4a4732626245c508065 to your computer and use it in GitHub Desktop.
Save theor/20ecaf85adfba4a4732626245c508065 to your computer and use it in GitHub Desktop.
@ECHO OFF
REM echo %~dp0
csc %~dp0\Biisect.cs /out:%~dp0\Biisect.exe
REM echo %ERRORLEVEL%
IF NOT ERRORLEVEL 1 %~dp0\Biisect.exe %*
// biisect - hg bisect helper
// compile: csc
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Biisect")]
[assembly: AssemblyProduct("Biisect")]
[assembly: AssemblyCopyright("theor")]
[assembly: Guid("220188f3-4b4f-454a-bf86-ecf0eb8c74d5")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
namespace UBisect
{
class Program
{
const string Usage = @"Usage: {0} [-w] [-i] COMMAND
-i interactive mode - prompt for success instead of checking return code
-w wait for exit
example: {0} -i ""build.bat && app.exe""";
class Options
{
public bool Interactive;
public bool WaitForExit;
public string Command;
}
static void WriteLine(ConsoleColor color, string format, params object[] args)
{
Console.ForegroundColor = color;
Console.WriteLine(format, args);
Console.ResetColor();
}
static int Main(string[] aargs)
{
List<string> args = aargs.ToList();
Options opt;
if (!ParseOpts(args, out opt))
return 0;
bool success;
bool done = false;
do
{
Process p = ExecCommand(args);
if (opt.Interactive)
{
if(opt.WaitForExit)
{
WriteLine(ConsoleColor.Red, "Waiting for exit...");
p.WaitForExit();
WriteLine(p.ExitCode == 0 ? ConsoleColor.Green : ConsoleColor.Red, "\tExit code: {0}", p.ExitCode);
}
WriteLine(ConsoleColor.Blue, "Success ? (y)es, (n)o, (r)etry");
var readLine = Console.ReadLine().ToLowerInvariant();
switch (readLine)
{
case "y":
case "yes":
case "n":
case "no":
done = true;
break;
}
success = readLine[0] == 'y';
}
else
{
done = true;
p.WaitForExit();
success = p.ExitCode == 0;
}
} while (!done);
return success ? 0 : 1;
}
private static Process ExecCommand(List<string> args)
{
WriteLine(ConsoleColor.Blue, "Bisect '{0}'", String.Join(" ", args.ToArray()));
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", string.Format("/c \"{0}\"", string.Join(" ", args)))
{
UseShellExecute = false
};
Process p = Process.Start(psi);
return p;
}
private static bool ParseOpts(List<string> args, out Options opt)
{
opt = new Options();
string usage = String.Format(Usage, Assembly.GetEntryAssembly().GetName().Name);
for (int index = 0; index < args.Count; index++)
{
string arg = args[index];
switch (arg)
{
case "-h":
case "/?":
case "--help":
Console.WriteLine(usage);
return false;
case "-i":
case "/i":
opt.Interactive = true;
args.RemoveAt(index--);
break;
case "-w":
case "/w":
opt.WaitForExit = true;
args.RemoveAt(index--);
break;
default:
if (opt.Command != null)
{
Console.WriteLine("Error: multiple commands specified:\n\t{0}\n\t{1}", opt.Command, arg);
Console.WriteLine(usage);
return false;
}
opt.Command = arg;
break;
}
}
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment