Пример #1
0
        /// <summary>
        /// Prompts for environment by looking into spreadsheet and listing them out
        /// to the console.
        /// </summary>
        /// <param name="source">The data source.</param>
        /// <param name="context">The preprocessing context.</param>
        /// <returns></returns>
        private static string PromptForEnvironment(DataSource source, PreprocessingContext context)
        {
            SettingsLoader loader = new SettingsLoader(context);

            Console.WriteLine("Environment name was not passed.");
            Console.WriteLine("");

            ConsoleUtils.WriteLine(ConsoleColor.Cyan, "These are the environment columns found in the spreadsheet:");

            List <string> environments = loader.GetEnvironments(source);

            for (int j = 0; j < environments.Count; j++)
            {
                ConsoleUtils.WriteLine(ConsoleColor.Cyan, string.Format(" {0} - {1}", j, environments[j]));
            }

            ConsoleUtils.Write(ConsoleColor.Cyan, "Type the environment # to use and press Enter: ");

            string environmentIndexString = Console.ReadLine();
            int    environmentIndex       = -1;

            if (int.TryParse(environmentIndexString, out environmentIndex))
            {
                return(environments[environmentIndex]);
            }

            return(null);
        }
Пример #2
0
        /// <summary>
        /// Parse any command line properties, allowing them
        /// to override the file base ones
        /// </summary>
        /// <param name="context">Preprocessing context</param>
        /// <param name="array">ArrayList read from command line</param>
        public void AddPropertiesFromArrayList(PreprocessingContext context, ArrayList array)
        {
            for (int i = 0; i < array.Count; i++)
            {
                string property = (string)array[i];
                if (null != property && property.Length > 0)
                {
                    string propertyName  = null;
                    string propertyValue = "";

                    int equalPos = -1;
                    if (context.IsDynamicProperty(property))
                    {
                        equalPos = property.LastIndexOf('=');
                    }
                    else
                    {
                        equalPos = property.IndexOf('=');
                    }

                    if (-1 == equalPos)
                    {
                        propertyName = property;
                    }
                    else
                    {
                        propertyName  = property.Substring(0, equalPos);
                        propertyValue = property.Substring(equalPos + 1);
                    }

                    Add(propertyName, propertyValue);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Deploy an XML file using preprocessor.
        /// </summary>
        /// <param name="context">Preprocessing Context</param>
        public int Preprocess(PreprocessingContext context)
        {
            // load the file into a string
            string source = FileUtils.LoadFile(context.SourceFile);

            // add all of the built-in properties like _current_dir
            context.AddBuiltInProperties();

            // pre-load embedded defines in case there are any defines used in includes
            ExtractDefines(context, source);

            // pull-in any externally included files
            string dest = ProcessIncludes(context, source);

            // again scan for embedded defines in case the includes contained them
            ExtractDefines(context, dest);

            // process the entire file
            dest = Process(context, dest);

            if (context.ValidateSettingsExist && context.Errors.Count > 0)
            {
                // don't write file, just return error code
                return(2);
            }
            else
            {
                if (context.ValidateXmlWellFormed)
                {
                    try
                    {
                        XmlDocument wellFormednessCheckingDocument = new XmlDocument();
                        wellFormednessCheckingDocument.LoadXml(dest);
                    }
                    catch (XmlException e)
                    {
                        string errorFile = context.DestinationFile + ".error";
                        FileUtils.WriteFile(errorFile, dest);

                        ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorNotWellFormed, context.SourceFile);
                        errorInfo.Message = string.Format("Output was not well-formed: {0}, A copy of the file that was not well-formed was saved to {1}.", e.Message, errorFile);
                        context.Errors.Add(errorInfo);

                        return(1);
                    }
                }


                // Only write out the file if the destination is different
                // than the source or if changes were made
                if (!context.DestinationFile.Equals(context.SourceFile) || !source.Equals(dest))
                {
                    FileUtils.WriteFile(context.DestinationFile, dest);
                }
            }
            return(0);
        }
Пример #4
0
        /// <summary>
        /// Remove macro braces (example: ${...}) from a section of content.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <param name="content">The content from which to remove the macro braces.</param>
        /// <returns>Content without macro braces.</returns>
        private string RemoveMacro(PreprocessingContext context, string content)
        {
            string result = null;

            if (null != content)
            {
                result = content.Replace(context.TokenStart, "");
                result = result.Replace(context.TokenEnd, "");
                result = result.Trim();
            }
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Resolves content that could possibly contain macros
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <param name="content">The content that could contain macros.</param>
        /// <exception cref="UndefinedSettingException">Throws this exception if it encounters an undefined setting</exception>
        /// <returns>the resolved content</returns>
        public string ResolveContent(PreprocessingContext context, string content)
        {
            if (!string.IsNullOrEmpty(content))
            {
                bool isSameTokenUsedForStartAndEnd = context.TokenStart.Equals(context.TokenEnd, StringComparison.OrdinalIgnoreCase);

                // Look for start of tokens, order depends on type of token used
                int macroPosition = -1;

                // Evaluate from back to front if tokens are not equal
                // this enables nested tokens such as this: ${PROPERTY_${MACHINE}}
                // Evaluate from front to back if start and end tokens are equal...nested properties with
                // custom tokens that match is not supported. You can't do this: #PROPERTY_#MACHINE##
                if (!isSameTokenUsedForStartAndEnd)
                {
                    macroPosition = content.LastIndexOf(context.TokenStart);
                }
                else
                {
                    macroPosition = content.IndexOf(context.TokenStart);
                }

                while (macroPosition > -1)
                {
                    int    endMacroPosition = content.IndexOf(context.TokenEnd, macroPosition + context.TokenStart.Length);
                    string macro            = content.Substring(macroPosition, endMacroPosition - macroPosition + 1);
                    string key = macro.Substring(context.TokenStart.Length, macro.Length - (context.TokenStart.Length + context.TokenEnd.Length)).Trim();

                    PreprocessingProperty property = this[key];
                    if (null == property)
                    {
                        throw new UndefinedSettingException(string.Format("{0} was not defined", key), key);
                    }

                    string val = property.Value;
                    content = content.Replace(macro, val);

                    if (!isSameTokenUsedForStartAndEnd)
                    {
                        macroPosition = content.LastIndexOf(context.TokenStart);
                    }
                    else
                    {
                        macroPosition = content.IndexOf(context.TokenStart);
                    }
                }
            }

            return(content);
        }
Пример #6
0
 /// <summary>
 /// Reports the use count.
 /// </summary>
 /// <param name="cl">The cl.</param>
 /// <param name="context">The context.</param>
 private static void ReportUseCount(CommandLine cl, PreprocessingContext context)
 {
     if (!string.IsNullOrEmpty(cl.countReportFile))
     {
         StringBuilder sb = new StringBuilder();
         sb.Append("Property, Count\r\n");
         foreach (var property in context.Properties)
         {
             if (!property.Key.StartsWith("_"))
             {
                 sb.Append(string.Format("{0}, {1}\r\n", property.Key, property.UseCount));
             }
         }
         FileUtils.WriteFile(cl.countReportFile, sb.ToString());
     }
 }
Пример #7
0
        /// <summary>
        /// Dumps the environment names from the data source to the console.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <returns></returns>
        private static int DumpEnvironments(PreprocessingContext context)
        {
            int exitCode = 0;

            try
            {
                DataSource firstDataSource = context.DataSources[0];

                SettingsLoader loader = new SettingsLoader(context);

                DataTable settingsTable = loader.LoadDataTableFromDataSource(firstDataSource);

                List <string> environments = loader.GetEnvironmentsFromDataTable(settingsTable);
                foreach (string environment in environments)
                {
                    if (!string.IsNullOrEmpty(context.PropertyToExtract))
                    {
                        PreprocessingProperties properties = new PreprocessingProperties(context.FixFalse);
                        loader.LoadSettingsFromDataTable(settingsTable, context.Properties, environment);

                        PreprocessingProperty property = context.Properties[context.PropertyToExtract];
                        if (null != property)
                        {
                            string resolvedPropertyValue = context.ResolveContent(property.Value);

                            if (!string.IsNullOrEmpty(resolvedPropertyValue))
                            {
                                Console.WriteLine(resolvedPropertyValue);
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine(environment);
                    }
                }
            }
            catch (Exception e)
            {
                ConsoleUtils.WriteLine(ConsoleColor.Red, e.Message);
                exitCode = 1;
            }

            return(exitCode);
        }
Пример #8
0
 /// <summary>
 /// Extracts the #defines from the document
 /// </summary>
 /// <param name="context">The Preprocessing context.</param>
 /// <param name="content">The content.</param>
 private void ExtractDefines(PreprocessingContext context, string content)
 {
     for (Match matchDefine = regexDefine.Match(content);
          matchDefine.Success;
          matchDefine = matchDefine.NextMatch())
     {
         Group expressionGroup = matchDefine.Groups["expression"];
         Group valueGroup      = matchDefine.Groups["value"];
         if (null != expressionGroup && null != valueGroup &&
             !string.IsNullOrEmpty(expressionGroup.Value) &&
             !string.IsNullOrEmpty(valueGroup.Value))
         {
             string expression = expressionGroup.Value.Trim();
             string value      = valueGroup.Value.Trim();
             context.Properties.Add(expression, value);
         }
     }
 }
Пример #9
0
        /// <summary>
        /// Processes the dynamically bound properties.
        /// </summary>
        /// <remarks>
        /// This is a fairly inefficient implementation for the first cut, it would be
        /// nicer if a buffer could be reused to avoid reallocating huge strings for
        /// every single property, especially in the case of XML.
        /// </remarks>
        /// <param name="context">The Preprocessing context.</param>
        /// <param name="content">The content.</param>
        /// <returns>The buffer with any dynamically bound properties replaced</returns>
        private string ProcessDynamicallyBoundProperties(PreprocessingContext context, string content)
        {
            string resultBuffer = content;

            foreach (PreprocessingProperty property in context.Properties)
            {
                if (context.IsDynamicProperty(property.Key))
                {
                    IDynamicResolver resolver = property.GetDynamicResolver(context);
                    if (resolver.ShouldProcess(context.SourceFile))
                    {
                        string replacementValue = ResolveProperties(property.Value, context);
                        resultBuffer = resolver.Replace(resultBuffer, replacementValue);
                    }
                }
            }

            return(resultBuffer);
        }
Пример #10
0
        /// <summary>
        /// Reads the settings from files.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <returns>Error code</returns>
        private static int ReadSettings(PreprocessingContext context)
        {
            // read data source settings files
            int exitCode = ReadSettingsFromDataSources(context);

            if (0 != exitCode)
            {
                return(exitCode);
            }

            // read loose settings files (moved after data sources to allow overriding)
            exitCode = ReadEnvironmentSettingsFile(context);

            if (0 != exitCode)
            {
                return(exitCode);
            }

            return(exitCode);
        }
Пример #11
0
        /// <summary>
        /// Resolves an expression
        /// </summary>
        /// <param name="expression">The function.</param>
        /// <param name="context">The preprocessing context.</param>
        /// <returns>The resulting value</returns>
        private string ResolveExpression(string expression, PreprocessingContext context)
        {
            string           val       = "";
            DynamicEvaluator evaluator = new DynamicEvaluator();

            try
            {
                val = evaluator.EvaluateToString(context, expression);
            }
            catch (Exception ex)
            {
                val = "<!-- " + expression + " not properly formed -->";

                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorNotWellFormed, context.SourceFile);
                errorInfo.Message = string.Format("The expression '{0}' was not properly formed. {1}", expression, ex.ToString());
                context.Errors.Add(errorInfo);
            }

            return(val);
        }
Пример #12
0
        /// <summary>
        /// Dumps an individual property from the data source to the console.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <returns></returns>
        private static int DumpProperty(PreprocessingContext context)
        {
            int exitCode = 0;

            try
            {
                PreprocessingProperty property = context.Properties[context.PropertyToExtract];

                if (null != property)
                {
                    string resolvedValue = context.ResolveContent(property.Value);

                    if (!string.IsNullOrEmpty(resolvedValue))
                    {
                        if (!string.IsNullOrEmpty(context.Delimiters))
                        {
                            foreach (string s in resolvedValue.Split(context.Delimiters.ToCharArray()))
                            {
                                Console.WriteLine(s.Trim());
                            }
                        }
                        else
                        {
                            Console.WriteLine(resolvedValue);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ConsoleUtils.WriteLine(ConsoleColor.Red, e.Message);
                exitCode = 1;
            }

            return(exitCode);
        }
Пример #13
0
        public static int Main(string[] args)
        {
            int exitCode = 0;

            // be nice & set console color back in the case of a Ctrl-C
            ConsoleColor originalColor = Console.ForegroundColor;

            Console.CancelKeyPress += delegate { Console.ForegroundColor = originalColor; };

            // Parse the command line and show help or version or error
            CommandLine cl = new CommandLine();

            if (!cl.ParseAndContinue(args))
            {
                exitCode = 1;
                return(exitCode);
            }

            // Make sure argument combinations are valid
            if (!cl.ValidateArguments())
            {
                exitCode = 1;
                return(exitCode);
            }

            // Output logo if they didn't ask to turn it off, and they aren't extracting something
            bool isExtractingProperty = !string.IsNullOrEmpty(cl.property);

            if (!cl.noLogo && !cl.list && !isExtractingProperty)
            {
                Console.WriteLine(cl.GetCommandLineLogo());
            }

            cl.NormalizeAllFileArrays();

            PreprocessingContext context = cl.CreatePreprocessingContext();

            if (cl.list)
            {
                return(DumpEnvironments(context));
            }

            // Do not prompt for input if extracting a property
            if (isExtractingProperty)
            {
                context.QuietMode = true;
            }

            // read settings files
            exitCode = ReadSettings(context);

            if (0 == exitCode && !string.IsNullOrEmpty(cl.environmentFile))
            {
                Console.WriteLine("Writing selected environment \"{0}\" to {1}", context.EnvironmentName, cl.environmentFile);
                FileUtils.WriteFile(cl.environmentFile, context.EnvironmentName);
                return(exitCode);
            }

            if (0 == exitCode)
            {
                // Add properties from command line last so they override everything else
                context.Properties.AddPropertiesFromArrayList(context, cl.define);

                if (isExtractingProperty)
                {
                    return(DumpProperty(context));
                }
                else
                {
                    XmlPreprocessor preprocessor = new XmlPreprocessor();

                    // loop through input files
                    for (int i = 0; i < cl.input.Count; i++)
                    {
                        context.SourceFile = cl.input[i] as string;

                        if (null != context.SourceFile)
                        {
                            context.SourceFile = context.SourceFile.Trim();
                        }

                        if (!string.IsNullOrEmpty(context.SourceFile))
                        {
                            if (!File.Exists(context.SourceFile))
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorFileNotFound, context.SourceFile);
                                errorInfo.Message = string.Format("Input file was not found: \"{0}\"", context.SourceFile);
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }

                            context.DestinationFile = null;
                            if (i < cl.output.Count)
                            {
                                context.DestinationFile = cl.output[i] as string;
                            }

                            // If destination file was not specified, use input file
                            if (string.IsNullOrEmpty(context.DestinationFile))
                            {
                                context.DestinationFile = context.SourceFile;
                                ConsoleUtils.WriteLine(ConsoleColor.Cyan, string.Format("Preprocessing \"{0}\"...", context.SourceFile));
                            }
                            else
                            {
                                ConsoleUtils.WriteLine(ConsoleColor.Cyan, string.Format("Preprocessing \"{0}\" to \"{1}\"...", context.SourceFile, context.DestinationFile));
                            }

                            try
                            {
                                exitCode = preprocessor.Preprocess(context);
                                if (0 != exitCode)
                                {
                                    break;
                                }
                            }
                            catch (Exception e)
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                                errorInfo.Message = e.Message;
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }
                        }
                    }
                }
            }

            ReportUseCount(cl, context);

            ReportErrorsAndWarnings(context.Errors);

            return(exitCode);
        }
Пример #14
0
        /// <summary>
        /// Replace any macros with their property value.
        /// </summary>
        /// <param name="content">Content in which to replace all macros.</param>
        /// <param name="context">The preprocessing context.</param>
        /// <param name="overriddenValues">The value to insert.</param>
        /// <returns>The content with macros replaced with corresponding property values.</returns>
        private string ResolveProperties(string content, PreprocessingContext context, IDictionary <string, string> overriddenValues)
        {
            bool         containedEscapedMacros        = false;
            const string startEscapedMacro             = "{6496D0A7-21B9-4603-A2E5-43C64FCD435E{";
            const string endEscapedMacro               = "}6496D0A7-21B9-4603-A2E5-43C64FCD435E}";
            bool         isSameTokenUsedForStartAndEnd = context.TokenStart.Equals(context.TokenEnd, StringComparison.OrdinalIgnoreCase);

            if (null != content && null != context.Properties)
            {
                // Look for start of tokens, order depends on type of token used
                int macroPosition = -1;

                // Evaluate from back to front if tokens are not equal
                // this enables nested tokens such as this: ${PROPERTY_${MACHINE}}
                // Evaluate from front to back if start and end tokens are equal...nested properties with
                // custom tokens that match is not supported. You can't do this: #PROPERTY_#MACHINE##
                if (!isSameTokenUsedForStartAndEnd)
                {
                    macroPosition = content.LastIndexOf(context.TokenStart);
                }
                else
                {
                    macroPosition = content.IndexOf(context.TokenStart);
                }

                while (macroPosition > -1)
                {
                    int    endMacroPosition = content.IndexOf(context.TokenEnd, macroPosition + context.TokenStart.Length);
                    string macro            = content.Substring(macroPosition, endMacroPosition - macroPosition + 1);
                    string key = macro.Substring(context.TokenStart.Length, macro.Length - (context.TokenStart.Length + context.TokenEnd.Length)).Trim();

                    string val = null;

                    // if the key starts out with "script=" treat it as an expression
                    if (key.Length > 6 &&
                        key.StartsWith("script", StringComparison.OrdinalIgnoreCase) &&
                        key.Substring(6).Trim().StartsWith("="))
                    {
                        key = key.Substring(6).Trim().Substring(1).Trim();
                        if (!string.IsNullOrEmpty(key))
                        {
                            val = ResolveExpression(key, context);
                        }
                    }
                    else if (key.Length > 8 &&
                             key.StartsWith("registry", StringComparison.OrdinalIgnoreCase) &&
                             key.Substring(8).Trim().StartsWith("="))
                    {
                        key = key.Substring(8).Trim().Substring(1).Trim();
                        if (!string.IsNullOrEmpty(key))
                        {
                            val = RegistryEvaluator.GetValue(key);
                        }
                    }
                    else
                    {
                        if (null != overriddenValues && overriddenValues.ContainsKey(key))
                        {
                            val = overriddenValues[key];
                        }
                        else
                        {
                            PreprocessingProperty property = null;

                            // Implementation of fallback properties.
                            // Go through the semicolon delimited list
                            // of properties looking for the first one that exists
                            // ex: ${PROPERTY_ABC;PROPERTY_DEF;PROPERTY}
                            // useful for machine-specific configuration
                            // when coupled with nested properties like this:
                            // ${PROPERTY_${_machine_name};PROPERTY}

                            string[] keys = key.Split(';');
                            foreach (string keyPart in keys)
                            {
                                string keyPartTrimmed = keyPart.Trim();
                                if (!string.IsNullOrEmpty(keyPartTrimmed))
                                {
                                    property = context.Properties[keyPartTrimmed];
                                    if (null != property)
                                    {
                                        break;
                                    }
                                }
                            }

                            if (null != property)
                            {
                                val = property.Value;

                                if (context.CountUsage)
                                {
                                    int useCount = CountOccurrences(content, macro);
                                    property.UseCount = property.UseCount + useCount;
                                }
                            }
                            else
                            {
                                //Pavan added code here..
                                val = "$${{" + key + "}}";
                                ConsoleUtils.WriteLine(ConsoleColor.Yellow, string.Format("The setting named '{0}' was not defined.", key));

                                //Instead of erroring out, keep macro as value and write to warning.

                                /*
                                 * val = "<!-- " + key + " not defined -->";
                                 *
                                 * if (context.ValidateSettingsExist)
                                 * {
                                 *  ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorMissingToken, context.SourceFile);
                                 *  errorInfo.Message = string.Format("The setting named '{0}' was not defined.", key);
                                 *  context.Errors.Add(errorInfo);
                                 * }*/
                            }
                        }
                    }

                    // Enable Escaping
                    if (!string.IsNullOrEmpty(val))
                    {
                        int escapedMacroStartPos = val.IndexOf(context.TokenStartEscaped);
                        int escapedMacroEndPos   = val.IndexOf(context.TokenEndEscaped);
                        if (escapedMacroStartPos > -1 && escapedMacroEndPos > escapedMacroStartPos)
                        {
                            val = val.Replace(context.TokenStartEscaped, startEscapedMacro).Replace(context.TokenEndEscaped, endEscapedMacro);
                            containedEscapedMacros = true;
                        }
                    }

                    content = content.Replace(macro, val);

                    if (!isSameTokenUsedForStartAndEnd)
                    {
                        macroPosition = content.LastIndexOf(context.TokenStart);
                    }
                    else
                    {
                        macroPosition = content.IndexOf(context.TokenStart);
                    }
                }
            }

            if (containedEscapedMacros)
            {
                content = content.Replace(startEscapedMacro, context.TokenStart).Replace(endEscapedMacro, context.TokenEnd);
            }

            return(content);
        }
Пример #15
0
        /// <summary>
        /// Reads from spreadsheet.
        /// </summary>
        /// <param name="source">The settings source.</param>
        /// <param name="context">the context.</param>
        public void LoadFromDataSource(DataSource source, PreprocessingContext context)
        {
            SettingsLoader loader = new SettingsLoader(context);

            loader.LoadSettingsFromDataSource(source, this, context.EnvironmentName);
        }
Пример #16
0
        /// <summary>
        /// Loads settings from the environment settings files.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <returns>Error code</returns>
        private static int ReadEnvironmentSettingsFile(PreprocessingContext context)
        {
            int exitCode = 0;

            bool isExtractingProperty = !string.IsNullOrEmpty(context.PropertyToExtract);

            // read settings file
            // if settings file was specified, but is empty or not found, prompt for it
            if (null != context.SettingsFiles && context.SettingsFiles.Count > 0)
            {
                for (int i = 0; i < context.SettingsFiles.Count; i++)
                {
                    string settingsFile = context.SettingsFiles[i] as string;
                    if (null != settingsFile)
                    {
                        settingsFile = settingsFile.Trim();

                        if (!FileUtils.IsHttpUrl(settingsFile) && !File.Exists(settingsFile))
                        {
                            Console.WriteLine(string.Format("\nSettings XML file not found: \"{0}\"", settingsFile));
                            if (!context.QuietMode)
                            {
                                while (true)
                                {
                                    Console.WriteLine("Enter path to settings XML file, leave blank if no settings are required.");
                                    Console.Write("Settings XML file: ");
                                    settingsFile = Console.ReadLine().Trim();

                                    if (settingsFile.Length == 0)
                                    {
                                        break;
                                    }

                                    if (File.Exists(settingsFile))
                                    {
                                        break;
                                    }

                                    Console.WriteLine(string.Format("Settings XML file not found: \"{0}\"", settingsFile));
                                }
                            }
                        }
                        else
                        {
                            if (!isExtractingProperty)
                            {
                                Console.WriteLine(string.Format("Settings XML file: \"{0}\"", settingsFile));
                            }
                        }

                        if (null != settingsFile && settingsFile.Length > 0)
                        {
                            try
                            {
                                context.Properties.ReadFromFile(settingsFile, context.EnvironmentName);
                            }
                            catch (XmlException xe)
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                                errorInfo.Message = string.Format("Error parsing {0}: {1} at line {2}", settingsFile, xe.Message, xe.LineNumber);
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }
                            catch (Exception e)
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                                errorInfo.Message = string.Format("Error parsing {0}: {1}", settingsFile, e.Message);
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }
                        }
                    }
                }
            }

            return(exitCode);
        }
Пример #17
0
        /// <summary>
        /// Process the body of a macro expression.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <param name="keyword">Keyword (#if or #ifdef).</param>
        /// <param name="condition">Condition to test.</param>
        /// <param name="body">Body of macro expression.</param>
        /// <returns>Returns the preprocessed result of the macro expression.</returns>
        private string ProcessBody(PreprocessingContext context, string keyword, string condition, string body)
        {
            string ifbody        = null;
            string elsebody      = null;
            bool   hasElse       = false;
            bool   conditionTrue = false;

            ////////////
            //for (Match matchElif = regexElif.Match(body);
            //    matchElif.Success;
            //    matchElif = matchElif.NextMatch())
            //{
            //}
            ////////////

            Match matchElse = regexElse.Match(body);

            if (matchElse.Success)
            {
                hasElse = true;

                ifbody   = body.Substring(0, matchElse.Index);
                elsebody = body.Substring(matchElse.Index + matchElse.Length);
            }
            else
            {
                ifbody = body;
            }

            string result = "";

            conditionTrue = false;
            if (keyword.EndsWith("ifdef"))
            {
                conditionTrue = (!string.IsNullOrEmpty(condition) && context.Properties.ContainsKey(condition));
            }
            else
            {
                DynamicEvaluator evaluator = new DynamicEvaluator();
                conditionTrue = evaluator.EvaluateToBool(context, condition);
            }

            if (context.PreserveMarkup)
            {
                string whitespacePrefix = "";
                for (int i = 0; i < ifbody.Length; i++)
                {
                    if (!Char.IsWhiteSpace(ifbody[i]))
                    {
                        whitespacePrefix = ifbody.Substring(0, i);
                        break;
                    }
                }
                string commentedOutIfBody = RemoveComment(ifbody, false).Trim();
                if (null != commentedOutIfBody && commentedOutIfBody.Length > 0)
                {
                    if (commentedOutIfBody.IndexOf('\n') > -1) // multi-line
                    {
                        result += whitespacePrefix + "<!--" + whitespacePrefix + commentedOutIfBody + whitespacePrefix + "-->";
                    }
                    else // single line
                    {
                        result += whitespacePrefix + "<!-- " + commentedOutIfBody + " -->";
                    }
                }

                if (!hasElse) // always add an else
                {
                    if (keyword.StartsWith("#"))
                    {
                        result += whitespacePrefix + "<!-- #else -->";
                    }
                    else
                    {
                        result += whitespacePrefix + "<!-- else -->";
                    }
                }
                else
                {
                    result += body.Substring(matchElse.Index, matchElse.Length);
                }
            }

            if (conditionTrue)
            {
                if (context.PreserveMarkup && !hasElse)
                {
                    result += ResolveProperties(RemoveComment(ifbody, true), context);
                }

                if (!(context.PreserveMarkup && !hasElse))
                {
                    result += ResolveProperties(RemoveComment(ifbody, true), context);
                }

                if (context.PreserveMarkup && hasElse && 0 == ifbody.Trim().Length)
                {
                    result += "<!-- " + RemoveComment(elsebody, false) + " -->";
                }
            }
            else
            {
                if (hasElse)
                {
                    result += elsebody;
                }
            }

            return(result);
        }
Пример #18
0
        /// <summary>
        /// Process the file.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <param name="content">Contents of a file as a string.</param>
        /// <returns>Returns the file contents with preprocessing applied.</returns>
        private string Process(PreprocessingContext context, string content)
        {
            StringBuilder result = new StringBuilder();
            int           offset = 0;

            if (context.NoDirectives)
            {
                result.Append(ResolveProperties(content, context));
            }
            else
            {
                for (Match matchIfdef = regexIfdef.Match(content);
                     matchIfdef.Success;
                     matchIfdef = matchIfdef.NextMatch())
                {
                    if (context.PreserveMarkup)
                    {
                        result.Append(content.Substring(offset, (matchIfdef.Index + matchIfdef.Length) - offset));
                    }
                    else
                    {
                        result.Append(content.Substring(offset, matchIfdef.Index - offset));
                    }

                    offset = matchIfdef.Index + matchIfdef.Length;

                    Match matchEndif = regexEndif.Match(content, offset);
                    if (matchEndif.Success)
                    {
                        string condition = RemoveMacro(context, matchIfdef.Groups["condition"].Value);
                        string keyword   = RemoveMacro(context, matchIfdef.Groups["keyword"].Value);
                        string body      = content.Substring(offset, matchEndif.Index - offset);

                        // Check to see if there is another ifdef in the body,
                        // if so, it is an error
                        Match matchErroneousIfdef = regexIfdef.Match(body);
                        if (matchErroneousIfdef.Success)
                        {
                            throw new Exception("Comments are malformed, endif missing.");
                        }

                        offset = matchEndif.Index + matchEndif.Length;

                        result.Append(ProcessBody(context, keyword, condition, body));

                        if (context.PreserveMarkup)
                        {
                            result.Append(content.Substring(matchEndif.Index, matchEndif.Length));
                        }
                    }
                    else
                    {
                        throw new Exception("Comments are malformed, no endif found.");
                    }
                }

                result.Append(content.Substring(offset));
            }

            return(ProcessDynamicallyBoundProperties(context, result.ToString()));
        }
Пример #19
0
        /// <summary>
        /// Processes the #includes
        /// </summary>
        /// <param name="context">The Preprocessing context.</param>
        /// <param name="content">The content.</param>
        private string ProcessIncludes(PreprocessingContext context, string content)
        {
            while (true)
            {
                Match matchInclude = regexInclude.Match(content);
                if (!matchInclude.Success)
                {
                    break;
                }

                Group fileGroup  = matchInclude.Groups["file"];
                Group xpathGroup = matchInclude.Groups["xpath"];

                if (null != fileGroup && !string.IsNullOrEmpty(fileGroup.Value))
                {
                    string file = fileGroup.Value.Trim();
                    // replace any macros in file name
                    string resolvedFile = ResolveProperties(file, context, null);

                    if (context.Errors.Count > 0)
                    {
                        return(content);
                    }

                    // turn relative paths into fully qualified relative to the location of source file
                    if (!Path.IsPathRooted(resolvedFile))
                    {
                        resolvedFile = Path.Combine(Path.GetDirectoryName(context.SourceFile), resolvedFile);
                    }

                    if (!File.Exists(resolvedFile))
                    {
                        throw new FileNotFoundException(string.Format("Could not find file {0}", resolvedFile), resolvedFile);
                    }

                    string source = "";

                    if (null != xpathGroup && !string.IsNullOrEmpty(xpathGroup.Value))
                    {
                        string xpathUnresolved = xpathGroup.Value.Trim();
                        // replace any macros in xpath
                        string xpath = ResolveProperties(xpathUnresolved, context, null);

                        if (context.Errors.Count > 0)
                        {
                            return(content);
                        }

                        source = GetXmlContentFromIncludeFile(resolvedFile, xpath);
                    }
                    else
                    {
                        // Load file
                        source = FileUtils.LoadFile(resolvedFile);
                    }

                    // Insert contents
                    content = content.Substring(0, matchInclude.Index) +
                              source +
                              content.Substring(matchInclude.Index + matchInclude.Length);
                }
            }

            return(content);
        }
Пример #20
0
 /// <summary>
 /// Gets the dynamic resolver.
 /// </summary>
 /// <param name="context">The preeprocessing context.</param>
 /// <returns></returns>
 public IDynamicResolver GetDynamicResolver(PreprocessingContext context)
 {
     return(DynamicBindingExpression.Parse(context, Key) as IDynamicResolver);
 }
Пример #21
0
        /// <summary>
        /// Reads the settings from data sources.
        /// </summary>
        /// <param name="context">The preprocessing context.</param>
        /// <returns>Error code</returns>
        private static int ReadSettingsFromDataSources(PreprocessingContext context)
        {
            int exitCode = 0;

            bool isExtractingProperty = !string.IsNullOrEmpty(context.PropertyToExtract);

            // read settings file
            // if data sources were specified, but environment was not, prompt for it
            if (null != context.DataSources && context.DataSources.Count > 0)
            {
                foreach (DataSource dataSource in context.DataSources)
                {
                    if (!dataSource.Exists)
                    {
                        ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorFileNotFound, context.SourceFile);
                        errorInfo.Message = string.Format("Settings data source not found: \"{0}\"", dataSource);
                        context.Errors.Add(errorInfo);
                        exitCode = 1;
                        break;
                    }
                    else
                    {
                        if (!isExtractingProperty)
                        {
                            Console.WriteLine(string.Format("Settings data source: \"{0}\"", dataSource));
                        }
                    }

                    if (!string.IsNullOrEmpty(dataSource.Path))
                    {
                        if (!context.QuietMode && string.IsNullOrEmpty(context.EnvironmentName))
                        {
                            context.EnvironmentName = PromptForEnvironment(dataSource, context);
                        }

                        if (string.IsNullOrEmpty(context.EnvironmentName))
                        {
                            ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                            errorInfo.Message = string.Format("Error loading settings from {0}, environment name was not supplied.", dataSource);
                            context.Errors.Add(errorInfo);
                            exitCode = 1;
                            break;
                        }
                        else
                        {
                            try
                            {
                                context.Properties.LoadFromDataSource(dataSource, context);
                            }
                            catch (XmlException xe)
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                                errorInfo.Message = string.Format("Error loading settings from {0}, {1} at line {2}", dataSource, xe.Message, xe.LineNumber);
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }
                            catch (Exception e)
                            {
                                ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorException, context.SourceFile);
                                errorInfo.Message = string.Format("Error loading settings from {0}, {1}", dataSource, e.Message);
                                context.Errors.Add(errorInfo);
                                exitCode = 1;
                                break;
                            }
                        }
                    }
                }
            }

            return(exitCode);
        }
