Last active
September 9, 2019 02:09
-
-
Save codewings/4c2097c6555cbb26691a6877efa19f12 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Text.RegularExpressions; | |
namespace P4 | |
{ | |
class P4OutputStream : IDisposable | |
{ | |
public StreamReader Reader { get; set; } | |
public StreamWriter Writer { get; set; } | |
public bool Empty | |
{ | |
get { Writer.Flush(); return Stream.Length == 0; } | |
} | |
public P4OutputStream() | |
{ | |
Stream = new MemoryStream(); | |
Reader = new StreamReader(Stream); | |
Writer = new StreamWriter(Stream); | |
} | |
public void ReceiveOutput(object sender, DataReceivedEventArgs e) | |
{ | |
if (e.Data != null) | |
{ | |
Writer.WriteLine(e.Data); | |
} | |
} | |
public StreamReader BeginRead() | |
{ | |
Writer.Flush(); | |
Stream.Position = 0; | |
return Reader; | |
} | |
public void Dispose() | |
{ | |
Writer.Close(); | |
Reader.Close(); | |
Stream.Dispose(); | |
Writer.Dispose(); | |
Reader.Dispose(); | |
} | |
MemoryStream Stream; | |
} | |
class P4Command | |
{ | |
public delegate T CommandAction<T>(StreamReader stream); | |
public delegate void LogAction(string log); | |
public static string P4PORT = string.Empty; | |
public static string P4USER = string.Empty; | |
public static string P4CLIENT = string.Empty; | |
public static LogAction P4LOG = line => Console.WriteLine(line); | |
public static bool LogP4CMD = false; | |
public static bool Configured | |
{ | |
get | |
{ | |
return string.IsNullOrEmpty(P4PORT) == false && string.IsNullOrEmpty(P4USER) == false && string.IsNullOrEmpty(P4CLIENT) == false; | |
} | |
} | |
static void RunProcess(string args, P4OutputStream stdout, string[] stdin = null) | |
{ | |
var stderr = new P4OutputStream(); | |
{ | |
var pi = new ProcessStartInfo(); | |
pi.FileName = "p4.exe"; | |
pi.Arguments = string.Format("-p {0} -u {1} -c {2} {3}", P4PORT, P4USER, P4CLIENT, args); | |
pi.UseShellExecute = false; | |
pi.RedirectStandardOutput = true; | |
pi.RedirectStandardError = true; | |
pi.RedirectStandardInput = stdin != null; | |
if (LogP4CMD) | |
{ | |
P4LOG("p4 " + pi.Arguments); | |
} | |
var p = new Process(); | |
p.StartInfo = pi; | |
p.OutputDataReceived += stdout.ReceiveOutput; | |
p.ErrorDataReceived += stderr.ReceiveOutput; | |
p.Start(); | |
if (stdin != null) | |
{ | |
foreach (var str in stdin) | |
{ | |
p.StandardInput.WriteLine(str); | |
} | |
p.StandardInput.WriteLine("\u001A"); | |
} | |
p.BeginOutputReadLine(); | |
p.BeginErrorReadLine(); | |
p.WaitForExit(); | |
p.Dispose(); | |
if (stderr.Empty == false) | |
{ | |
P4LOG(stderr.BeginRead().ReadToEnd()); | |
} | |
} | |
stderr.Dispose(); | |
} | |
static int NullOutput(StreamReader stream) | |
{ | |
stream.ReadToEnd(); | |
return 0; | |
} | |
public static int GenericOutput(StreamReader stream) | |
{ | |
P4LOG(stream.ReadToEnd()); | |
return 0; | |
} | |
public static T Run<T>(string args, CommandAction<T> action, string[] inputs, LogAction log) | |
{ | |
Debug.Assert(Configured == true); | |
var old = P4LOG; | |
T result = default(T); | |
if (log != null) P4LOG = log; | |
{ | |
try | |
{ | |
var stdout = new P4OutputStream(); | |
{ | |
RunProcess(args, stdout, inputs); | |
} | |
result = action.Invoke(stdout.BeginRead()); | |
stdout.Dispose(); | |
} | |
catch (Exception ex) | |
{ | |
P4LOG(ex.Message); | |
} | |
} | |
if (log != null) P4LOG = old; | |
return result; | |
} | |
public static void Run(string args, string[] inputs, LogAction log = null) | |
{ | |
Run(args, NullOutput, inputs, log); | |
} | |
public static void Run(string args, LogAction log = null) | |
{ | |
Run(args, NullOutput, null, log); | |
} | |
public static T Run<T>(string args, CommandAction<T> action, LogAction log = null) | |
{ | |
return Run(args, action, null, log); | |
} | |
#region Shortcuts for common p4 command | |
public static string NewCL(string desc, LogAction log = null) | |
{ | |
string[] str = new string[] | |
{ | |
"Description:\n\t" + desc, | |
"Change: new" | |
}; | |
return Run("change -i", stream => | |
{ | |
var line = stream.ReadToEnd(); | |
var m = Regex.Match(line, @"\d+"); | |
return m.Success ? m.Value : string.Empty; | |
} | |
, str, log); | |
} | |
public static void SafeResolveCL(string changlist, LogAction log = null) | |
{ | |
Run(string.Format("resolve -as -c {0}", changlist), stream => | |
{ | |
while (stream.EndOfStream == false) | |
{ | |
P4LOG(stream.ReadLine()); | |
} | |
return 0; | |
}, log); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment