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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }