/// <summary> /// Traverses the nodes inheritance path to build a single flat delimeted line of /// inheritance paths. /// e.g. returns "Prod,Uat,Qa,Dev". /// </summary> /// <returns></returns> public static string ConvertNestedToFlatInheritance(EnvItem env, IDictionary <string, EnvItem> envItems) { // Return name of environment provided if it doesn't have // any inheritance chain. if (string.IsNullOrEmpty(env.Inherits)) { return(env.Name); } // Single parent. if (env.Inherits.IndexOf(",") < 0) { // Get the parent. EnvItem parent = envItems[env.Inherits.Trim().ToLower()]; return(env.Name + "," + ConvertNestedToFlatInheritance(parent, envItems)); } // Multiple parents. string[] parents = env.Inherits.Split(','); string path = env.Name; foreach (string parent in parents) { EnvItem parentEnv = envItems[env.Inherits.Trim().ToLower()]; path += "," + ConvertNestedToFlatInheritance(parentEnv, envItems); } return(path); }
/// <summary> /// Get list of inherited environments. /// </summary> /// <param name="selectedEnv">"prod,qa,dev"</param> /// <param name="firstEnv"></param> /// <returns></returns> public static List <EnvItem> Parse(string selectedEnv, out string firstEnv) { // Validate. if (string.IsNullOrEmpty(selectedEnv)) { throw new ArgumentException("Must provide the selected environment."); } List <string> envsSelected = ParseEnvsToNames(selectedEnv); // Create the environment. firstEnv = envsSelected[0]; EnvItem env = new EnvItem(firstEnv, false, EnvUtils.GetEnvType(firstEnv), string.Empty); List <EnvItem> envs = new List <EnvItem>() { env }; // More than 1 supplied. This represents an inheritance path. if (envsSelected.Count > 1) { for (int ndx = 1; ndx < envsSelected.Count; ndx++) { string envName = envsSelected[ndx]; var newEnv = new EnvItem(envName, false, EnvUtils.GetEnvType(envName), ""); envs.Add(newEnv); // Append the inheritance path to the first one. envs[0].Inherits += (string.IsNullOrEmpty(env.Inherits)) ? envName : "," + envName; } } return(envs); }
/// <summary> /// Set the current environment. /// </summary> /// <param name="envName"></param> public void Set(string envName) { if (!_ctx.EnvsByName.ContainsKey(envName)) { throw new ArgumentException("Environment " + envName + " does not exist."); } // set the current environment. _current = _ctx.EnvsByName[envName]; Load(); // Notify. if (OnEnvironmentChange != null) { OnEnvironmentChange(this, new EventArgs()); } }
/// <summary> /// Set the current environment. /// </summary> /// <param name="envName"></param> public void Change(string envName) { envName = envName.ToLower().Trim(); if (!_availableEnvs.ContainsKey(envName)) { throw new ArgumentException("Environment " + envName + " does not exist."); } // Set the current environment and Name. _selected = _availableEnvs[envName]; Name = envName; // Get list of all available environment names. _availableEnvNames = (from env in _availableEnvsList select env.Name).ToList <string>(); // Notify. if (OnEnvironmentChange != null) { OnEnvironmentChange(this, new EventArgs()); } }
/// <summary> /// Set the current environment. /// </summary> /// <param name="envName"></param> public void Change(string envName) { envName = envName.ToLower().Trim(); if (!_availableEnvs.ContainsKey(envName)) { throw new ArgumentException("Environment " + envName + " does not exist."); } // 1: Set the current environment and Name. _selected = _availableEnvs[envName]; Name = envName; // 2. Get list of all available environment names. _availableEnvNames = (from env in _availableEnvsList select env.Name).ToList <string>(); // 3. Get the inheritance chain if applicable. // e.g. if prod inherits from qa. List containing Prod,Qa _inheritancePath = EnvUtils.ConvertNestedToFlatInheritance(_selected, _availableEnvs); // 4. Get the ref path. // If inherited, then combine all the ref paths. // e.g. if prod(prod.config) inherits qa(qa.config) inherits dev(dev.config) // refPath = "prod.config,qa.config,dev.config". if (string.IsNullOrEmpty(_selected.Inherits)) { _refPath = _selected.RefPath; } else { List <EnvItem> inheritanceChain = EnvUtils.LoadInheritance(_selected, _availableEnvs); _refPath = EnvUtils.CollectEnvironmentProps(inheritanceChain, ",", env => env.RefPath); } // Notify. if (OnEnvironmentChange != null) { OnEnvironmentChange(this, new EventArgs()); } }
/// <summary> /// Loads an inheritance chain delimited by ,(comma) /// </summary> /// <param name="delimitedInheritancePath"></param> /// <param name="ctx"></param> /// <returns></returns> public static List <EnvItem> LoadInheritance(EnvItem coreEnv, IDictionary <string, EnvItem> envItems) { // No inheritance chain. if (string.IsNullOrEmpty(coreEnv.Inherits)) { return new List <EnvItem>() { coreEnv } } ; string inheritancePath = coreEnv.Inherits; StringBuilder buffer = new StringBuilder(); // Get flat list "prod,uat,qa,dev" from traversing the refrenced nodes. if (coreEnv.InheritsDeeply) { inheritancePath = ConvertNestedToFlatInheritance(coreEnv, envItems); } string[] parents = inheritancePath.Split(','); List <EnvItem> inheritanceList = new List <EnvItem>() { coreEnv }; // Build inheritance path where the first one is the core, following the // older parents. foreach (string parent in parents) { if (envItems.ContainsKey(parent)) { EnvItem parentEnv = envItems[parent]; inheritanceList.Add(parentEnv); } } return(inheritanceList); }
/// <summary> /// Parse the selected environments and config paths. /// </summary> /// <param name="envs"> /// 1. "prod,qa,dev". If the names are the same as the types. /// 2. "prod1:prod,qa1:qa,mydev:dev" If the names are different that the env type names. /// </param> /// <returns>List of environment items.</returns> public static List <EnvItem> ParseEnvsToItems(string envs) { string[] envNames = envs.Contains(",") ? envs.Split(',') : new string[] { envs }; var envItems = new List <EnvItem>(); foreach (string env in envNames) { // Check for ":" which indicates name/type pair. string envName = env; string envType = env; if (env.Contains(":")) { envName = env.Substring(0, env.IndexOf(":")); envType = env.Substring(env.IndexOf(":") + 1); } EnvItem item = new EnvItem(); item.Name = envName; item.EnvType = EnvUtils.GetEnvType(envType); item.IsSelectable = true; item.Inherits = string.Empty; envItems.Add(item); } return(envItems); }
/// <summary> /// Set the current environment and also supply available environment names/types. /// </summary> /// <param name="selected">"prod" or "prod1". This should match the name /// from <paramref name="availableEnvsCommaDelimited"/></param> /// <param name="availableEnvsCommaDelimited"> /// 1. "prod,qa,dev". If the names are the same as the types. /// 2. "prod1:prod,qa1:qa,mydev:dev" If the names are different that the env type names. /// </param> /// <param name="refPaths">The config reference paths. e.g. "prod.config,qa.config".</param> /// <param name="enableInheritance">Whether or not environment inheritance is enabled.</param> public static void Set(string selected, string availableEnvsCommaDelimited, string refPaths, bool distributeRefPaths, bool enableInheritance) { // Check available envs were supplied. if (string.IsNullOrEmpty(availableEnvsCommaDelimited)) { availableEnvsCommaDelimited = "prod,uat,qa,dev"; } // Parse "prod,uat,qa,dev" to List of EnvItems. var availableEnvs = EnvUtils.ParseEnvsToItems(availableEnvsCommaDelimited); // Environment Inheritance enabled. Default setup is : // e.g. Available Environments are "prod,uat,qa,dev". // Default inheritance becomes : // prod inherits uat // uat inherits qa // qa inherits dev if (enableInheritance) { for (int ndx = 0; ndx <= availableEnvs.Count - 2; ndx++) { availableEnvs[ndx].Inherits = availableEnvs[ndx + 1].Name; } foreach (EnvItem env in availableEnvs) { env.InheritsDeeply = true; } } // Check if refpaths(configs) were supplied. bool hasConfigs = !string.IsNullOrEmpty(refPaths); string[] configs = hasConfigs ? refPaths.Split(',') : new string[] { }; EnvItem selectedEnv = (from env in availableEnvs where string.Compare(env.Name, selected, true) == 0 select env).First <EnvItem>(); if (hasConfigs) { // Case 1: Single config file = "prod.config" if (configs.Length == 1) { selectedEnv.RefPath = refPaths; } // Case 2: Multiple config files "prod.config,qa.config" and not distributing across the env's. // This means that ref paths "prod.config,qa.config" will be set on "selected" environment. else if (configs.Length > 1 && !distributeRefPaths) { selectedEnv.RefPath = refPaths; } // Case 3: Multiple config files should be distributed to each environment. // e.g. "prod,qa,dev", "prod.config,qa.config,dev.config". // Apply prod.config to "prod" refpath, qa.config to "qa" refPath, dev.config to "dev" refpath. else if (configs.Length > 1 && distributeRefPaths) { string error = string.Format("The number of reference paths({0}) must be less than or equal to the number of environments({1}).", configs.Length, availableEnvs.Count); Guard.IsTrue(availableEnvs.Count >= configs.Length, error); for (int ndx = 0; ndx < availableEnvs.Count; ndx++) { availableEnvs[ndx].RefPath = configs[ndx]; } } } Set(Default, selected, availableEnvs); }