Пример #1
0
        // Run the AccuRev stat command for the stream and initialize our _map class variable with the results.
        // Returns true if the operation succeeded, false otherwise. AcUtilsException caught and logged in
        // %LOCALAPPDATA%\AcTools\Logs\Stranded-YYYY-MM-DD.log on stat command failure. Exception caught and
        // logged in same for a range of exceptions.
        private static async Task <bool> runStatCommandAsync(AcStream stream)
        {
            bool ret = false; // assume failure

            try
            {
                AcResult result = await AcCommand.runAsync($@"stat -fx -s ""{stream}"" -i");

                if (result != null && result.RetVal == 0)
                {
                    XElement xml = XElement.Parse(result.CmdResult);
                    int      num = xml.Elements("element").Count();
                    if (num > 0)
                    {
                        lock (_locker) { _map.Add(stream, initVal(xml)); }
                    }
                }

                ret = true;
            }

            catch (AcUtilsException exc)
            {
                AcDebug.Log($"AcUtilsException caught and logged in Program.runStatCommandAsync{Environment.NewLine}{exc.Message}");
            }

            catch (Exception ecx)
            {
                AcDebug.Log($"Exception caught and logged in Program.runStatCommandAsync{Environment.NewLine}{ecx.Message}");
            }

            return(ret);
        }
        // Returns the attributes for the element in stream if the query succeeded, otherwise null.
        // AcUtilsException caught and logged in %LOCALAPPDATA%\AcTools\Logs\EvilTwins-YYYY-MM-DD.log on stat command failure.
        // Exception caught and logged in same for a range of exceptions.
        private static async Task <XElement> getElementInfoAsync(AcStream stream, string element)
        {
            XElement e = null;

            try
            {
                AcResult r = await AcCommand.runAsync($@"stat -fx -s ""{stream}"" ""{element}""");

                if (r != null && r.RetVal == 0)
                {
                    XElement xml = XElement.Parse(r.CmdResult);
                    e = xml.Element("element");
                    e.AddAnnotation(stream); // add stream since it's not in the XML
                }
            }

            catch (AcUtilsException ecx)
            {
                AcDebug.Log($"AcUtilsException caught and logged in Program.getElementInfoAsync{Environment.NewLine}{ecx.Message}");
            }

            catch (Exception ecx)
            {
                AcDebug.Log($"Exception caught and logged in Program.getElementInfoAsync{Environment.NewLine}{ecx.Message}");
            }

            return(e);
        }
