internal Int32 CalculateBytes( TemplateToken value, Boolean traverse = false) { var enumerable = traverse ? value.Traverse() : new[] { value }; var result = 0; foreach (var item in enumerable) { // This measurement doesn't have to be perfect // https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/ switch (item.Type) { case TokenType.Null: case TokenType.Boolean: case TokenType.Number: checked { result += MinObjectSize; } break; case TokenType.String: var stringToken = item as StringToken; checked { result += MinObjectSize + StringBaseOverhead + ((stringToken.Value?.Length ?? 0) * sizeof(Char)); } break; case TokenType.Sequence: case TokenType.Mapping: case TokenType.InsertExpression: // Min object size is good enough. Allows for base + a few fields. checked { result += MinObjectSize; } break; case TokenType.BasicExpression: var basicExpression = item as BasicExpressionToken; checked { result += MinObjectSize + StringBaseOverhead + ((basicExpression.Expression?.Length ?? 0) * sizeof(Char)); } break; default: throw new NotSupportedException($"Unexpected template type '{item.Type}'"); } } return(result); }
internal static Boolean ConvertToIfResult( TemplateContext context, TemplateToken ifResult) { var expression = ifResult.Traverse().FirstOrDefault(x => x is ExpressionToken); if (expression != null) { throw new ArgumentException($"Unexpected type '{expression.GetType().Name}' encountered while reading 'if'."); } var evaluationResult = EvaluationResult.CreateIntermediateResult(null, ifResult); return(evaluationResult.IsTruthy); }
internal static List <KeyValuePair <String, JobContainer> > ConvertToJobServiceContainers( TemplateContext context, TemplateToken services, bool allowExpressions = false) { var result = new List <KeyValuePair <String, JobContainer> >(); if (allowExpressions && services.Traverse().Any(x => x is ExpressionToken)) { return(result); } var servicesMapping = services.AssertMapping("services"); foreach (var servicePair in servicesMapping) { var networkAlias = servicePair.Key.AssertString("services key").Value; var container = ConvertToJobContainer(context, servicePair.Value); result.Add(new KeyValuePair <String, JobContainer>(networkAlias, container)); } return(result); }
internal static JobContainer ConvertToJobContainer( TemplateContext context, TemplateToken value, bool allowExpressions = false) { var result = new JobContainer(); if (allowExpressions && value.Traverse().Any(x => x is ExpressionToken)) { return(result); } if (value is StringToken containerLiteral) { if (String.IsNullOrEmpty(containerLiteral.Value)) { return(null); } result.Image = containerLiteral.Value; } else { var containerMapping = value.AssertMapping($"{PipelineTemplateConstants.Container}"); foreach (var containerPropertyPair in containerMapping) { var propertyName = containerPropertyPair.Key.AssertString($"{PipelineTemplateConstants.Container} key"); switch (propertyName.Value) { case PipelineTemplateConstants.Image: result.Image = containerPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName}").Value; break; case PipelineTemplateConstants.Env: var env = containerPropertyPair.Value.AssertMapping($"{PipelineTemplateConstants.Container} {propertyName}"); var envDict = new Dictionary <String, String>(env.Count); foreach (var envPair in env) { var envKey = envPair.Key.ToString(); var envValue = envPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName} {envPair.Key.ToString()}").Value; envDict.Add(envKey, envValue); } result.Environment = envDict; break; case PipelineTemplateConstants.Options: result.Options = containerPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName}").Value; break; case PipelineTemplateConstants.Ports: var ports = containerPropertyPair.Value.AssertSequence($"{PipelineTemplateConstants.Container} {propertyName}"); var portList = new List <String>(ports.Count); foreach (var portItem in ports) { var portString = portItem.AssertString($"{PipelineTemplateConstants.Container} {propertyName} {portItem.ToString()}").Value; portList.Add(portString); } result.Ports = portList; break; case PipelineTemplateConstants.Volumes: var volumes = containerPropertyPair.Value.AssertSequence($"{PipelineTemplateConstants.Container} {propertyName}"); var volumeList = new List <String>(volumes.Count); foreach (var volumeItem in volumes) { var volumeString = volumeItem.AssertString($"{PipelineTemplateConstants.Container} {propertyName} {volumeItem.ToString()}").Value; volumeList.Add(volumeString); } result.Volumes = volumeList; break; case PipelineTemplateConstants.Credentials: result.Credentials = ConvertToContainerCredentials(containerPropertyPair.Value); break; default: propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Container} key"); break; } } } if (result.Image.StartsWith("docker://", StringComparison.Ordinal)) { result.Image = result.Image.Substring("docker://".Length); } if (String.IsNullOrEmpty(result.Image)) { context.Error(value, "Container image cannot be empty"); } return(result); }