示例#1
0
        protected void ParseDownloadUrl()
        {
            if (RepoUrlPath[0].Equals('/') || RepoUrlPath[0].Equals('\\'))
            {
                Logging.Debug("Removing extra slash from the start of the URL");
                RepoUrlPath = RepoUrlPath.Substring(1);
            }

            AutomationMacro automationXmlRepoFilebaseEscapedMacro = Macros.Find(macro => macro.Name.Equals("automationRepoRoot"));

            if (automationXmlRepoFilebaseEscapedMacro == null)
            {
                throw new BadMemeException("This shouldn't happen. Like literally. Should. Not. Happen.");
            }

            if (AutomationSettings.UseLocalRunnerDatabase)
            {
                RepoUrlPath  = RepoUrlPath.Replace('/', '\\');
                fullFilepath = Path.Combine(Path.GetDirectoryName(AutomationSettings.LocalRunnerDatabaseRoot), RepoUrlPath);
            }
            else
            {
                if (RepoUrlPath.Contains("\\"))
                {
                    Logging.Warning("The RepoUrlPath argument contains folder seperator chars, but should be http url slashes");
                    RepoUrlPath = RepoUrlPath.Replace('\\', '/');
                }
                fullFilepath = automationXmlRepoFilebaseEscapedMacro.Value + RepoUrlPath;
            }

            Logging.Debug("Parsed RepoUrlPath to resolve to {0}", fullFilepath);
        }
        protected override void ImportList()
        {
            Logging.Debug("Setting each parsed macro as local, overriding if other local macro exists");

            List <AutomationMacro> macroList = objectList as List <AutomationMacro>;

            foreach (AutomationMacro macro in macroList)
            {
                macro.MacroType = MacroType.Local;

                //check if macro already exists
                AutomationMacro result = Macros.Find(mac => mac.Name.ToLower().Equals(macro.Name.ToLower()));
                if (result != null)
                {
                    if (result.MacroType != MacroType.Local)
                    {
                        Logging.Error("The parsed macro {{{0}}} already exists in the current macro list as macro type {1}, and cannot be overridden.", result.Name, result.MacroType.ToString());
                        continue;
                    }
                    else
                    {
                        Logging.Info("The parsed macro {{{0}}} already exists in the current macro list as macro type {1} with value {2}, and will be over-ridden", result.Name, result.MacroType.ToString(), result.Value);
                        result.Value = macro.Value;
                    }
                }
                else
                {
                    Logging.Info("Adding macro {{{0}}} with value '{1}'", macro.Name, macro.Value);
                    Macros.Add(macro);
                }
            }
        }
        public override void ProcessTaskResults()
        {
            AutomationMacro macro = Macros.Find(mac => mac.Name.Equals(MacroName));

            if (macro != null)
            {
                throw new BadMemeException("you have made a mistake");
            }
        }
        public override void ProcessTaskResults()
        {
            AutomationMacro macro = Macros.Find(mac => mac.Name.Equals(MacroName));

            if (ProcessTaskResultTrue(macro == null, "Could not find newly created macro in list"))
            {
                return;
            }
        }
示例#5
0
        public override async Task RunTask()
        {
            Logging.Debug("Checking for if macro {0} already exists", MacroName);
            AutomationMacro macro = Macros.Find(mac => mac.Name.Equals(MacroName));

            if (macro != null)
            {
                Logging.Debug("Macro found, removing");
                Macros.Remove(macro);
            }
        }
示例#6
0
        public override void ProcessMacros()
        {
            base.ProcessMacros();

            //if the value contains the macro old_package_property_value, the user probably wants to use the old value as part of the new value
            //check if it exists first and delete
            AutomationMacro macro = Macros.Find(mac => mac.Name.Equals("old_package_property_value"));

            if (macro != null)
            {
                Macros.Remove(macro);
            }
            PropertyValue = ProcessMacro(nameof(PropertyValue), PropertyValue);
        }