Пример #3
0
        // Run the stat command for streams in depots listed in LatestOverlaps.exe.config and add the
        // results to the Stat.Elements list. Returns true if initialization succeeded, false otherwise.
        // AcUtilsException caught and logged in %LOCALAPPDATA%\AcTools\Logs\LatestOverlaps-YYYY-MM-DD.log
        // on stat command failure. Exception caught and logged in same for a range of exceptions.
        private static async Task <bool> initStatAsync()
        {
            bool ret = false; // assume failure

            try
            {
                IEnumerable <XElement> trans = from e in _hist.Elements("transaction")
                                               select e;
                ILookup <string, XElement> map = trans.ToLookup(n => (string)n.Attribute("streamName"), n => n);

                List <Task <AcResult> > tasks = new List <Task <AcResult> >();
                foreach (var ii in map) // for each stream
                {
                    AcStream stream = _depots.getStream(ii.Key);
                    if (!stream.HasDefaultGroup)
                    {
                        continue;                          // run stat only if default group exists
                    }
                    tasks.Add(AcCommand.runAsync($@"stat -s ""{stream}"" -o -fx"));
                }

                bool op = true;
                while (tasks.Count > 0 && op)
                {
                    Task <AcResult> r = await Task.WhenAny(tasks);

                    tasks.Remove(r);
                    op = (r != null && r.Result.RetVal == 0 && Stat.init(r.Result.CmdResult));
                }

                ret = op; // true if all completed successfully
            }

            catch (AcUtilsException exc)
            {
                AcDebug.Log($"AcUtilsException caught and logged in Program.initStatAsync{Environment.NewLine}{exc.Message}");
            }

            catch (Exception ecx)
            {
                AcDebug.Log($"Exception caught and logged in Program.initStatAsync{Environment.NewLine}{ecx.Message}");
            }

            return(ret);
        }
        // Report evil twins if found. Assumes the initMapAsync method has been called. Exception caught
        // and logged in %LOCALAPPDATA%\AcTools\Logs\EvilTwins-YYYY-MM-DD.log on operation failure.
        private static async Task <bool> reportAsync()
        {
            bool ret = false; // assume failure

            try
            {
                foreach (KeyValuePair <AcDepot, HashSet <Tuple <string, int> > > pair in _map.OrderBy(n => n.Key)) // order by AcDepot
                {
                    AcDepot depot = pair.Key;                                                                      // depot
                    HashSet <Tuple <string, int> > hset = pair.Value;                                              // [element, EID] from all dynamic streams in depot
                    // from our hashset create a collection of elements mapped to their EID's
                    Lookup <string, Tuple <string, int> > col = (Lookup <string, Tuple <string, int> >)hset.ToLookup(n => n.Item1);
                    // where more than one EID exists for the element, order by element
                    foreach (var ii in col.Where(n => n.Count() > 1).OrderBy(n => n.Key))
                    {
                        string element = ii.Key;
                        if (_excludeList != null && _excludeList.Contains(element))
                        {
                            continue; // ignore if in TwinsExcludeFile
                        }
                        log(element);
                        IEnumerable <AcStream> filter = from n in depot.Streams
                                                        where n.IsDynamic && !n.Hidden
                                                        select n;
                        List <Task <XElement> > tasks = new List <Task <XElement> >(filter.Count());
                        foreach (AcStream stream in filter)
                        {
                            tasks.Add(getElementInfoAsync(stream, element));
                        }

                        XElement[] arr = await Task.WhenAll(tasks);                      // finish running stat commands in parallel

                        if (arr != null && arr.All(n => n != null))                      // true if all ran successfully
                        {
                            foreach (Tuple <string, int> jj in ii.OrderBy(n => n.Item2)) // order twins by EID
                            {
                                int eid = jj.Item2;
                                log($"\tEID: {eid} on {DateTime.Now.ToString("ddd MMM d h:mm tt")}");
                                // C# language short-circuit: the test for id equals eid isn't evaluated if status equals "(no such elem)",
                                // otherwise an exception would be thrown since the id attribute doesn't exist in this case
                                foreach (XElement e in arr.Where(n => (string)n.Attribute("status") != "(no such elem)" &&
                                                                 (int)n.Attribute("id") == eid).OrderBy(n => n.Annotation <AcStream>()))
                                {
                                    log($"\t\t{e.Annotation<AcStream>()} {(string)e.Attribute("status")}");
                                    string      namedVersion = (string)e.Attribute("namedVersion"); // virtual stream name and version number
                                    string      temp         = (string)e.Attribute("Real");
                                    string[]    real         = temp.Split('\\');                    // workspace stream and version numbers
                                    AcStream    wkspace      = depot.getStream(int.Parse(real[0])); // workspace stream
                                    ElementType elemType     = e.acxType("elemType");
                                    string      twin;
                                    if ((long?)e.Attribute("size") != null)
                                    {
                                        twin = $"\t\t\tSize: {(long)e.Attribute("size")}, ModTime: {e.acxTime("modTime")} {{{elemType}}}" +
                                               $"{Environment.NewLine}\t\t\tReal: {wkspace}\\{real[1]}, Virtual: {namedVersion}";
                                    }
                                    else // a folder or link
                                    {
                                        twin = $"\t\t\tReal: {wkspace}\\{real[1]}, Virtual: {namedVersion} {{{elemType}}}";
                                    }

                                    log(twin);
                                }

                                log("");
                            }
                        }
                    }
                }

                ret = true; // operation succeeded
            }

            catch (Exception ecx)
            {
                AcDebug.Log($"Exception caught and logged in Program.reportAsync{Environment.NewLine}{ecx.Message}");
            }

            return(ret);
        }