Skip to content

Commit

Permalink
Added process output&timeout, fixed codegen issue
Browse files Browse the repository at this point in the history
  • Loading branch information
devlead committed Feb 16, 2015
1 parent baf5781 commit 1bc3113
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 24 deletions.
54 changes: 53 additions & 1 deletion src/Cake.Common/ProcessAliases.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Cake.Core;
using Cake.Core.Annotations;
using Cake.Core.IO;
Expand Down Expand Up @@ -46,6 +48,37 @@ public static int StartProcess(this ICakeContext context, FilePath fileName)
/// </example>
[CakeMethodAlias]
public static int StartProcess(this ICakeContext context, FilePath fileName, ProcessSettings settings)
{
IEnumerable<string> redirectedOutput;
return StartProcess(context, fileName, settings, out redirectedOutput);
}

/// <summary>
/// Starts the process resource that is specified by the filename and settings.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="fileName">Name of the file.</param>
/// <param name="settings">The settings.</param>
/// <param name="redirectedOutput">outputs process output <see cref="ProcessSettings.RedirectStandardOutput">RedirectStandardOutput</see> is true</param>
/// <returns>The exit code that the started process specified when it terminated.</returns>
/// <example>
/// <code>
/// IEnumerable&lt;string&gt; redirectedOutput;
/// var exitCodeWithArgument = StartProcess("ping", new ProcessSettings{
/// Arguments = "localhost",
/// RedirectStandardOutput = true
/// },
/// out redirectedOutput
/// );
/// //Output last line of process output
/// Information("Last line of output: {0}", redirectedOutput.LastOrDefault());
///
/// // This should output 0 as valid arguments supplied
/// Information("Exit code: {0}", exitCodeWithArgument);
/// </code>
/// </example>
[CakeMethodAlias]
public static int StartProcess(this ICakeContext context, FilePath fileName, ProcessSettings settings, out IEnumerable<string> redirectedOutput)
{
if (context == null)
{
Expand All @@ -72,8 +105,27 @@ public static int StartProcess(this ICakeContext context, FilePath fileName, Pro
}

// Wait for the process to stop.
process.WaitForExit();
if (settings.Timeout.HasValue)
{
if (!process.WaitForExit(settings.Timeout.Value))
{
throw new TimeoutException(
string.Format(
CultureInfo.InvariantCulture,
"Process TimeOut ({0}): {1}",
settings.Timeout.Value,
fileName));
}
}
else
{
process.WaitForExit();
}

redirectedOutput = settings.RedirectStandardOutput
? process.GetStandardOutput()
: null;

// Return the exit code.
return process.GetExitCode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void Should_Return_Correctly_Generated_Wrapper_For_Non_Generic_Type_With_
{
const string expected = "public void NonGeneric_ExtensionMethodWithParameter(System.Int32 value){" +
"Cake.Core.Tests.Fixtures.MethodAliasGeneratorFixture.NonGeneric_ExtensionMethodWithParameter" +
"(GetContext(),value);}";
"(GetContext(), value);}";

var method = typeof(MethodAliasGeneratorFixture).GetMethod("NonGeneric_ExtensionMethodWithParameter");

Expand All @@ -101,7 +101,7 @@ public void Should_Return_Correctly_Generated_Wrapper_For_Non_Generic_Type_With_
{
const string expected = "public void NonGeneric_ExtensionMethodWithGenericParameter(System.Action<System.Int32> value){" +
"Cake.Core.Tests.Fixtures.MethodAliasGeneratorFixture.NonGeneric_ExtensionMethodWithGenericParameter" +
"(GetContext(),value);}";
"(GetContext(), value);}";

var method = typeof(MethodAliasGeneratorFixture).GetMethod("NonGeneric_ExtensionMethodWithGenericParameter");

Expand Down Expand Up @@ -149,7 +149,7 @@ public void Should_Return_Correctly_Generated_Wrapper_For_Generic_Type_With_Argu
{
const string expected = "public void Generic_ExtensionMethodWithParameter<TTest>(TTest value){" +
"Cake.Core.Tests.Fixtures.MethodAliasGeneratorFixture.Generic_ExtensionMethodWithParameter<TTest>" +
"(GetContext(),value);}";
"(GetContext(), value);}";

var method = typeof(MethodAliasGeneratorFixture).GetMethods().SingleOrDefault(x => x.Name == "Generic_ExtensionMethodWithParameter");

Expand All @@ -165,7 +165,7 @@ public void Should_Return_Correctly_Generated_Wrapper_For_Generic_Type_With_Gene
{
const string expected = "public TTest Generic_ExtensionMethodWithGenericReturnValue<TTest>(TTest value){" +
"return Cake.Core.Tests.Fixtures.MethodAliasGeneratorFixture.Generic_ExtensionMethodWithGenericReturnValue<TTest>" +
"(GetContext(),value);}";
"(GetContext(), value);}";

var method = typeof(MethodAliasGeneratorFixture).GetMethods().SingleOrDefault(x => x.Name == "Generic_ExtensionMethodWithGenericReturnValue");

Expand All @@ -181,7 +181,7 @@ public void Should_Return_Correctly_Generated_Wrapper_For_Non_Generic_Type_With_
{
const string expected = "public void NonGeneric_ExtensionMethodWithParameterArray(params System.Int32[] values){" +
"Cake.Core.Tests.Fixtures.MethodAliasGeneratorFixture.NonGeneric_ExtensionMethodWithParameterArray" +
"(GetContext(),values);}";
"(GetContext(), values);}";

var method = typeof(MethodAliasGeneratorFixture).GetMethod("NonGeneric_ExtensionMethodWithParameterArray");

Expand Down
13 changes: 11 additions & 2 deletions src/Cake.Core/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ public static string GetFullName(this Type type, bool includeNamespace = true)
{
return type.Name;
}
return type.IsGenericType
? GetGenericTypeName(type, includeNamespace)
Type genericType;
return type.IsGenericType(out genericType)
? GetGenericTypeName(genericType, includeNamespace)
: includeNamespace ? type.FullName : type.Name;
}

Expand All @@ -60,6 +61,14 @@ private static string GetGenericTypeName(this Type type, bool includeNamespace)
return builder.ToString();
}

private static bool IsGenericType(this Type type, out Type genericType)
{
genericType = type.IsByRef
? (type.GetElementType() ?? type)
: type;
return genericType.IsGenericType;
}

private static string GetGenericTypeArguments(this Type type, bool includeNamespace)
{
var genericArguments = new List<string>();
Expand Down
7 changes: 7 additions & 0 deletions src/Cake.Core/IO/IProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ public interface IProcess
/// </summary>
void WaitForExit();

/// <summary>
/// Waits for the process to exit with possible timeout for command.
/// </summary>
/// <param name="milliseconds">The amount of time, in milliseconds, to wait for the associated process to exit. The maximum is the largest possible value of a 32-bit integer, which represents infinity to the operating system.</param>
/// <returns>true if the associated process has exited; otherwise, false.</returns>
bool WaitForExit(int milliseconds);

/// <summary>
/// Gets the exit code of the process.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Cake.Core/IO/ProcessSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ public sealed class ProcessSettings
/// </summary>
/// <value>true if output should be written to <see cref="P:System.Diagnostics.Process.StandardOutput"/>; otherwise, false. The default is false.</value>
public bool RedirectStandardOutput { get; set; }

/// <summary>
/// Gets or sets optional timeout for process execution
/// </summary>
public int? Timeout { get; set; }
}
}
14 changes: 14 additions & 0 deletions src/Cake.Core/IO/ProcessWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ public void WaitForExit()
_process.WaitForExit();
}

public bool WaitForExit(int milliseconds)
{
if (_process.WaitForExit(milliseconds))
{
return true;
}
_process.Refresh();
if (!_process.HasExited)
{
_process.Kill();
}
return false;
}

public int GetExitCode()
{
return _process.ExitCode;
Expand Down
50 changes: 34 additions & 16 deletions src/Cake.Core/Scripting/CodeGen/MethodAliasGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private static string GenerateCode(MethodInfo method)
}

builder.Append("(");
builder.Append(GetProxyParameters(parameters));
builder.Append(string.Concat(GetProxyParameters(parameters, true)));
builder.Append(")");
builder.Append("{");

Expand All @@ -86,7 +86,7 @@ private static string GenerateCode(MethodInfo method)
}

builder.Append("(");
builder.Append(GetCallArguments(parameters));
builder.Append(string.Concat(GetProxyParameters(parameters, false)));
builder.Append(");");

// End method.
Expand All @@ -102,24 +102,42 @@ private static string GetReturnType(MethodInfo method)
: method.ReturnType.GetFullName();
}

private static string GetProxyParameters(IEnumerable<ParameterInfo> parameters)
private static IEnumerable<string> GetProxyParameters(IEnumerable<ParameterInfo> parameters, bool includeType)
{
var result = new List<string>();
var first = includeType;
if (!includeType)
{
yield return "GetContext()";
}
foreach (var parameter in parameters)
{
var isParameterArray = parameter.IsDefined(typeof(ParamArrayAttribute));
var typeName = parameter.ParameterType.GetFullName();
var typeDeclaration = isParameterArray ? string.Concat("params ", typeName) : typeName;
result.Add(string.Concat(typeDeclaration, " ", parameter.Name));
if (first)
{
first = false;
}
else
{
yield return ", ";
}
if (parameter.IsOut)
{
yield return "out ";
}
else if (parameter.ParameterType.IsByRef)
{
yield return "ref ";
}
if (includeType)
{
if (parameter.IsDefined(typeof(ParamArrayAttribute)))
{
yield return "params ";
}
yield return parameter.ParameterType.GetFullName();
yield return " ";
}
yield return parameter.Name;
}
return string.Join(",", result);
}

private static string GetCallArguments(IEnumerable<ParameterInfo> parameters)
{
var result = new List<string> { "GetContext()" };
result.AddRange(parameters.Select(x => x.Name));
return string.Join(",", result);
}

private static void BuildGenericArguments(MethodInfo method, StringBuilder builder)
Expand Down

0 comments on commit 1bc3113

Please sign in to comment.