示例#7
0
        public override async Task RunTask()
        {
            string valueToSave;

            if (property.PropertyType.IsValueType)
            {
                valueToSave = property.GetValue(targetPackage).ToString();
            }
            else
            {
                object currentValue = property.GetValue(targetPackage);
                //to get type of array
                //https://stackoverflow.com/a/2085186/3128017
                Type arrayType = currentValue.GetType().GetElementType();
                if (!(arrayType.IsValueType || arrayType.Equals(typeof(string))))
                {
                    Logging.Error("The array requested does not hold value type objects");
                    propertyGot = false;
                    return;
                }

                Array arrayObject = currentValue as Array;
                if (propertyIndex > arrayObject.Length || propertyIndex < 0)
                {
                    Logging.Error("Index {0} is not valid for this property, valid options are 0 to {1}", propertyIndex, arrayObject.Length - 1);
                    propertyGot = false;
                    return;
                }
                object indexedArrayObjectValue = arrayObject.GetValue(propertyIndex);
                valueToSave = indexedArrayObjectValue.ToString();
            }

            Logging.Info("Creating macro for package {0} (UID {1}) of property {2}", targetPackage.PackageName, targetPackage.UID, property.Name);
            Logging.Info("Macro name: {0}, Value: {1}", MacroSaveName, valueToSave);
            AutomationMacro macro = Macros.Find(mac => mac.Name.Equals(MacroSaveName));

            if (macro != null)
            {
                Macros.Remove(macro);
            }
            Macros.Add(new AutomationMacro()
            {
                MacroType = MacroType.Local, Name = MacroSaveName, Value = valueToSave
            });
            propertyGot = true;
        }
        protected static void ProcessMacro(string argName, ref string arg, List <AutomationMacro> macros, int recursionLevel = 0)
        {
            string recursiveLevelString = string.Empty;

            if (recursionLevel > 0)
            {
                recursiveLevelString = string.Format("(recursive level {0})", recursionLevel);
            }
            Logging.Info(Logfiles.AutomationRunner, LogOptions.MethodName, "Processing arg '{0}' {1}", argName, recursiveLevelString);
            Logging.Debug(Logfiles.AutomationRunner, LogOptions.MethodName, "Before processing: '{0}'", arg);

            //run regex on the arg to get the type of replacement to do. if it's recursive, then we need to process the inner one first
            Match result = Regex.Match(arg, AutomationMacro.MacroReplaceRegex);

            if (!result.Success)
            {
                //check if any "{" exist at all
                Match startBracketsMatch = Regex.Match(arg, "{");
                if (startBracketsMatch.Captures.Count > 0)
                {
                    Match endBracketsMatch = Regex.Match(arg, "}");
                    Logging.Error(Logfiles.AutomationRunner, LogOptions.MethodName, "Macros were detected in the argument, but the syntax was incorrect. Most likely is the number of start and end brackets are unbalanced.");
                    Logging.Error(Logfiles.AutomationRunner, LogOptions.None, "Examine the number of brackets starting and ending in the argument, and try again. For debug, here's what was parsed:");
                    Logging.Info(Logfiles.AutomationRunner, LogOptions.None, "Argument value: {0}", arg);
                    Logging.Info(Logfiles.AutomationRunner, LogOptions.None, "Start brackets count: {0}", startBracketsMatch.Captures.Count);
                    foreach (Capture capture in startBracketsMatch.Captures)
                    {
                        Logging.Info(Logfiles.AutomationRunner, LogOptions.None, "Capture location in string: {0}", capture.Index);
                    }
                    Logging.Info(Logfiles.AutomationRunner, LogOptions.None, "End brackets count: {0}", endBracketsMatch.Captures.Count);
                    foreach (Capture capture in endBracketsMatch.Captures)
                    {
                        Logging.Info(Logfiles.AutomationRunner, LogOptions.None, "Capture location in string: {0}", capture.Index);
                    }
                    return;
                }
                Logging.Info(Logfiles.AutomationRunner, LogOptions.MethodName, "The argument {0} has no macros, continue", argName);
                return;
            }

            int inner1Count = result.Groups[AutomationMacro.RegexGroupInner1].Captures.Count;
            int inner2Count = result.Groups[AutomationMacro.RegexGroupInner2].Captures.Count;
            int inner3Count = result.Groups[AutomationMacro.RegexGroupInner3].Captures.Count;

            //verify that 2 and 3 have the same number
            if (inner2Count != inner3Count)
            {
                Logging.Error(Logfiles.AutomationRunner, LogOptions.MethodName, "Inner2Count ({0}) != Inner3Count ({1})! The macro engine is not designed for this!", inner2Count, inner3Count);
                throw new NotImplementedException("soon tm");
            }
            else if (inner2Count > inner1Count)
            {
                int countDifference = inner2Count - inner1Count;
                //this means that the regex must recurse x levels (the difference) into the string to solve the inner values first
                Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "Inner2Count ({0}) > Inner1Count ({1}), required to recuse {2} levels to solve inner macros", inner2Count, inner1Count, countDifference);

                //use the matches of inner1 to send each section into the regex engine again
                int captureCount = 0;
                foreach (Capture capture in result.Groups[AutomationMacro.RegexGroupInner1].Captures)
                {
                    string capturedValue = capture.Value;
                    Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "Running regex on Inner1Count: {0}", capturedValue);
                    //get a count of how many "{" characters exist in this string. If it's 1, then just run this string through and call it good
                    //if it's more then 1, then need to parse out the extra level via a new greedy regex
                    int numStarts = capturedValue.Count(ch_ => ch_.Equals('{'));
                    if (numStarts > 1)
                    {
                        Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "This match is {0} level of brackets, split out the brackets before recursively processing", numStarts);
                        //we need to use the new value as the 'starting value', as if it didn't have a macro around it. for example, consider:
                        //name_{use_{date}_val}_thing
                        //after we resolve {date}, it will become part of the name for {use_{date}_val}.
                        //the way to do this is to treat {use_{date}_val} as a word by itself, i.e. 'use_{date}_val'
                        Regex subRegex     = new Regex(@"{.+}");
                        Match sectionMatch = subRegex.Match(capturedValue);

                        //following the example above, we have the section {use_{date}_val}
                        //strip off the brackets and send it through
                        string splitValue = sectionMatch.Value;
                        splitValue = splitValue.Remove(0, 1);
                        splitValue = splitValue.Remove(splitValue.Length - 1, 1);

                        //we now have 'use_{date}_val', send that through the macro engine
                        string innerResult = ProcessMacro(string.Format("{0}_capture{1}_level{2}", argName, captureCount, countDifference), splitValue, macros);

                        //use_the_date_val, if {date} = the_date. put the brackets back on
                        innerResult = "{" + innerResult + "}";

                        //{use_the_date_val}, now do the final replace of that macro
                        Regex replaceRegex2 = new Regex(sectionMatch.Value);
                        capturedValue = replaceRegex2.Replace(capturedValue, innerResult, 1);
                    }
                    else if (numStarts == 0)
                    {
                        throw new BadMemeException("whoa. didn't see that coming.");
                    }
                    else
                    {
                        Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "This match is 1 level of brackets, perform direct recursive replacement");
                    }

                    string processedValue = ProcessMacro(string.Format("{0}_capture{1}_level{2}", argName, captureCount, countDifference), capturedValue, macros);
                    Regex  replaceRegex   = new Regex(capture.Value);
                    arg = replaceRegex.Replace(arg, processedValue, 1);
                    captureCount++;
                }
            }
            else
            {
                //macros are at the same level, we can just replace as we see them
                //use inner3 as the method to determine what's inside
                foreach (Capture capture in result.Groups[AutomationMacro.RegexGroupInner3].Captures)
                {
                    if (string.IsNullOrEmpty(capture.Value))
                    {
                        continue;
                    }

                    Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "Processing macro {0}, string location {1}, length {2}", capture.Value, capture.Index, capture.Length);
                    AutomationMacro resultMacro = macros.Find(macro => macro.Name.Equals(capture.Value));
                    if (resultMacro == null)
                    {
                        if (!SpecialCaseIgnoreMacro.Contains(capture.Value))
                        {
                            Logging.Warning(Logfiles.AutomationRunner, LogOptions.None, "The macro with name '{0}', does not exist, skipping. (Is this intended?)", capture.Value);
                        }
                        continue;
                    }

                    string macroValue = resultMacro.Value;

                    Match recursiveCheck = Regex.Match(macroValue, AutomationMacro.MacroReplaceRegex);
                    if (recursiveCheck.Success)
                    {
                        Logging.Debug("A macro was resolved to another macro, run the macro replacement code again");
                        string temp = macroValue;
                        ProcessMacro(argName, ref temp, macros, recursionLevel + 1);
                        macroValue = temp;
                    }

                    //perform a single replace on the specified location of the string
                    //https://stackoverflow.com/a/6372134/3128017
                    Regex replaceRegex = new Regex("{" + capture.Value + "}");
                    arg = replaceRegex.Replace(arg, macroValue, 1);
                    Logging.Debug(Logfiles.AutomationRunner, LogOptions.None, "A single replace was done on the argument. Result: {0}", arg);
                }
            }

            Logging.Debug(Logfiles.AutomationRunner, LogOptions.MethodName, "After processing: {0}", arg);
        }