/// <summary> /// Applies the xml changes to this instance. /// </summary> /// <returns></returns> public Boolean Run() { //Add them in a specific order foreach (XmlAdd mod in file.Add) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "ADD", 27, MessageImportance.High, log); LogModificationDetails(mod.xpath, mod.attribute, mod.Value, string.Empty, log); Add(mod); } foreach (XmlUpdate mod in file.Update) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "UPDATE", 27, MessageImportance.High, log); LogModificationDetails(mod.xpath, string.Empty, mod.Value, string.Empty, log); Update(mod); } foreach (XmlReplace mod in file.Replace) { //HACK: This is not pretty...anytime I use out I swear a puppy dies somewhere... mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "REPLACE", 27, MessageImportance.High, log); LogModificationDetails(string.Empty, string.Empty, mod.Value, mod.regex, log); int count = 0; document.LoadXml(RenderConfigEngine.RegExParseAndReplace(out count, mod.regex, mod.Value, document.OuterXml.ToString())); LogUtilities.LogCount(count, log); } foreach (XmlDelete mod in file.Delete) { LogUtilities.LogKeyValue("TYPE", "DELETE", 27, MessageImportance.High, log); LogModificationDetails(mod.xpath, string.Empty, mod.Value, string.Empty, log); Delete(mod); } //TODO: Make sure that we stamp the renderconfig data if required if (config.StampRenderData) { XmlComment comment = document.CreateComment("Test Comment"); document.FirstChild.AppendChild(comment); } //HACK Why oh why are XmlWriterSettings and XmlReaderSettings SOOO SIMILAR, and yet.... XmlWriterSettings writerSettings = GetXmlWriterSettings(config.CleanOutput, document); using (XmlWriter writer = XmlWriter.Create(targetFile, writerSettings)) { document.Save(writer); } //HACK BAD returnCode = true; return(returnCode); }
/// <summary> /// Logs the node count. /// </summary> /// <param name="nodes">The nodes.</param> /// <param name="breakOnNoMatch">if set to <c>true</c> [break on no match].</param> private void LogNodeCount(XmlNodeList nodes, Boolean breakOnNoMatch) { LogUtilities.LogCount(nodes.Count, log); if (breakOnNoMatch) { throw new Exception("Could not find match"); } }
/// <summary> /// Logs the modification details. /// </summary> /// <param name="section">The section.</param> /// <param name="key">The key.</param> /// <param name="value">The value.</param> /// <param name="regex">The regex.</param> /// <param name="log">The log.</param> private static void LogModificationDetails(string section, string key, string value, string regex, IRenderConfigLogger log) { if (String.IsNullOrEmpty(section)) { LogUtilities.LogKeyValue("SECTION", section, 27, MessageImportance.Normal, log); } if (String.IsNullOrEmpty(key)) { LogUtilities.LogKeyValue("KEY", key, 27, MessageImportance.Normal, log); } //Dont output if we are deleting a key, it just doesnt make sense if (!String.IsNullOrEmpty(value)) { LogUtilities.LogKeyValue("VALUE", value.Trim(), 27, MessageImportance.Normal, log); } }
/// <summary> /// Runs this modification. /// </summary> /// <returns></returns> public bool Run() { if (config.StampRenderData) { //TODO: Nini doesnt seem to do comments for us, need to do this by hand. } //Add them in a specific order foreach (IniAdd mod in file.Add) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "ADD", 27, MessageImportance.High, log); LogModificationDetails(mod.section, mod.key, mod.Value, string.Empty, log); Add(mod); } foreach (IniUpdate mod in file.Update) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "Update", 27, MessageImportance.High, log); LogModificationDetails(mod.section, mod.key, mod.Value, string.Empty, log); Update(mod); } foreach (IniReplace mod in file.Replace) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "ADD", 27, MessageImportance.High, log); LogModificationDetails(string.Empty, string.Empty, mod.Value, mod.regex, log); LogUtilities.LogCount(RenderConfigEngine.ReplaceTokenInFile(mod.regex, mod.Value, targetFile), log); } foreach (IniDelete mod in file.Delete) { LogUtilities.LogKeyValue("TYPE", "DELETE", 27, MessageImportance.High, log); LogModificationDetails(mod.section, mod.key, string.Empty, string.Empty, log); Delete(mod); } //HACK BAd returnCode = true; return(returnCode); }
/// <summary> /// Logs the modification details. /// </summary> /// <param name="xpath">The xpath.</param> /// <param name="attribute">The attribute.</param> /// <param name="value">The value.</param> /// <param name="regex">The regex.</param> /// <param name="log">The log.</param> private static void LogModificationDetails(string xpath, string attribute, string value, string regex, IRenderConfigLogger log) { if (!String.IsNullOrEmpty(xpath)) { LogUtilities.LogKeyValue("XPATH", xpath, 27, MessageImportance.Normal, log); } if (!String.IsNullOrEmpty(attribute)) { LogUtilities.LogKeyValue("ATTRIBUTE", attribute, 27, MessageImportance.Normal, log); } if (!String.IsNullOrEmpty(value)) { LogUtilities.LogKeyValue("VALUE", value, 27, MessageImportance.Normal, log); } if (!String.IsNullOrEmpty(regex)) { LogUtilities.LogKeyValue("REGEX", regex, 27, MessageImportance.Normal, log); } }
/// <summary> /// Check and modify source and destination file based on input and output directory existence, and a set of configuration values /// </summary> /// <param name="config">The config.</param> /// <param name="file">The file.</param> private void CheckAndModifySourceAndDestination(RenderConfigConfig config, ITargetFile file) { //Check to see if we want to preserve the directory structure.... file.source = CleansePlatformSpecificDirectoryMarkers(file.source); FileInfo t = new FileInfo(file.source); if (config.PreserveSourceStructure) { if (file.destination == null) { file.destination = file.source; } else { //TODO This is broken if (file.source.IndexOf(t.Name) != Path.DirectorySeparatorChar) { char badSep = file.source[file.source.IndexOf(t.Name)]; file.source.Replace(badSep, Path.DirectorySeparatorChar); } file.destination = Path.Combine(file.source.Replace(t.Name, string.Empty), file.destination); } } //Now check to see if the input directory has been provided, and modify the file object to represent the change of relative path if so if (config.InputDirectory != null) { file.source = Path.Combine(config.InputDirectory, file.source); } else { file.source = t.FullName; } LogUtilities.LogTargetFileHeader(file.source, file.destination, config.InputDirectory, config.OutputDirectory, log); //Check if it exists now... if (!File.Exists(file.source)) { throw new Exception("Could not find source file " + file.source); } }
/// <summary> /// Runs this instance. /// </summary> /// <returns></returns> public bool Run() { int count = 0; foreach (IniReplace mod in file.Replace) { mod.Value = RenderConfigEngine.ReplaceEnvironmentVariables(mod.Value); LogUtilities.LogKeyValue("TYPE", "REPLACE", 27, MessageImportance.High, log); LogUtilities.LogKeyValue("REGEX", mod.regex, 27, MessageImportance.Normal, log); LogUtilities.LogKeyValue("VALUE", mod.Value, 27, MessageImportance.Normal, log); count = RenderConfigEngine.ReplaceTokenInFile(mod.regex, mod.Value, targetFile); LogUtilities.LogCount(count, log); } //TODO if (config.BreakOnNoMatch && count == 0) { return(false); } else { return(true); } }
/// <summary> /// Renders the configuration specified. /// </summary> /// <returns></returns> public bool Render() { LogUtilities.LogSettings(config, log); nodeList = new List <Node <string> >(); Boolean returnCode = true; if (File.Exists(config.ConfigFile)) { log.LogMessage("Reading in configuration file..."); RenderConfig renderConfig = ReadConfigurationFile(); if (renderConfig != null) { //HACK We should be using a deep copy so that all this becomes "variableStack = dependencyStack.Clone();" //Get the list of nodes nodeList = GenerateNodeList(renderConfig, log); if (SearchForNodeByIdentity(nodeList, config.Configuration) == null) { throw new ApplicationException("Could not find Configuration : " + config.Configuration); } List <Node <string> > n2 = GenerateNodeList(renderConfig, log); //Generate the dependency path DepthFirstSearch <string> dfs = new DepthFirstSearch <string>(nodeList); DepthFirstSearch <string> dfs2 = new DepthFirstSearch <string>(n2); dependencyStack = dfs.GetDependencyPath(config.Configuration); //HACK Need to write a deep copy Queue Clone to get rid of this... variableStack = dfs2.GetDependencyPath(config.Configuration); } if (Directory.Exists(config.OutputDirectory)) { if (config.DeleteOutputDirectory) { log.LogMessage("Deleting and recreating output directory..."); Directory.Delete(config.OutputDirectory, true); Directory.CreateDirectory(config.OutputDirectory); } } else { log.LogMessage("Creating output directory..."); Directory.CreateDirectory(config.OutputDirectory); } //Create a queue of mods to run and a queue of EnvironmentVariables to implement //Variables have to be put in place before the mods... log.LogMessage("Building dependency queue..."); Queue <Configuration> configsToRun = CreateConfigProcessQueue(renderConfig, dependencyStack); //HACK This is ugly, needs a deep copy here.... Queue <Configuration> envQueue = CreateConfigProcessQueue(renderConfig, variableStack); while (envQueue.Count > 0) { Configuration varConfig = envQueue.Dequeue(); //First, we need to get all the Variables and create them. foreach (EnvironmentVariable variable in varConfig.EnvironmentVariables) { Environment.SetEnvironmentVariable(variable.variable, variable.Value); } } while (configsToRun.Count > 0) { Configuration currentConfig = configsToRun.Dequeue(); log.LogMessage(MessageImportance.High, "Running modification: " + currentConfig.Name); if (currentConfig.TargetFiles != null) { if (!currentConfig.Apply(config, log)) { log.LogError("Failed to apply configuration: " + currentConfig.Name); returnCode = false; } } } } else { log.LogError("Could not find configuration file: " + config.ConfigFile); returnCode = false; } //Let 'em know if (returnCode) { log.LogMessage(MessageImportance.High, "Configuration rendered!"); } else { log.LogError("Failed to render configuration."); } return(returnCode); }
/// <summary> /// Logs the count of applied modifications. /// </summary> /// <param name="log">The log.</param> private void LogCount(IRenderConfigLogger log) { LogUtilities.LogCount(1, log); }