// Initialize our logging support for stranded elements found. Output is sent to the daily log file // StrandedFound-YYYY-MM-DD.log created (or updated) in the same folder where Stranded.exe resides. // Returns true if logging was successfully initialized, false otherwise. Exception caught and logged in // %LOCALAPPDATA%\AcTools\Logs\Stranded-YYYY-MM-DD.log on initialization failure. private static bool initStrandedFoundLogging() { bool ret = false; // assume failure try { TraceSource ts = new TraceSource("Stranded"); // this program name _tl = (FileLogTraceListener)ts.Listeners["StrandedFound"]; _tl.Location = LogFileLocation.ExecutableDirectory; // create the log file in the same folder as our executable _tl.BaseFileName = "StrandedFound"; // our log file name begins with this name _tl.MaxFileSize = 83886080; // log file can grow to a maximum of 80 megabytes in size _tl.ReserveDiskSpace = 2500000000; // at least 2.3GB free disk space must exist for logging to continue // append -YYYY-MM-DD to the log file name // additional runs of this app in the same day append to this file (by default) _tl.LogFileCreationSchedule = LogFileCreationScheduleOption.Daily; _tl.AutoFlush = true; // true to make sure we capture data in the event of an exception ret = true; } catch (Exception exc) { AcDebug.Log($"Exception caught and logged in Program.initStrandedFoundLogging{Environment.NewLine}{exc.Message}"); } return(ret); }
private static bool promoRights() { bool ret = false; // assume failure try { foreach (AcUser user in _users.OrderBy(n => n)) { SortedSet <string> groups = user.Principal.Members; // the list of groups this user is a member of IEnumerable <string> query = from ef in _locks.Select(lk => lk.ExceptFor) // locks applied to all except this group where groups.Any(g => g == ef) // any group in groups list that matches an ExceptFor group select ef; string found = query.FirstOrDefault(); // not null indicates the user has promote privileges somewhere Console.WriteLine($"{user}\t{((found == null) ? "None" : "ExceptFor")}"); } ret = true; } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.promoRights{Environment.NewLine}{ecx.Message}"); } return(ret); }
// Get the stranded elements along with the list of status types found and the total count for each type. // Returns true if the operation completed successfully, false otherwise. Exception caught and logged // in %LOCALAPPDATA%\AcTools\Logs\Stranded-YYYY-MM-DD.log on failure to handle a range of exceptions. private static async Task <bool> getStrandedAsync() { bool ret = false; // assume failure try { AcDepots depots = new AcDepots(dynamicOnly: true); // dynamic streams only if (!(await depots.initAsync())) { return(false); } List <Task <bool> > tasks = new List <Task <bool> >(); // select all depots except those from Stranded.exe.config that should be ignored IEnumerable <AcDepot> filter = from d in depots where !_excludeList.OfType <DepotElement>().Any(de => de.Depot == d.Name) select d; foreach (AcStream stream in filter.SelectMany(d => d.Streams)) { tasks.Add(runStatCommandAsync(stream)); } bool[] arr = await Task.WhenAll(tasks); // finish running stat commands in parallel ret = (arr != null && arr.All(n => n == true)); // true if all succeeded or if no tasks were run } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.getStrandedAsync{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); }
// Run the show triggers command for depot and add the results to our list. Returns true // if the operation succeeded, false otherwise. AcUtilsException caught and logged in // %LOCALAPPDATA%\AcTools\Logs\Triggers-YYYY-MM-DD.log on show command failure. // Exception caught and logged in same for a range of exceptions. private async Task <bool> initListAsync(string depot) { bool ret = false; // assume failure try { AcResult result = await AcCommand.runAsync($@"show -p ""{depot}"" -fx triggers"); if (result != null && result.RetVal == 0) { XElement xml = XElement.Parse(result.CmdResult); xml.AddAnnotation(depot); // add depot since it's not in the XML lock (_locker) { Add(xml); } ret = true; } } catch (AcUtilsException exc) { AcDebug.Log($"AcUtilsException caught and logged in Program.initListAsync{Environment.NewLine}{exc.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initListAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
// Initialize depots list class variable with select depots from WSpaceTransLevel.exe.config. Returns true // if initialization was successful, false otherwise. ConfigurationErrorsException caught and logged in // %LOCALAPPDATA%\AcTools\Logs\WSpaceTransLevel-YYYY-MM-DD.log on initialization failure. private static bool initAppConfigData() { bool ret = false; // assume failure try { DepotsSection depotsConfigSection = ConfigurationManager.GetSection("Depots") as DepotsSection; if (depotsConfigSection == null) { AcDebug.Log("Error in Program.initAppConfigData creating DepotsSection"); } else { _selDepots = depotsConfigSection.Depots; ret = true; } } catch (ConfigurationErrorsException exc) { Process currentProcess = Process.GetCurrentProcess(); ProcessModule pm = currentProcess.MainModule; AcDebug.Log($"Invalid data in {pm.ModuleName}.config{Environment.NewLine}{exc.Message}"); } return(ret); }
// Get the latest transaction in the depot that occurred the last time wspace was successfully updated, // otherwise returns null on error. Adds wspace to the transaction as an annotation. AcUtilsException // caught and logged in %LOCALAPPDATA%\AcTools\Logs\WSpaceTransLevel-YYYY-MM-DD.log on hist command failure. // Exception caught and logged in same for a range of exceptions. private static async Task <XElement> latestTransAsync(AcWorkspace wspace) { XElement trans = null; // assume failure try { AcResult r = await AcCommand.runAsync($@"hist -fx -p ""{wspace.Depot}"" -t {wspace.UpdateLevel}"); if (r != null && r.RetVal == 0) { XElement xml = XElement.Parse(r.CmdResult); trans = xml.Element("transaction"); if (trans != null) { trans.AddAnnotation(wspace); } } } catch (AcUtilsException ecx) { AcDebug.Log($"AcUtilsException caught and logged in Program.latestTransAsync{Environment.NewLine}{ecx.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.latestTransAsync{Environment.NewLine}{ecx.Message}"); } return(trans); }
// Send program results to the console. Returns true if the operation succeeded, false otherwise. // Exception caught and logged in %LOCALAPPDATA%\AcTools\Logs\XLinked-YYYY-MM-DD.log for a range of exceptions. private static bool report() { bool ret = false; // assume failure try { foreach (KeyValuePair <AcDepot, HashSet <XElement> > pair in _map.OrderBy(n => n.Key)) // order by AcDepot { Console.WriteLine(pair.Key); // depot foreach (XElement e in pair.Value // unique list of elements found throughout depot // order by stream name then element's depot-relative path .OrderBy(n => ((string)n.Attribute("namedVersion")) .Substring(0, ((string)n.Attribute("namedVersion")).IndexOf('\\'))) .ThenBy(n => (string)n.Attribute("location"))) { string mtime = e.acxTime("modTime") == null ? String.Empty : "Last modified: " + e.acxTime("modTime").ToString() + " "; Console.WriteLine($"\tEID: {(string)e.Attribute("id")} {{{(string)e.Attribute("elemType")}}} " + $"{(string)e.Attribute("location")}{Environment.NewLine}" + $"\t\t{mtime}{(string)e.Attribute("namedVersion")} {(string)e.Attribute("status")}"); } } ret = true; } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.report{Environment.NewLine}{ecx.Message}"); } return(ret); }
// Run the hist command for depot and add the results to our transactions list. Returns // true if operation succeeds, otherwise false. AcUtilsException caught and logged in // %LOCALAPPDATA%\AcTools\Logs\LatestTransactions-YYYY-MM-DD.log on hist command failure. // Exception caught and logged in same for a range of exceptions. private async static Task <bool> initLastTransAsync(string depot) { bool ret = false; // assume failure try { AcResult r = await AcCommand.runAsync($@"hist -p ""{depot}"" -t now -fx"); if (r != null && r.RetVal == 0) { XElement xml = XElement.Parse(r.CmdResult); XElement trans = xml.Element("transaction"); trans.AddAnnotation(depot); // add depot since it's not in the XML lock (_locker) { _transactions.Add(trans); } ret = true; } } catch (AcUtilsException exc) { AcDebug.Log($"AcUtilsException caught and logged in Program.initLastTransAsync{Environment.NewLine}{exc.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initLastTransAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
// General program startup initialization routines. // Returns true if initialization was successful, false otherwise. private static bool init() { // initialize logging support for reporting program errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // save an unhandled exception in log file before program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our class variables from Stranded.exe.config if (!initAppConfigData()) { return(false); } // initialize our logging support to log stranded elements found if (!initStrandedFoundLogging()) { return(false); } return(true); }
// 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); }
// Initialize our class variables with values from LatestPromotions.exe.config. Returns true if all values // successfully read and class variables initialized, false otherwise. ConfigurationErrorsException caught // and logged in %LOCALAPPDATA%\AcTools\Logs\LatestPromotions-YYYY-MM-DD.log on initialization failure. private static bool initAppConfigData() { bool ret = true; // assume success try { _fromHoursAgo = AcQuery.getAppConfigSetting <int>("FromHoursAgo"); _outputFile = AcQuery.getAppConfigSetting <string>("OutputFile").Trim(); ADSection adSection = ConfigurationManager.GetSection("activeDir") as ADSection; if (adSection == null) { AcDebug.Log("Error in Program.initAppConfigData creating ADSection"); ret = false; } else { _domains = adSection.Domains; _properties = adSection.Props; } DepotsSection depotsConfigSection = ConfigurationManager.GetSection("Depots") as DepotsSection; if (depotsConfigSection == null) { AcDebug.Log("Error in Program.initAppConfigData creating DepotsSection"); ret = false; } else { _selDepots = depotsConfigSection.Depots; } StreamsSection streamsConfigSection = ConfigurationManager.GetSection("Streams") as StreamsSection; if (streamsConfigSection == null) { AcDebug.Log("Error in Program.initAppConfigData creating StreamsSection"); ret = false; } else { _selStreams = streamsConfigSection.Streams; } } catch (ConfigurationErrorsException exc) { Process currentProcess = Process.GetCurrentProcess(); ProcessModule pm = currentProcess.MainModule; AcDebug.Log($"Invalid data in {pm.ModuleName}.config{Environment.NewLine}{exc.Message}"); ret = false; } return(ret); }
// Initialize our dictionary class variable with [element, EID] for all elements in all dynamic streams in depot. // 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 <bool> initMapAsync(AcDepot depot) { bool ret = false; // assume failure try { IEnumerable <AcStream> filter = from n in depot.Streams where n.IsDynamic && !n.Hidden select n; List <Task <AcResult> > tasks = new List <Task <AcResult> >(filter.Count()); foreach (AcStream stream in filter) { tasks.Add(AcCommand.runAsync($@"stat -a -s ""{stream}"" -fx")); // -a for all elements in stream } AcResult[] arr = await Task.WhenAll(tasks); // finish running stat commands in parallel if (arr != null && arr.All(n => n.RetVal == 0)) // true if all initialized successfully { HashSet <Tuple <string, int> > hset = new HashSet <Tuple <string, int> >(_tcompare); foreach (AcResult r in arr) { // if empty the stream has an ACL that is preventing us from reading it or some other error occurred if (r == null || String.IsNullOrEmpty(r.CmdResult)) { continue; } XElement xml = XElement.Parse(r.CmdResult); foreach (XElement e in xml.Elements("element")) { string path = (string)e.Attribute("location"); int eid = (int)e.Attribute("id"); hset.Add(new Tuple <string, int>(path, eid)); } } lock (_locker) { _map.Add(depot, hset); } ret = true; // operation succeeded } } catch (AcUtilsException ecx) { AcDebug.Log($"AcUtilsException caught and logged in Program.initMapAsync{Environment.NewLine}{ecx.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initMapAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
private static readonly object _locker = new object(); // token for lock keyword scope #endregion // Returns zero (0) if program ran successfully, otherwise // one (1) in the event of an exception or program initialization failure. static int Main() { // general program startup initialization if (!init()) { return(1); } // if a TwinsExcludeFile was specified in EvilTwins.exe.config, // validate that it exists and retrieve its content if (!String.IsNullOrEmpty(_twinsExcludeFile)) { if (!File.Exists(_twinsExcludeFile)) { AcDebug.Log($"TwinsExcludeFile {_twinsExcludeFile} specified in EvilTwins.exe.config not found"); return(1); } else { _excludeList = getTwinsExcludeList(); } } // all stream types in order to include workspace streams, include hidden (removed) streams AcDepots depots = new AcDepots(dynamicOnly: false, includeHidden: true); Task <bool> dini = depots.initAsync(_selDepots); if (!dini.Result) { return(1); } _tcompare = new TwinEqualityComparer(); _map = new Dictionary <AcDepot, HashSet <Tuple <string, int> > >(); List <Task <bool> > tasks = new List <Task <bool> >(depots.Count); foreach (AcDepot depot in depots) { tasks.Add(initMapAsync(depot)); } Task <bool[]> arr = Task.WhenAll(tasks); // finish running stat commands and initialization in parallel if (arr == null || arr.Result.Any(n => n == false)) { return(1); // check log file } Task <bool> r = reportAsync(); return((r.Result) ? 0 : 1); }
// Run the stat command for all dynamic streams in depot and initialize our dictionary class variable // with the xlinked elements found that have a type listed in ElementTypes from XLinked.exe.config. // Returns true if the operation succeeded, false otherwise. AcUtilsException caught and logged in // %LOCALAPPDATA%\AcTools\Logs\XLinked-YYYY-MM-DD.log on stat command failure. Exception caught and // logged in same for a range of exceptions. private static async Task <bool> initAsync(AcDepot depot) { bool ret = false; // assume failure try { int num = depot.Streams.Count(); List <Task <AcResult> > tasks = new List <Task <AcResult> >(num); foreach (AcStream stream in depot.Streams) { // -k: Display the element type (that is, data type) of this version // -v: Display the target of an element link or symbolic link tasks.Add(AcCommand.runAsync($@"stat -s ""{stream}"" -a -fkvx")); } HashSet <XElement> hset = new HashSet <XElement>(_comparer); while (tasks.Count > 0) { Task <AcResult> r = await Task.WhenAny(tasks); tasks.Remove(r); if (r == null || r.Result.RetVal != 0) { return(false); } XElement xml = XElement.Parse(r.Result.CmdResult); foreach (XElement e in xml.Elements("element") // attribute xlinked="true" exists only when status includes (xlinked), // otherwise it isn't there (i.e. there never is an xlinked="false" in the XML) .Where(n => (string)n.Attribute("xlinked") != null && _etypes.Any(t => t == n.acxType("elemType")))) { hset.Add(e); } } lock (_locker) { _map.Add(depot, hset); } ret = true; } catch (AcUtilsException exc) { AcDebug.Log($"AcUtilsException caught and logged in Program.initAsync{Environment.NewLine}{exc.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
static int Main() { // general program startup initialization if (!init()) { return(1); // initialization failure, check log file } DateTime past = DateTime.Now.AddHours(_fromHoursAgo * -1); // go back this many hours if (!initListsAsync(past).Result) { return(1); // operation failed, check log file } if (_hist != null && _hist.Count > 0) { XmlWriter writer = null; try { XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, IndentChars = "\t", Encoding = new UTF8Encoding(false) }; // false to exclude Unicode byte order mark (BOM) using (writer = XmlWriter.Create(_outputFile, settings)) { XDocument report = buildReport(past); report.WriteTo(writer); } } catch (Exception exc) { AcDebug.Log($"Exception caught and logged in Program.Main{Environment.NewLine}" + $"Failed writing to {_outputFile}{Environment.NewLine}{exc.Message}"); return(1); } finally { if (writer != null) { writer.Close(); } } } return(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); }
// General program startup initialization. private static bool init() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // save an unhandled exception in log file before program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our class variables from LatestPromotions.exe.config if (!initAppConfigData()) { return(false); } // dynamic streams only in select depots _depots = new AcDepots(dynamicOnly: true); Task <bool> dini = _depots.initAsync(_selDepots); // no group membership initialization, include deactivated users _users = new AcUsers(_domains, _properties, includeGroupsList: false, includeDeactivated: true); Task <bool> uini = _users.initAsync(); Task <bool[]> all = Task.WhenAll(dini, uini); // finish initializing both lists in parallel if (all == null || all.Result.Any(n => n == false)) { return(false); } return(true); }
private static async Task <bool> reportAsync() { DateTime past = DateTime.Now.AddHours(_fromHoursAgo * -1); // go back this many hours if (!(await initHistAsync(past))) { return(false); } if (_hist != null && _hist.Count > 0) { if (!(await initStatAsync())) { return(false); } XmlWriter writer = null; try { XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, IndentChars = "\t", Encoding = new UTF8Encoding(false) // false to exclude Unicode byte order mark (BOM) }; using (writer = XmlWriter.Create(_outputFile, settings)) { XDocument report = buildReport(past); report.WriteTo(writer); } } catch (Exception exc) { AcDebug.Log($"Exception caught and logged in Program.reportAsync{Environment.NewLine}" + $"Failed writing to {_outputFile}{Environment.NewLine}{exc.Message}"); return(false); } finally { if (writer != null) { writer.Close(); } } } return(true); }
// General program startup initialization. Returns true if initialization succeeded, false otherwise. private static bool init() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // in the event of an unhandled exception, save it to our log file before the program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our class variables from PromoCount.exe.config if (!initAppConfigData()) { return(false); } // initialize our logging support for program results if (!initPromoCountResultsLogging()) { return(false); } _users = new AcUsers(_domains, null, includeGroupsList: false, includeDeactivated: true); _depots = new AcDepots(dynamicOnly: true); Task <bool[]> lists = Task.WhenAll(_depots.initAsync(_selDepots), _users.initAsync()); if (lists == null || lists.Result.Any(n => n == false)) { return(false); } return(true); }
// Run the hist command for depots listed in LatestOverlaps.exe.config and add the results to // our history list class variable. Returns true if initialization succeeded, false otherwise. // AcUtilsException caught and logged in %LOCALAPPDATA%\AcTools\Logs\LatestOverlaps-YYYY-MM-DD.log // on hist command failure. Exception caught and logged in same for a range of exceptions. private static async Task <bool> initHistAsync(DateTime past) { bool ret = false; // assume failure try { string timeHrsAgo = AcDateTime.DateTime2AcDate(past); // get date in string format suitable for AccuRev CLI List <Task <AcResult> > tasks = new List <Task <AcResult> >(_depots.Count); foreach (AcDepot depot in _depots) { tasks.Add(AcCommand.runAsync($@"hist -k promote -p ""{depot}"" -t now-""{timeHrsAgo}"" -fex")); } _hist = new List <XElement>(_depots.Count); while (tasks.Count > 0) { Task <AcResult> r = await Task.WhenAny(tasks); tasks.Remove(r); if (r == null || r.Result.RetVal != 0) { return(false); } XElement xml = XElement.Parse(r.Result.CmdResult); _hist.Add(xml); } ret = true; // if we're here then all completed successfully } catch (AcUtilsException exc) { AcDebug.Log($"AcUtilsException caught and logged in Program.initHistAsync{Environment.NewLine}{exc.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initHistAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
// Initialize our class variables from LatestTransactions.exe.config. Returns true if class variables // initialized successfully, false otherwise. ConfigurationErrorsException caught and logged in // %LOCALAPPDATA%\AcTools\Logs\LatestTransactions-YYYY-MM-DD.log on initialization failure. private static bool initAppConfigData() { bool ret = false; // assume failure try { _fileName = AcQuery.getAppConfigSetting <string>("FileName").Trim(); _fileLocation = AcQuery.getAppConfigSetting <string>("FileLocation").Trim(); ret = true; } catch (ConfigurationErrorsException exc) { Process currentProcess = Process.GetCurrentProcess(); ProcessModule pm = currentProcess.MainModule; AcDebug.Log($"Invalid data in {pm.ModuleName}.config{Environment.NewLine}{exc.Message}"); } return(ret); }
// Initialize our ElementType array class variable with values from XLinked.exe.config. // Returns true if successfully read and initialized, false otherwise. ConfigurationErrorsException // caught and logged in %LOCALAPPDATA%\AcTools\Logs\XLinked-YYYY-MM-DD.log on initialization failure. private static bool initAppConfigData() { bool ret = false; // assume failure try { string[] arr = AcQuery.getAppConfigSetting <string>("ElementTypes") .Split(',').Select(s => s.Trim()).ToArray(); _etypes = Array.ConvertAll(arr, new Converter <string, ElementType>(n => (ElementType)Enum.Parse(typeof(ElementType), n))); ret = true; } catch (ConfigurationErrorsException exc) { Process currentProcess = Process.GetCurrentProcess(); ProcessModule pm = currentProcess.MainModule; AcDebug.Log($"Invalid data in {pm.ModuleName}.config{Environment.NewLine}{exc.Message}"); } return(ret); }
// General program startup initialization. private static bool init() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // in the event of an unhandled exception, save it to our log file before the program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our ElementType array class variable from XLinked.exe.config if (!initAppConfigData()) { return(false); } _depots = new AcDepots(dynamicOnly: true); // dynamic streams only Task <bool> dini = _depots.initAsync(); if (!dini.Result) { AcDebug.Log($"Depots list initialization failed. See log file:{Environment.NewLine}" + $"{AcDebug.getLogFile()}"); return(false); } return(true); }
// Returns the list of elements in TwinsExcludeFile from EvilTwins.exe.config with elements that can be ignored. // Assumes caller has determined that the TwinsExcludeFile specified in EvilTwins.exe.config exists. // Exception caught and logged in %LOCALAPPDATA%\AcTools\Logs\EvilTwins-YYYY-MM-DD.log on operation failure. private static List <String> getTwinsExcludeList() { List <String> exclude = new List <String>(); FileStream fs = null; try { // constructor arguments that avoid an exception thrown when file is in use by another process fs = new FileStream(_twinsExcludeFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using (StreamReader sr = new StreamReader(fs)) { String line; while ((line = sr.ReadLine()) != null) { string temp = line.Trim(); if (temp.Length == 0 || temp.StartsWith("#")) { continue; // this is an empty line or a comment } exclude.Add(temp); } } } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.getTwinsExcludeList{Environment.NewLine}{ecx.Message}"); } finally // avoids CA2202: Do not dispose objects multiple times { if (fs != null) { fs.Dispose(); } } return(exclude); }
// General program startup initialization. Returns true if initialization was successful, false otherwise. private static bool init() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // save an unhandled exception in log file before program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our depots list class variable with select depots from WSpaceTransLevel.exe.config if (!initAppConfigData()) { return(false); } // initialize our workspaces list class variable Task <bool> wslist = initWSListAsync(); if (!wslist.Result) { AcDebug.Log($"Workspaces list initialization failed. See log file:{Environment.NewLine}{AcDebug.getLogFile()}"); return(false); } return(true); }
// General program initialization routines. Returns true if initialization was successful, false otherwise. private static bool init() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // save an unhandled exception in log file before program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev Task <string> prncpl = AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl.Result)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our class variables from LatestTransactions.exe.config if (!initAppConfigData()) { return(false); } // list of all depot names in the repository _depots = AcQuery.getDepotNameListAsync().Result; if (_depots == null) { return(false); } return(true); }
// General program startup initialization. private static async Task <bool> initAsync() { // initialize our logging support so we can log errors if (!AcDebug.initAcLogging()) { Console.WriteLine("Logging support initialization failed."); return(false); } // in the event of an unhandled exception, save it to our log file before the program terminates AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException); // ensure we're logged into AccuRev string prncpl = await AcQuery.getPrincipalAsync(); if (String.IsNullOrEmpty(prncpl)) { AcDebug.Log($"Not logged into AccuRev.{Environment.NewLine}Please login and try again."); return(false); } // initialize our depots list class variable from PromoRights.exe.config if (!initAppConfigData()) { return(false); } _users = new AcUsers(null, null, includeGroupsList: true); _locks = new AcLocks(); bool[] arr = await Task.WhenAll( _users.initAsync(), // all users with their respective group membership list initialized _locks.initAsync(_depots) // locks on all streams in select depots from PromoRights.exe.config ); return(arr != null && arr.All(n => n == true)); }
// Initialize our history and stat lists for each stream listed in the LatestPromotions.exe.config Streams section. // AcUtilsException caught and logged in %LOCALAPPDATA%\AcTools\Logs\LatestPromotions-YYYY-MM-DD.log on hist or stat // command failure. Exception caught and logged in same on failure to handle a range of exceptions. private static async Task <bool> initListsAsync(DateTime past) { bool ret = false; // assume failure try { string timeHrsAgo = AcDateTime.DateTime2AcDate(past); // get date in string format suitable for AccuRev CLI List <Task <AcResult> >[] tasks = new List <Task <AcResult> > [2]; tasks[0] = new List <Task <AcResult> >(); // for hist results tasks[1] = new List <Task <AcResult> >(); // for stat results // Alternatively change Equals() to Contains() and modify LatestPromotions.exe.config stream values // accordingly to filter on stream name subsets, e.g. <add stream="DEV"/> for all streams with DEV in their name. foreach (AcStream stream in _depots.SelectMany(d => d.Streams .Where(s => _selStreams.OfType <StreamElement>().Any(se => s.Name.Equals(se.Stream))))) { Task <AcResult> hr = AcCommand.runAsync($@"hist -k promote -s ""{stream}"" -t now-""{timeHrsAgo}"" -fx"); tasks[0].Add(hr); Task <AcResult> sr = AcCommand.runAsync($@"stat -s ""{stream}"" -d -fx"); // stream's default group tasks[1].Add(sr); } _hist = new List <XElement>(tasks[0].Count); while (tasks[0].Count > 0) // process hist results { Task <AcResult> r = await Task.WhenAny(tasks[0]); tasks[0].Remove(r); if (r == null || r.Result.RetVal != 0) { return(false); } XElement xml = XElement.Parse(r.Result.CmdResult); _hist.Add(xml); } while (tasks[1].Count > 0) // process stat results { Task <AcResult> r = await Task.WhenAny(tasks[1]); tasks[1].Remove(r); if (r == null || r.Result.RetVal != 0) { return(false); } if (!Stat.init(r.Result.CmdResult)) { return(false); } } ret = true; // if we're here then all completed successfully } catch (AcUtilsException exc) { AcDebug.Log($"AcUtilsException caught and logged in Program.initListsAsync{Environment.NewLine}{exc.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.initListsAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }
// Run the AccuRev hist command for all streams in PromoCount.exe.config, generate the results and send it // to the daily log file PromoCountResults-YYYY-MM-DD.log created (or updated) in the same folder where // PromoCount.exe resides. Returns true if the operation succeeded, false otherwise. AcUtilsException // caught and logged in %LOCALAPPDATA%\AcTools\Logs\PromoCount-YYYY-MM-DD.log on hist command failure. // Exception caught and logged in same for a range of exceptions. private static async Task <bool> promoCountAsync() { bool ret = false; // assume failure try { Dictionary <AcStream, Task <AcResult> > map = new Dictionary <AcStream, Task <AcResult> >(_selStreams.Count); Func <AcStream, Task <AcResult> > run = (stream) => { // start-end times reversed as workaround for AccuRev issue 15780 Task <AcResult> result = AcCommand.runAsync( $@"hist -fx -k promote -s ""{stream}"" -t ""{_endTime} - {_startTime}"""); lock (_locker) { map.Add(stream, result); } return(result); }; var tasks = from s in _depots.SelectMany(d => d.Streams) where _selStreams.OfType <StreamElement>().Any(se => se.Stream == s.Name) select run(s); AcResult[] arr = await Task.WhenAll(tasks); // finish running hist commands in parallel if (arr == null || arr.Any(r => r.RetVal != 0)) { return(false); } log($"Promotions to select streams from {_startTime} to {_endTime}.{Environment.NewLine}"); int tgrandtot = 0; int vgrandtot = 0; foreach (var ii in map.OrderBy(n => n.Key)) { log($"{ii.Key} {{{$"promotions\\versions"}}}:"); // key is stream AcResult r = ii.Value.Result; XElement xml = XElement.Parse(r.CmdResult); ILookup <string, XElement> look = xml.Elements("transaction") .ToLookup(n => (string)n.Attribute("user"), n => n); int tsubtot = 0; int vsubtot = 0; foreach (var jj in look.OrderBy(n => _users.getUser(n.Key))) { AcUser user = _users.getUser(jj.Key); int tnum = jj.Count(); int vnum = jj.Elements("version").Count(); string val = $"{{{tnum}\\{vnum}}}"; log($"\t{user.ToString().PadRight(40, '.')}{val.PadLeft(13, '.')}"); tsubtot += tnum; tgrandtot += tnum; vsubtot += vnum; vgrandtot += vnum; } log($"\tTotal {tsubtot} promotions and {vsubtot} versions.{Environment.NewLine}"); } log($"Grand total of {tgrandtot} promotions and {vgrandtot} versions."); ret = true; } catch (AcUtilsException ecx) { AcDebug.Log($"AcUtilsException caught and logged in Program.promoCountAsync{Environment.NewLine}{ecx.Message}"); } catch (Exception ecx) { AcDebug.Log($"Exception caught and logged in Program.promoCountAsync{Environment.NewLine}{ecx.Message}"); } return(ret); }