Пример #22
0
        /// <summary>
        /// Replace any macros with their property value.
        /// </summary>
        /// <param name="content">Content in which to replace all macros.</param>
        /// <param name="context">The preprocessing context.</param>
        /// <returns>The content with macros replaced with corresponding property values.</returns>
        private string ResolveProperties(string content, PreprocessingContext context)
        {
            // search for the #foreach(property1,property2) construct which
            // expands the content multiple times
            Match match = regexForEach.Match(content);

            if (match.Success)
            {
                Group nameGroup = match.Groups["name"];
                if (null != nameGroup && !string.IsNullOrEmpty(nameGroup.Value))
                {
                    // Remove the #foreach(...) construct
                    Group foreachEndGroup = match.Groups["foreachend"];
                    content = content.Substring(0, match.Groups["foreachstart"].Index) +
                              content.Substring(foreachEndGroup.Index + foreachEndGroup.Length);

                    string combinedContent = "";

                    // if the foreach contains a prefix and wildcard,
                    // (For example "SomePrefix*") handle it differently
                    if (!string.IsNullOrWhiteSpace(nameGroup.Value) &&
                        nameGroup.Value.Length > 0 &&
                        nameGroup.Value.IndexOf(',') < 0 &&
                        nameGroup.Value.EndsWith("*"))
                    {
                        string prefix = nameGroup.Value.Substring(0, nameGroup.Value.Length - 1);
                        foreach (PreprocessingProperty property in context.Properties)
                        {
                            if (property.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                            {
                                // values to override when resolving properties within repeated body
                                Dictionary <string, string> overriddenValues = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                                overriddenValues.Add("_.Key", property.Key);
                                overriddenValues.Add("_.KeyNoPrefix", property.Key.Substring(prefix.Length));
                                overriddenValues.Add("_.Value", property.Value);

                                combinedContent += ResolveProperties(content, context, overriddenValues);
                            }
                        }
                    }
                    else
                    {
                        // Get the values to expand
                        int maxCount = 0;
                        Dictionary <string, string[]> compoundValues =
                            ExtractForEachProperties(nameGroup.Value, context, out maxCount);

                        // Loop through the largest collection
                        for (int i = 0; i < maxCount; i++)
                        {
                            // values to override when resolving properties within repeated body
                            Dictionary <string, string> overriddenValues = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                            // override all looped properties
                            foreach (string key in compoundValues.Keys)
                            {
                                string   overriddenValue = "";
                                string[] values          = compoundValues[key];
                                if (values.Length > i)
                                {
                                    overriddenValue = values[i];
                                }

                                overriddenValues.Add(key, overriddenValue.Trim());
                            }

                            combinedContent += ResolveProperties(content, context, overriddenValues);
                        }
                    }

                    return(combinedContent);
                }
            }

            return(ResolveProperties(content, context, null));
        }
Пример #23
0
        /// <summary>
        /// Creates the preprocessing context.
        /// </summary>
        /// <returns>A new preprocessing context</returns>
        public PreprocessingContext CreatePreprocessingContext()
        {
            // Create the preprocessing context
            PreprocessingContext context = new PreprocessingContext(fixFalse);

            context.SettingsFiles  = settings;
            context.PreserveMarkup = !clean;
            context.QuietMode      = quiet;
            if (validate)
            {
                context.ValidateSettingsExist = true;
                context.ValidateXmlWellFormed = true;
            }
            else
            {
                context.ValidateSettingsExist = validateSettingsExist;
                context.ValidateXmlWellFormed = validateXmlWellFormed;
            }

            // create data sources collection
            List <DataSource> dataSources = new List <DataSource>();

            foreach (string spreadsheetFile in spreadsheet)
            {
                DataSourceSpreadsheetFormat spreadsheetFormat = DetermineSpreadsheetFormat(spreadsheetFile);
                dataSources.Add(new DataSource(spreadsheetFile, DataSourceType.Spreadsheet, spreadsheetFormat));
            }

            foreach (string databaseConnectionString in database)
            {
                dataSources.Add(new DataSource(databaseConnectionString, DataSourceType.Database));
            }

            foreach (string customCommandLineString in custom)
            {
                dataSources.Add(new DataSource(customCommandLineString, DataSourceType.Custom));
            }

            context.DataSources = dataSources;

            context.EnvironmentName         = environment;
            context.FirstValueRowIndex      = firstValueRow;
            context.EnvironmentNameRowIndex = environmentRow;
            context.DefaultValueColumnIndex = defaultValueCol;
            context.SettingNameColumnIndex  = settingNameCol;
            context.List = list;
            context.PropertyToExtract = property;
            context.Delimiters        = delimiters;
            context.NoDirectives      = noDirectives;
            context.CountUsage        = !string.IsNullOrEmpty(countReportFile);

            if (!string.IsNullOrEmpty(tokenStart))
            {
                context.TokenStart = tokenStart;

                if (string.IsNullOrEmpty(tokenEnd))
                {
                    context.TokenEnd = tokenStart;
                }
            }

            if (!string.IsNullOrEmpty(tokenEnd))
            {
                context.TokenEnd = tokenEnd;
            }

            return(context);
        }
Пример #24
0
        /// <summary>
        /// Extracts for each properties.
        /// </summary>
        /// <param name="compoundValueNames">The compound value names.</param>
        /// <param name="context">The context.</param>
        /// <param name="maxCount">The max count.</param>
        /// <returns></returns>
        private Dictionary <string, string[]> ExtractForEachProperties(string compoundValueNames, PreprocessingContext context, out int maxCount)
        {
            maxCount = 0;
            Dictionary <string, string[]> compoundValues = new Dictionary <string, string[]>();

            string[] compoundValueNamesArray = compoundValueNames.Split(',');
            foreach (string compoundValueName in compoundValueNamesArray)
            {
                string compoundValueNameTrimmed = compoundValueName.Trim();
                if (!string.IsNullOrEmpty(compoundValueNameTrimmed))
                {
                    string compoundValue = "";
                    PreprocessingProperty compoundProperty = context.Properties[compoundValueNameTrimmed];
                    if (null != compoundProperty)
                    {
                        compoundValue = ResolveProperties(compoundProperty.Value, context, null);
                    }

                    string[] compoundValuesArray = null;
                    if (!string.IsNullOrEmpty(compoundValue))
                    {
                        compoundValuesArray = compoundValue.Split(';');
                        if (compoundValuesArray.Length > maxCount)
                        {
                            maxCount = compoundValuesArray.Length;
                        }
                    }

                    compoundValues.Add(compoundValueNameTrimmed, compoundValuesArray);
                }
            }

            return(compoundValues);
        }