mirror of
https://github.com/actions/runner.git
synced 2025-12-10 12:36:23 +00:00
c
This commit is contained in:
committed by
TingluoHuang
parent
b37aa3254f
commit
3ea3b5ff59
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines
|
||||
{
|
||||
[DataContract]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public sealed class ConditionResult
|
||||
{
|
||||
[DataMember]
|
||||
public Boolean Value
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Trace
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,26 +146,6 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
/// </summary>
|
||||
internal Boolean IsLiteral => String.IsNullOrEmpty(m_expression);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the referenced value from the provided execution context.
|
||||
/// </summary>
|
||||
/// <param name="context">The execution context used for variable resolution</param>
|
||||
/// <returns>The value of the variable if found; otherwise, null</returns>
|
||||
public ExpressionResult<T> GetValue(IPipelineContext context = null)
|
||||
{
|
||||
if (this.IsLiteral)
|
||||
{
|
||||
return new ExpressionResult<T>(m_literalValue, containsSecrets: false);
|
||||
}
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
return context.Evaluate<T>(m_expression);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the value to a string representation.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using GitHub.DistributedTask.Expressions2;
|
||||
using GitHub.DistributedTask.Logging;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the environment and services available during build and execution of a pipeline.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface IPipelineContext
|
||||
{
|
||||
DictionaryContextData Data { get; }
|
||||
|
||||
Int32 EnvironmentVersion { get; }
|
||||
|
||||
EvaluationOptions ExpressionOptions { get; }
|
||||
|
||||
ISecretMasker SecretMasker { get; }
|
||||
|
||||
IPipelineTraceWriter Trace { get; }
|
||||
|
||||
ISet<String> SystemVariableNames { get; }
|
||||
|
||||
IDictionary<String, VariableValue> Variables { get; }
|
||||
|
||||
String ExpandVariables(String value, Boolean maskSecrets = false);
|
||||
|
||||
ExpressionResult<T> Evaluate<T>(String expression);
|
||||
|
||||
ExpressionResult<JObject> Evaluate(JObject value);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface IPipelineTraceWriter : ITraceWriter
|
||||
{
|
||||
void EnterProperty(String name);
|
||||
void LeaveProperty(String name);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface IFileProvider
|
||||
{
|
||||
String GetFileContent(String path);
|
||||
|
||||
String ResolvePath(String defaultRoot, String path);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
internal sealed class JobDisplayNameBuilder
|
||||
{
|
||||
public JobDisplayNameBuilder(String jobFactoryDisplayName)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(jobFactoryDisplayName))
|
||||
{
|
||||
m_jobFactoryDisplayName = jobFactoryDisplayName;
|
||||
m_segments = new List<String>();
|
||||
}
|
||||
}
|
||||
|
||||
public void AppendSegment(String value)
|
||||
{
|
||||
if (String.IsNullOrEmpty(value) || m_segments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_segments.Add(value);
|
||||
}
|
||||
|
||||
public String Build()
|
||||
{
|
||||
if (String.IsNullOrEmpty(m_jobFactoryDisplayName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var displayName = default(String);
|
||||
if (m_segments.Count == 0)
|
||||
{
|
||||
displayName = m_jobFactoryDisplayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var joinedSegments = String.Join(", ", m_segments);
|
||||
displayName = String.Format(CultureInfo.InvariantCulture, "{0} ({1})", m_jobFactoryDisplayName, joinedSegments);
|
||||
}
|
||||
|
||||
const Int32 maxDisplayNameLength = 100;
|
||||
if (displayName.Length > maxDisplayNameLength)
|
||||
{
|
||||
displayName = displayName.Substring(0, maxDisplayNameLength - 3) + "...";
|
||||
}
|
||||
|
||||
m_segments.Clear();
|
||||
return displayName;
|
||||
}
|
||||
|
||||
private readonly String m_jobFactoryDisplayName;
|
||||
private readonly List<String> m_segments;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public sealed class ParseOptions
|
||||
{
|
||||
public ParseOptions()
|
||||
{
|
||||
}
|
||||
|
||||
internal ParseOptions(ParseOptions copy)
|
||||
{
|
||||
MaxFiles = copy.MaxFiles;
|
||||
MaxFileSize = copy.MaxFileSize;
|
||||
MaxResultSize = copy.MaxResultSize;
|
||||
}
|
||||
|
||||
public Int32 MaxDepth => 50;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum error message length before the message will be truncated.
|
||||
/// </summary>
|
||||
public Int32 MaxErrorMessageLength => 500;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum number of errors that can be recorded when parsing a pipeline.
|
||||
/// </summary>
|
||||
public Int32 MaxErrors => 10;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of files that can be loaded when parsing a pipeline. Zero or less is treated as infinite.
|
||||
/// </summary>
|
||||
public Int32 MaxFiles { get; set; } = 50;
|
||||
|
||||
public Int32 MaxFileSize { get; set; } = 1024 * 1024; // 1 mb
|
||||
|
||||
public Int32 MaxParseEvents => 1000000; // 1 million
|
||||
|
||||
public Int32 MaxResultSize { get; set; } = 10 * 1024 * 1024; // 10 mb
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using GitHub.DistributedTask.ObjectTemplating;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
internal sealed class ParseResult
|
||||
{
|
||||
public TemplateContext Context { get; set; }
|
||||
|
||||
public TemplateToken Value { get; set; }
|
||||
|
||||
public String ToYaml()
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Serialize
|
||||
using (var stringWriter = new StringWriter())
|
||||
{
|
||||
TemplateWriter.Write(new YamlObjectWriter(stringWriter), Value);
|
||||
stringWriter.Flush();
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,52 +16,6 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
internal static class PipelineTemplateConverter
|
||||
{
|
||||
internal static String ConvertToJobDisplayName(
|
||||
TemplateContext context,
|
||||
TemplateToken displayName,
|
||||
Boolean allowExpressions = false)
|
||||
{
|
||||
var result = default(String);
|
||||
|
||||
// Expression
|
||||
if (allowExpressions && displayName is ExpressionToken)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// String
|
||||
var displayNameString = displayName.AssertString($"job {PipelineTemplateConstants.Name}");
|
||||
result = displayNameString.Value;
|
||||
return result;
|
||||
}
|
||||
internal static Int32? ConvertToJobTimeout(
|
||||
TemplateContext context,
|
||||
TemplateToken token,
|
||||
Boolean allowExpressions = false)
|
||||
{
|
||||
if (allowExpressions && token is ExpressionToken)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var numberToken = token.AssertNumber($"job {PipelineTemplateConstants.TimeoutMinutes}");
|
||||
return (Int32)numberToken.Value;
|
||||
}
|
||||
|
||||
internal static Int32? ConvertToJobCancelTimeout(
|
||||
TemplateContext context,
|
||||
TemplateToken token,
|
||||
Boolean allowExpressions = false)
|
||||
{
|
||||
if (allowExpressions && token is ExpressionToken)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var numberToken = token.AssertNumber($"job {PipelineTemplateConstants.CancelTimeoutMinutes}");
|
||||
return (Int32)numberToken.Value;
|
||||
}
|
||||
|
||||
internal static Boolean? ConvertToStepContinueOnError(
|
||||
TemplateContext context,
|
||||
TemplateToken token,
|
||||
@@ -291,74 +245,5 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<ContextScope> ConvertToScopes(
|
||||
TemplateContext context,
|
||||
TemplateToken scopes)
|
||||
{
|
||||
var scopesSequence = scopes.AssertSequence($"job {PipelineTemplateConstants.Scopes}");
|
||||
|
||||
foreach (var scopesItem in scopesSequence)
|
||||
{
|
||||
var result = new ContextScope();
|
||||
var scope = scopesItem.AssertMapping($"{PipelineTemplateConstants.Scopes} item");
|
||||
|
||||
foreach (var scopeProperty in scope)
|
||||
{
|
||||
var propertyName = scopeProperty.Key.AssertString($"{PipelineTemplateConstants.Scopes} item key");
|
||||
|
||||
switch (propertyName.Value)
|
||||
{
|
||||
case PipelineTemplateConstants.Name:
|
||||
var nameLiteral = scopeProperty.Value.AssertString($"{PipelineTemplateConstants.Scopes} item {PipelineTemplateConstants.Name}");
|
||||
result.Name = nameLiteral.Value;
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Inputs:
|
||||
result.Inputs = scopeProperty.Value.AssertMapping($"{PipelineTemplateConstants.Scopes} item {PipelineTemplateConstants.Inputs}");
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Outputs:
|
||||
result.Outputs = scopeProperty.Value.AssertMapping($"{PipelineTemplateConstants.Scopes} item {PipelineTemplateConstants.Outputs}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly INamedValueInfo[] s_jobIfNamedValues = new INamedValueInfo[]
|
||||
{
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.GitHub),
|
||||
};
|
||||
private static readonly INamedValueInfo[] s_stepNamedValues = new INamedValueInfo[]
|
||||
{
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Strategy),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Matrix),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Steps),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.GitHub),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Job),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Runner),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Env),
|
||||
};
|
||||
private static readonly INamedValueInfo[] s_stepInTemplateNamedValues = new INamedValueInfo[]
|
||||
{
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Strategy),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Matrix),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Steps),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Inputs),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.GitHub),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Job),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Runner),
|
||||
new NamedValueInfo<NoOperationNamedValue>(PipelineTemplateConstants.Env),
|
||||
};
|
||||
private static readonly IFunctionInfo[] s_stepConditionFunctions = new IFunctionInfo[]
|
||||
{
|
||||
new FunctionInfo<NoOperation>(PipelineTemplateConstants.Always, 0, 0),
|
||||
new FunctionInfo<NoOperation>(PipelineTemplateConstants.Cancelled, 0, 0),
|
||||
new FunctionInfo<NoOperation>(PipelineTemplateConstants.Failure, 0, 0),
|
||||
new FunctionInfo<NoOperation>(PipelineTemplateConstants.Success, 0, 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,85 +46,6 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
|
||||
public Int32 MaxResultSize { get; set; } = 10 * 1024 * 1024; // 10 mb
|
||||
|
||||
public String EvaluateJobDisplayName(
|
||||
TemplateToken token,
|
||||
DictionaryContextData contextData,
|
||||
String defaultDisplayName)
|
||||
{
|
||||
var result = default(String);
|
||||
|
||||
if (token != null && token.Type != TokenType.Null)
|
||||
{
|
||||
var context = CreateContext(contextData);
|
||||
try
|
||||
{
|
||||
token = TemplateEvaluator.Evaluate(context, PipelineTemplateConstants.StringStrategyContext, token, 0, null, omitHeader: true);
|
||||
context.Errors.Check();
|
||||
result = PipelineTemplateConverter.ConvertToJobDisplayName(context, token);
|
||||
}
|
||||
catch (Exception ex) when (!(ex is TemplateValidationException))
|
||||
{
|
||||
context.Errors.Add(ex);
|
||||
}
|
||||
|
||||
context.Errors.Check();
|
||||
}
|
||||
|
||||
return !String.IsNullOrEmpty(result) ? result : defaultDisplayName;
|
||||
}
|
||||
|
||||
public Int32 EvaluateJobTimeout(
|
||||
TemplateToken token,
|
||||
DictionaryContextData contextData)
|
||||
{
|
||||
var result = default(Int32?);
|
||||
|
||||
if (token != null && token.Type != TokenType.Null)
|
||||
{
|
||||
var context = CreateContext(contextData);
|
||||
try
|
||||
{
|
||||
token = TemplateEvaluator.Evaluate(context, PipelineTemplateConstants.NumberStrategyContext, token, 0, null, omitHeader: true);
|
||||
context.Errors.Check();
|
||||
result = PipelineTemplateConverter.ConvertToJobTimeout(context, token);
|
||||
}
|
||||
catch (Exception ex) when (!(ex is TemplateValidationException))
|
||||
{
|
||||
context.Errors.Add(ex);
|
||||
}
|
||||
|
||||
context.Errors.Check();
|
||||
}
|
||||
|
||||
return result ?? PipelineConstants.DefaultJobTimeoutInMinutes;
|
||||
}
|
||||
|
||||
public Int32 EvaluateJobCancelTimeout(
|
||||
TemplateToken token,
|
||||
DictionaryContextData contextData)
|
||||
{
|
||||
var result = default(Int32?);
|
||||
|
||||
if (token != null && token.Type != TokenType.Null)
|
||||
{
|
||||
var context = CreateContext(contextData);
|
||||
try
|
||||
{
|
||||
token = TemplateEvaluator.Evaluate(context, PipelineTemplateConstants.NumberStrategyContext, token, 0, null, omitHeader: true);
|
||||
context.Errors.Check();
|
||||
result = PipelineTemplateConverter.ConvertToJobCancelTimeout(context, token);
|
||||
}
|
||||
catch (Exception ex) when (!(ex is TemplateValidationException))
|
||||
{
|
||||
context.Errors.Add(ex);
|
||||
}
|
||||
|
||||
context.Errors.Check();
|
||||
}
|
||||
|
||||
return result ?? PipelineConstants.DefaultJobCancelTimeoutInMinutes;
|
||||
}
|
||||
|
||||
public DictionaryContextData EvaluateStepScopeInputs(
|
||||
TemplateToken token,
|
||||
DictionaryContextData contextData)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
public static class TaskResultExtensions
|
||||
{
|
||||
public static PipelineContextData ToContextData(this TaskResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case TaskResult.Succeeded:
|
||||
case TaskResult.SucceededWithIssues:
|
||||
return new StringContextData(PipelineTemplateConstants.Success);
|
||||
case TaskResult.Failed:
|
||||
case TaskResult.Abandoned:
|
||||
return new StringContextData(PipelineTemplateConstants.Failure);
|
||||
case TaskResult.Canceled:
|
||||
return new StringContextData(PipelineTemplateConstants.Cancelled);
|
||||
case TaskResult.Skipped:
|
||||
return new StringContextData(PipelineTemplateConstants.Skipped);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PipelineContextData ToContextData(this TaskResult? result)
|
||||
{
|
||||
if (result.HasValue)
|
||||
{
|
||||
return result.Value.ToContextData();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Schema;
|
||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
using GitHub.DistributedTask.ObjectTemplating;
|
||||
|
||||
internal sealed class TemplateReference
|
||||
{
|
||||
private TemplateReference(
|
||||
String scope,
|
||||
String id,
|
||||
String generatedId,
|
||||
StringToken templatePath,
|
||||
MappingToken inputs)
|
||||
{
|
||||
Scope = scope;
|
||||
TemplatePath = templatePath;
|
||||
Inputs = inputs;
|
||||
|
||||
if (!String.IsNullOrEmpty(generatedId))
|
||||
{
|
||||
Id = generatedId;
|
||||
m_isGeneratedId = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
}
|
||||
|
||||
internal String Id { get; }
|
||||
|
||||
internal MappingToken Inputs { get; }
|
||||
|
||||
internal String Scope { get; }
|
||||
|
||||
internal StringToken TemplatePath { get; }
|
||||
|
||||
internal String TemplateScope
|
||||
{
|
||||
get
|
||||
{
|
||||
return !String.IsNullOrEmpty(Scope) ? $"{Scope}.{Id}" : Id;
|
||||
}
|
||||
}
|
||||
|
||||
internal MappingToken CreateScope(
|
||||
TemplateContext context,
|
||||
TemplateToken template)
|
||||
{
|
||||
var mapping = template.AssertMapping("template file");
|
||||
|
||||
// Get the inputs and outputs from the template
|
||||
var inputs = default(MappingToken);
|
||||
var outputs = default(MappingToken);
|
||||
foreach (var pair in mapping)
|
||||
{
|
||||
var propertyName = pair.Key.AssertString("template file property name");
|
||||
switch (propertyName.Value)
|
||||
{
|
||||
case PipelineTemplateConstants.Inputs:
|
||||
inputs = pair.Value.AssertMapping("template file inputs");
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Outputs:
|
||||
if (!m_isGeneratedId)
|
||||
{
|
||||
outputs = pair.Value.AssertMapping("template file outputs");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine allowed input names
|
||||
var allowedInputNames = new HashSet<String>(StringComparer.OrdinalIgnoreCase);
|
||||
if (inputs?.Count > 0)
|
||||
{
|
||||
foreach (var pair in inputs)
|
||||
{
|
||||
var inputPropertyName = pair.Key.AssertString("template file inputs property");
|
||||
allowedInputNames.Add(inputPropertyName.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate override inputs names
|
||||
var overrideInputs = new HashSet<String>(StringComparer.OrdinalIgnoreCase);
|
||||
var mergedInputs = new MappingToken(null, null, null);
|
||||
if (Inputs?.Count > 0)
|
||||
{
|
||||
foreach (var pair in Inputs)
|
||||
{
|
||||
var inputPropertyName = pair.Key.AssertString("template reference inputs property");
|
||||
if (!allowedInputNames.Contains(inputPropertyName.Value))
|
||||
{
|
||||
context.Error(inputPropertyName, $"Input '{inputPropertyName.Value}' is not allowed");
|
||||
continue;
|
||||
}
|
||||
|
||||
overrideInputs.Add(inputPropertyName.Value);
|
||||
mergedInputs.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge defaults
|
||||
if (inputs?.Count > 0)
|
||||
{
|
||||
foreach (var pair in inputs)
|
||||
{
|
||||
var inputPropertyName = pair.Key.AssertString("template file inputs property");
|
||||
if (!overrideInputs.Contains(inputPropertyName.Value))
|
||||
{
|
||||
mergedInputs.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the scope object
|
||||
var result = new MappingToken(null, null, null);
|
||||
var namePropertyName = new StringToken(null, null, null, PipelineTemplateConstants.Name);
|
||||
var namePropertyValue = new StringToken(null, null, null, TemplateScope);
|
||||
result.Add(namePropertyName, namePropertyValue);
|
||||
if (mergedInputs.Count > 0)
|
||||
{
|
||||
var inputsPropertyName = new StringToken(null, null, null, PipelineTemplateConstants.Inputs);
|
||||
result.Add(inputsPropertyName, mergedInputs);
|
||||
}
|
||||
|
||||
if (outputs?.Count > 0)
|
||||
{
|
||||
var outputsPropertyName = new StringToken(null, null, null, PipelineTemplateConstants.Outputs);
|
||||
result.Add(outputsPropertyName, outputs);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Boolean TryCreate(
|
||||
MappingToken mapping,
|
||||
out TemplateReference reference)
|
||||
{
|
||||
var scope = default(String);
|
||||
var id = default(String);
|
||||
var generatedId = default(String);
|
||||
var templatePath = default(StringToken);
|
||||
var inputs = default(MappingToken);
|
||||
foreach (var property in mapping)
|
||||
{
|
||||
var propertyName = property.Key.AssertString("candidate template reference property name");
|
||||
switch (propertyName.Value)
|
||||
{
|
||||
case PipelineTemplateConstants.Scope:
|
||||
var scopeStringToken = property.Value.AssertString("step scope");
|
||||
scope = scopeStringToken.Value;
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Id:
|
||||
var idStringToken = property.Value.AssertString("step id");
|
||||
id = idStringToken.Value;
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.GeneratedId:
|
||||
var generatedIdStringToken = property.Value.AssertString("step generated id");
|
||||
generatedId = generatedIdStringToken.Value;
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Template:
|
||||
templatePath = property.Value.AssertString("step template reference");
|
||||
break;
|
||||
|
||||
case PipelineTemplateConstants.Inputs:
|
||||
inputs = property.Value.AssertMapping("step template reference inputs");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (templatePath != null)
|
||||
{
|
||||
reference = new TemplateReference(scope, id, generatedId, templatePath, inputs);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
reference = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean m_isGeneratedId;
|
||||
}
|
||||
}
|
||||
@@ -1,572 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using GitHub.DistributedTask.ObjectTemplating;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a YAML file into a TemplateToken
|
||||
/// </summary>
|
||||
internal sealed class YamlObjectReader : IObjectReader
|
||||
{
|
||||
internal YamlObjectReader(
|
||||
Int32? fileId,
|
||||
TextReader input)
|
||||
{
|
||||
m_fileId = fileId;
|
||||
m_parser = new Parser(input);
|
||||
}
|
||||
|
||||
public Boolean AllowLiteral(out LiteralToken value)
|
||||
{
|
||||
if (EvaluateCurrent() is Scalar scalar)
|
||||
{
|
||||
// Tag specified
|
||||
if (!String.IsNullOrEmpty(scalar.Tag))
|
||||
{
|
||||
// String tag
|
||||
if (String.Equals(scalar.Tag, c_stringTag, StringComparison.Ordinal))
|
||||
{
|
||||
value = new StringToken(m_fileId, scalar.Start.Line, scalar.Start.Column, scalar.Value);
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not plain style
|
||||
if (scalar.Style != ScalarStyle.Plain)
|
||||
{
|
||||
throw new NotSupportedException($"The scalar style '{scalar.Style}' on line {scalar.Start.Line} and column {scalar.Start.Column} is not valid with the tag '{scalar.Tag}'");
|
||||
}
|
||||
|
||||
// Boolean, Float, Integer, or Null
|
||||
switch (scalar.Tag)
|
||||
{
|
||||
case c_booleanTag:
|
||||
value = ParseBoolean(scalar);
|
||||
break;
|
||||
case c_floatTag:
|
||||
value = ParseFloat(scalar);
|
||||
break;
|
||||
case c_integerTag:
|
||||
value = ParseInteger(scalar);
|
||||
break;
|
||||
case c_nullTag:
|
||||
value = ParseNull(scalar);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unexpected tag '{scalar.Tag}'");
|
||||
}
|
||||
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Plain style, determine type using YAML 1.2 "core" schema https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
if (scalar.Style == ScalarStyle.Plain)
|
||||
{
|
||||
if (MatchNull(scalar, out var nullToken))
|
||||
{
|
||||
value = nullToken;
|
||||
}
|
||||
else if (MatchBoolean(scalar, out var booleanToken))
|
||||
{
|
||||
value = booleanToken;
|
||||
}
|
||||
else if (MatchInteger(scalar, out var numberToken) ||
|
||||
MatchFloat(scalar, out numberToken))
|
||||
{
|
||||
value = numberToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = new StringToken(m_fileId, scalar.Start.Line, scalar.Start.Column, scalar.Value);
|
||||
}
|
||||
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise assume string
|
||||
value = new StringToken(m_fileId, scalar.Start.Line, scalar.Start.Column, scalar.Value);
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean AllowSequenceStart(out SequenceToken value)
|
||||
{
|
||||
if (EvaluateCurrent() is SequenceStart sequenceStart)
|
||||
{
|
||||
value = new SequenceToken(m_fileId, sequenceStart.Start.Line, sequenceStart.Start.Column);
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean AllowSequenceEnd()
|
||||
{
|
||||
if (EvaluateCurrent() is SequenceEnd)
|
||||
{
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean AllowMappingStart(out MappingToken value)
|
||||
{
|
||||
if (EvaluateCurrent() is MappingStart mappingStart)
|
||||
{
|
||||
value = new MappingToken(m_fileId, mappingStart.Start.Line, mappingStart.Start.Column);
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean AllowMappingEnd()
|
||||
{
|
||||
if (EvaluateCurrent() is MappingEnd)
|
||||
{
|
||||
MoveNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes the last parsing events, which are expected to be DocumentEnd and StreamEnd.
|
||||
/// </summary>
|
||||
public void ValidateEnd()
|
||||
{
|
||||
if (EvaluateCurrent() is DocumentEnd)
|
||||
{
|
||||
MoveNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Expected document end parse event");
|
||||
}
|
||||
|
||||
if (EvaluateCurrent() is StreamEnd)
|
||||
{
|
||||
MoveNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Expected stream end parse event");
|
||||
}
|
||||
|
||||
if (MoveNext())
|
||||
{
|
||||
throw new InvalidOperationException("Expected end of parse events");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes the first parsing events, which are expected to be StreamStart and DocumentStart.
|
||||
/// </summary>
|
||||
public void ValidateStart()
|
||||
{
|
||||
if (EvaluateCurrent() != null)
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected parser state");
|
||||
}
|
||||
|
||||
if (!MoveNext())
|
||||
{
|
||||
throw new InvalidOperationException("Expected a parse event");
|
||||
}
|
||||
|
||||
if (EvaluateCurrent() is StreamStart)
|
||||
{
|
||||
MoveNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Expected stream start parse event");
|
||||
}
|
||||
|
||||
if (EvaluateCurrent() is DocumentStart)
|
||||
{
|
||||
MoveNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Expected document start parse event");
|
||||
}
|
||||
}
|
||||
|
||||
private ParsingEvent EvaluateCurrent()
|
||||
{
|
||||
if (m_current == null)
|
||||
{
|
||||
m_current = m_parser.Current;
|
||||
if (m_current != null)
|
||||
{
|
||||
if (m_current is Scalar scalar)
|
||||
{
|
||||
// Verify not using achors
|
||||
if (scalar.Anchor != null)
|
||||
{
|
||||
throw new InvalidOperationException($"Anchors are not currently supported. Remove the anchor '{scalar.Anchor}'");
|
||||
}
|
||||
}
|
||||
else if (m_current is MappingStart mappingStart)
|
||||
{
|
||||
// Verify not using achors
|
||||
if (mappingStart.Anchor != null)
|
||||
{
|
||||
throw new InvalidOperationException($"Anchors are not currently supported. Remove the anchor '{mappingStart.Anchor}'");
|
||||
}
|
||||
}
|
||||
else if (m_current is SequenceStart sequenceStart)
|
||||
{
|
||||
// Verify not using achors
|
||||
if (sequenceStart.Anchor != null)
|
||||
{
|
||||
throw new InvalidOperationException($"Anchors are not currently supported. Remove the anchor '{sequenceStart.Anchor}'");
|
||||
}
|
||||
}
|
||||
else if (!(m_current is MappingEnd) &&
|
||||
!(m_current is SequenceEnd) &&
|
||||
!(m_current is DocumentStart) &&
|
||||
!(m_current is DocumentEnd) &&
|
||||
!(m_current is StreamStart) &&
|
||||
!(m_current is StreamEnd))
|
||||
{
|
||||
throw new InvalidOperationException($"Unexpected parsing event type: {m_current.GetType().Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_current;
|
||||
}
|
||||
|
||||
private Boolean MoveNext()
|
||||
{
|
||||
m_current = null;
|
||||
return m_parser.MoveNext();
|
||||
}
|
||||
|
||||
private BooleanToken ParseBoolean(Scalar scalar)
|
||||
{
|
||||
if (MatchBoolean(scalar, out var token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
ThrowInvalidValue(scalar, c_booleanTag); // throws
|
||||
return default;
|
||||
}
|
||||
|
||||
private NumberToken ParseFloat(Scalar scalar)
|
||||
{
|
||||
if (MatchFloat(scalar, out var token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
ThrowInvalidValue(scalar, c_floatTag); // throws
|
||||
return default;
|
||||
}
|
||||
|
||||
private NumberToken ParseInteger(Scalar scalar)
|
||||
{
|
||||
if (MatchInteger(scalar, out var token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
ThrowInvalidValue(scalar, c_integerTag); // throws
|
||||
return default;
|
||||
}
|
||||
|
||||
private NullToken ParseNull(Scalar scalar)
|
||||
{
|
||||
if (MatchNull(scalar, out var token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
ThrowInvalidValue(scalar, c_nullTag); // throws
|
||||
return default;
|
||||
}
|
||||
|
||||
private Boolean MatchBoolean(
|
||||
Scalar scalar,
|
||||
out BooleanToken value)
|
||||
{
|
||||
// YAML 1.2 "core" schema https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
switch (scalar.Value ?? String.Empty)
|
||||
{
|
||||
case "true":
|
||||
case "True":
|
||||
case "TRUE":
|
||||
value = new BooleanToken(m_fileId, scalar.Start.Line, scalar.Start.Column, true);
|
||||
return true;
|
||||
case "false":
|
||||
case "False":
|
||||
case "FALSE":
|
||||
value = new BooleanToken(m_fileId, scalar.Start.Line, scalar.Start.Column, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean MatchFloat(
|
||||
Scalar scalar,
|
||||
out NumberToken value)
|
||||
{
|
||||
// YAML 1.2 "core" schema https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
var str = scalar.Value;
|
||||
if (!String.IsNullOrEmpty(str))
|
||||
{
|
||||
// Check for [-+]?(\.inf|\.Inf|\.INF)|\.nan|\.NaN|\.NAN
|
||||
switch (str)
|
||||
{
|
||||
case ".inf":
|
||||
case ".Inf":
|
||||
case ".INF":
|
||||
case "+.inf":
|
||||
case "+.Inf":
|
||||
case "+.INF":
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, Double.PositiveInfinity);
|
||||
return true;
|
||||
case "-.inf":
|
||||
case "-.Inf":
|
||||
case "-.INF":
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, Double.NegativeInfinity);
|
||||
return true;
|
||||
case ".nan":
|
||||
case ".NaN":
|
||||
case ".NAN":
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, Double.NaN);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise check [-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?
|
||||
|
||||
// Skip leading sign
|
||||
var index = str[0] == '-' || str[0] == '+' ? 1 : 0;
|
||||
|
||||
// Check for integer portion
|
||||
var length = str.Length;
|
||||
var hasInteger = false;
|
||||
while (index < length && str[index] >= '0' && str[index] <= '9')
|
||||
{
|
||||
hasInteger = true;
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check for decimal point
|
||||
var hasDot = false;
|
||||
if (index < length && str[index] == '.')
|
||||
{
|
||||
hasDot = true;
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check for decimal portion
|
||||
var hasDecimal = false;
|
||||
while (index < length && str[index] >= '0' && str[index] <= '9')
|
||||
{
|
||||
hasDecimal = true;
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check [-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)
|
||||
if ((hasDot && hasDecimal) || hasInteger)
|
||||
{
|
||||
// Check for end
|
||||
if (index == length)
|
||||
{
|
||||
// Try parse
|
||||
if (Double.TryParse(str, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var doubleValue))
|
||||
{
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, doubleValue);
|
||||
return true;
|
||||
}
|
||||
// Otherwise exceeds range
|
||||
else
|
||||
{
|
||||
ThrowInvalidValue(scalar, c_floatTag); // throws
|
||||
}
|
||||
}
|
||||
// Check [eE][-+]?[0-9]
|
||||
else if (index < length && (str[index] == 'e' || str[index] == 'E'))
|
||||
{
|
||||
index++;
|
||||
|
||||
// Skip sign
|
||||
if (index < length && (str[index] == '-' || str[index] == '+'))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check for exponent
|
||||
var hasExponent = false;
|
||||
while (index < length && str[index] >= '0' && str[index] <= '9')
|
||||
{
|
||||
hasExponent = true;
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check for end
|
||||
if (hasExponent && index == length)
|
||||
{
|
||||
// Try parse
|
||||
if (Double.TryParse(str, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out var doubleValue))
|
||||
{
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, (Double)doubleValue);
|
||||
return true;
|
||||
}
|
||||
// Otherwise exceeds range
|
||||
else
|
||||
{
|
||||
ThrowInvalidValue(scalar, c_floatTag); // throws
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean MatchInteger(
|
||||
Scalar scalar,
|
||||
out NumberToken value)
|
||||
{
|
||||
// YAML 1.2 "core" schema https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
var str = scalar.Value;
|
||||
if (!String.IsNullOrEmpty(str))
|
||||
{
|
||||
// Check for [0-9]+
|
||||
var firstChar = str[0];
|
||||
if (firstChar >= '0' && firstChar <= '9' &&
|
||||
str.Skip(1).All(x => x >= '0' && x <= '9'))
|
||||
{
|
||||
// Try parse
|
||||
if (Double.TryParse(str, NumberStyles.None, CultureInfo.InvariantCulture, out var doubleValue))
|
||||
{
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, doubleValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise exceeds range
|
||||
ThrowInvalidValue(scalar, c_integerTag); // throws
|
||||
}
|
||||
// Check for (-|+)[0-9]+
|
||||
else if ((firstChar == '-' || firstChar == '+') &&
|
||||
str.Length > 1 &&
|
||||
str.Skip(1).All(x => x >= '0' && x <= '9'))
|
||||
{
|
||||
// Try parse
|
||||
if (Double.TryParse(str, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out var doubleValue))
|
||||
{
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, doubleValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise exceeds range
|
||||
ThrowInvalidValue(scalar, c_integerTag); // throws
|
||||
}
|
||||
// Check for 0x[0-9a-fA-F]+
|
||||
else if (firstChar == '0' &&
|
||||
str.Length > 2 &&
|
||||
str[1] == 'x' &&
|
||||
str.Skip(2).All(x => (x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F')))
|
||||
{
|
||||
// Try parse
|
||||
if (Int32.TryParse(str.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var integerValue))
|
||||
{
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, integerValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise exceeds range
|
||||
ThrowInvalidValue(scalar, c_integerTag); // throws
|
||||
}
|
||||
// Check for 0o[0-9]+
|
||||
else if (firstChar == '0' &&
|
||||
str.Length > 2 &&
|
||||
str[1] == 'o' &&
|
||||
str.Skip(2).All(x => x >= '0' && x <= '7'))
|
||||
{
|
||||
// Try parse
|
||||
var integerValue = default(Int32);
|
||||
try
|
||||
{
|
||||
integerValue = Convert.ToInt32(str.Substring(2), 8);
|
||||
}
|
||||
// Otherwise exceeds range
|
||||
catch (Exception)
|
||||
{
|
||||
ThrowInvalidValue(scalar, c_integerTag); // throws
|
||||
}
|
||||
|
||||
value = new NumberToken(m_fileId, scalar.Start.Line, scalar.Start.Column, integerValue);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean MatchNull(
|
||||
Scalar scalar,
|
||||
out NullToken value)
|
||||
{
|
||||
// YAML 1.2 "core" schema https://yaml.org/spec/1.2/spec.html#id2804923
|
||||
switch (scalar.Value ?? String.Empty)
|
||||
{
|
||||
case "":
|
||||
case "null":
|
||||
case "Null":
|
||||
case "NULL":
|
||||
case "~":
|
||||
value = new NullToken(m_fileId, scalar.Start.Line, scalar.Start.Column);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ThrowInvalidValue(
|
||||
Scalar scalar,
|
||||
String tag)
|
||||
{
|
||||
throw new NotSupportedException($"The value '{scalar.Value}' on line {scalar.Start.Line} and column {scalar.Start.Column} is invalid for the type '{scalar.Tag}'");
|
||||
}
|
||||
|
||||
private const String c_booleanTag = "tag:yaml.org,2002:bool";
|
||||
private const String c_floatTag = "tag:yaml.org,2002:float";
|
||||
private const String c_integerTag = "tag:yaml.org,2002:int";
|
||||
private const String c_nullTag = "tag:yaml.org,2002:null";
|
||||
private const String c_stringTag = "tag:yaml.org,2002:string";
|
||||
private readonly Int32? m_fileId;
|
||||
private readonly Parser m_parser;
|
||||
private ParsingEvent m_current;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using GitHub.DistributedTask.ObjectTemplating;
|
||||
using YamlDotNet.Core.Events;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a TemplateToken into YAML
|
||||
/// </summary>
|
||||
internal sealed class YamlObjectWriter : IObjectWriter
|
||||
{
|
||||
internal YamlObjectWriter(StringWriter writer)
|
||||
{
|
||||
m_emitter = new YamlDotNet.Core.Emitter(writer);
|
||||
}
|
||||
|
||||
public void WriteString(String value)
|
||||
{
|
||||
m_emitter.Emit(new Scalar(value ?? String.Empty));
|
||||
}
|
||||
|
||||
public void WriteBoolean(Boolean value)
|
||||
{
|
||||
m_emitter.Emit(new Scalar(value ? "true" : "false"));
|
||||
}
|
||||
|
||||
public void WriteNumber(Double value)
|
||||
{
|
||||
m_emitter.Emit(new Scalar(value.ToString("G15", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
public void WriteNull()
|
||||
{
|
||||
m_emitter.Emit(new Scalar("null"));
|
||||
}
|
||||
|
||||
public void WriteSequenceStart()
|
||||
{
|
||||
m_emitter.Emit(new SequenceStart(null, null, true, SequenceStyle.Block));
|
||||
}
|
||||
|
||||
public void WriteSequenceEnd()
|
||||
{
|
||||
m_emitter.Emit(new SequenceEnd());
|
||||
}
|
||||
|
||||
public void WriteMappingStart()
|
||||
{
|
||||
m_emitter.Emit(new MappingStart());
|
||||
}
|
||||
|
||||
public void WriteMappingEnd()
|
||||
{
|
||||
m_emitter.Emit(new MappingEnd());
|
||||
}
|
||||
|
||||
public void WriteStart()
|
||||
{
|
||||
m_emitter.Emit(new StreamStart());
|
||||
m_emitter.Emit(new DocumentStart());
|
||||
}
|
||||
|
||||
public void WriteEnd()
|
||||
{
|
||||
m_emitter.Emit(new DocumentEnd(isImplicit: true));
|
||||
m_emitter.Emit(new StreamEnd());
|
||||
}
|
||||
|
||||
private readonly YamlDotNet.Core.IEmitter m_emitter;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines
|
||||
{
|
||||
@@ -12,18 +9,8 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class PipelineConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum agent version when performing an advanced checkout. This demand
|
||||
/// is required when multiple checkout steps are used, when the checkout step
|
||||
/// is not the first step, or when any repository is checked out other than self
|
||||
/// or none.
|
||||
/// </summary>
|
||||
public static readonly String AdvancedCheckoutMinAgentVersion = "2.137.0";
|
||||
|
||||
public static readonly String AgentVersionDemandName = "Runner.Version";
|
||||
|
||||
public static readonly String AgentName = "Agent.Name";
|
||||
|
||||
/// <summary>
|
||||
/// The default job cancel timeout in minutes.
|
||||
/// </summary>
|
||||
@@ -50,21 +37,11 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
/// </summary>
|
||||
public static readonly Int32 MaxNodeNameLength = 100;
|
||||
|
||||
/// <summary>
|
||||
/// The repository alias to use for dont-sync-sources.
|
||||
/// </summary>
|
||||
public static readonly String NoneAlias = "none";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the self repository.
|
||||
/// </summary>
|
||||
public static readonly String SelfAlias = "self";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the repository coming from designer build definition.
|
||||
/// </summary>
|
||||
public static readonly String DesignerRepo = "__designer_repo";
|
||||
|
||||
/// <summary>
|
||||
/// Error code during graph validation.
|
||||
/// </summary>
|
||||
@@ -90,9 +67,6 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
/// </summary>
|
||||
internal const String StartingPointNotFound = nameof(StartingPointNotFound);
|
||||
|
||||
internal const String CheckpointNodeInstanceNameClaimKey = "nodeInstanceName";
|
||||
internal const String CheckpointIdClaimKey = "checkpointId";
|
||||
|
||||
public static class CheckoutTaskInputs
|
||||
{
|
||||
public static readonly String Repository = "repository";
|
||||
@@ -120,20 +94,5 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
public static readonly String Resources = "resources";
|
||||
public static readonly String All = "all";
|
||||
}
|
||||
|
||||
public static class EnvironmentVariables
|
||||
{
|
||||
public static readonly String EnvironmentId = "Environment.Id";
|
||||
public static readonly String EnvironmentName = "Environment.Name";
|
||||
public static readonly String EnvironmentResourceId = "Environment.ResourceId";
|
||||
public static readonly String EnvironmentResourceName = "Environment.ResourceName";
|
||||
}
|
||||
|
||||
public static class ScriptStepInputs
|
||||
{
|
||||
public static readonly String Script = "script";
|
||||
public static readonly String WorkingDirectory = "workingDirectory";
|
||||
public static readonly String Shell = "shell";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,70 +9,9 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
public static class RepositoryPropertyNames
|
||||
{
|
||||
public static readonly String Id = "id";
|
||||
public static readonly String Mappings = "mappings";
|
||||
public static readonly String Name = "name";
|
||||
public static readonly String Ref = "ref";
|
||||
public static readonly String Type = "type";
|
||||
public static readonly String Url = "url";
|
||||
public static readonly String Version = "version";
|
||||
public static readonly String VersionInfo = "versionInfo";
|
||||
public static readonly String VersionSpec = "versionSpec";
|
||||
public static readonly String Shelveset = "shelveset";
|
||||
public static readonly String Project = "project";
|
||||
public static readonly String Path = "path";
|
||||
public static readonly String CheckoutOptions = "checkoutOptions";
|
||||
public static readonly String DefaultBranch = "defaultBranch";
|
||||
public static readonly String ExternalId = "externalId";
|
||||
public static readonly String IsJustInTimeRepository = "isJustInTimeRepository";
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class VersionInfo
|
||||
{
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Author { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Message { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class CheckoutOptions
|
||||
{
|
||||
[JsonConstructor]
|
||||
public CheckoutOptions()
|
||||
{ }
|
||||
|
||||
private CheckoutOptions(CheckoutOptions optionsToCopy)
|
||||
{
|
||||
this.Clean = optionsToCopy.Clean;
|
||||
this.FetchDepth = optionsToCopy.FetchDepth;
|
||||
this.Lfs = optionsToCopy.Lfs;
|
||||
this.Submodules = optionsToCopy.Submodules;
|
||||
this.PersistCredentials = optionsToCopy.PersistCredentials;
|
||||
}
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Clean{ get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String FetchDepth{ get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Lfs { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Submodules { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String PersistCredentials { get; set; }
|
||||
|
||||
public CheckoutOptions Clone()
|
||||
{
|
||||
return new CheckoutOptions(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,12 +4,6 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
{
|
||||
public static class RepositoryTypes
|
||||
{
|
||||
public static readonly String Bitbucket = nameof(Bitbucket);
|
||||
public static readonly String ExternalGit = nameof(ExternalGit);
|
||||
public static readonly String Git = nameof(Git);
|
||||
public static readonly String GitHub = nameof(GitHub);
|
||||
public static readonly String GitHubEnterprise = nameof(GitHubEnterprise);
|
||||
public static readonly String Tfvc = nameof(Tfvc);
|
||||
public static readonly String Svn = nameof(Svn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
|
||||
namespace GitHub.DistributedTask.Pipelines
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public sealed class StrategyResult
|
||||
{
|
||||
public StrategyResult()
|
||||
{
|
||||
FailFast = true;
|
||||
}
|
||||
|
||||
public Boolean FailFast { get; set; }
|
||||
|
||||
public int MaxParallel { get; set; }
|
||||
|
||||
public IList<StrategyConfiguration> Configurations { get; } = new List<StrategyConfiguration>();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public sealed class StrategyConfiguration
|
||||
{
|
||||
public String DisplayName { get; set; }
|
||||
|
||||
public String Name { get; set; }
|
||||
|
||||
public IDictionary<String, PipelineContextData> ContextData { get; } = new Dictionary<String, PipelineContextData>(StringComparer.Ordinal);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user