Generates a report of all streams in the repository that have stranded elements with the list of status types found and their count. Results are written to the daily log file StrandedFound-YYYY-MM-DD.log
created (or updated) in the same folder where Stranded.exe
resides.
Stranded elements are members of the default group yet they are not returned with the stat -d
option used to select only active elements of the workspace or stream; you must use the -i
option instead. They are purposely left out of the list retrieved with the -d
option to ensure they are not accidentally promoted. Salesforce 00042864, 00035837, RFE 13692.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="Depots" type="AcUtils.DepotsSection, AcUtils, Version=1.6.4.0, Culture=neutral, PublicKeyToken=26470c2daf5c2e2f, processorArchitecture=MSIL"/>
</configSections>
<Depots>
<depots>
<!-- include depots here that should be ignored, i.e. PlayGround depots, obsolete depots, etc. -->
<add
depot=
"PlayGround"/>
<add
depot=
"PlayGround2"/>
</depots>
</Depots>
<system.diagnostics>
<assert assertuienabled="false"/>
<sources>
<source name="Stranded">
<listeners>
<remove name="Default"/>
<add name="AcLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"/>
<add name="StrandedFound" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>
using System.Collections.Generic;
using Microsoft.VisualBasic.Logging;
namespace Stranded
{
class Program
{
#region class variables
private static DepotsCollection _excludeList;
private static SortedList<AcStream, SortedList<string, int>> _map = new SortedList<AcStream, SortedList<string, int>>();
private static readonly object _locker = new object();
private static int _totalStranded;
private static FileLogTraceListener _tl;
#endregion
static int Main()
{
if (!init()) return 1;
#if DEBUG
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
#endif
Task<bool> sini = getStrandedAsync();
bool ret = sini.Result;
if (ret)
{
report();
log($"Total stranded elements: {_totalStranded}");
#if DEBUG
AcDuration ts = stopWatch.Elapsed;
log($"{ts.ToString()} to complete execution");
#endif
}
return (ret) ? 0 : 1;
}
private static async Task<bool> getStrandedAsync()
{
bool ret = false;
try
{
AcDepots depots = new AcDepots(dynamicOnly: true);
if (!(await depots.initAsync())) return false;
List<Task<bool>> tasks = new List<Task<bool>>();
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);
ret = (arr != null && arr.All(n => n == true));
}
catch (Exception ecx)
{
AcDebug.Log($"Exception caught and logged in Program.getStrandedAsync{Environment.NewLine}{ecx.Message}");
}
return ret;
}
private static async Task<bool> runStatCommandAsync(AcStream
stream)
{
bool ret = false;
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;
}
private static SortedList<string, int> initVal(XElement xml)
{
SortedList<string, int> status = new SortedList<string, int>();
foreach (XElement e in xml.Elements("element"))
{
int sc;
string sval = (string)e.Attribute("status");
if (status.TryGetValue(sval, out sc))
{
sc++;
status[sval] = sc;
}
else
status[sval] = 1;
_totalStranded++;
}
return status;
}
private static void report()
{
foreach (KeyValuePair<AcStream, SortedList<string, int>> ii in _map)
{
log(ii.Key.Name);
SortedList<string, int> sc = ii.Value;
foreach (KeyValuePair<string, int> jj in sc)
log($"{jj.Key} {{{jj.Value}}}");
log("");
}
}
private static bool init()
{
if (!AcDebug.initAcLogging())
{
Console.WriteLine("Logging support initialization failed.");
return false;
}
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AcDebug.unhandledException);
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;
}
if (!initAppConfigData()) return false;
if (!initStrandedFoundLogging()) return false;
return true;
}
private static bool initAppConfigData()
{
bool ret = true;
try
{
DepotsSection depotsConfigSection = ConfigurationManager.GetSection("Depots") as DepotsSection;
if (depotsConfigSection == null)
{
AcDebug.Log("Error in Program.initAppConfigData creating DepotsSection");
ret = false;
}
else
_excludeList = depotsConfigSection.Depots;
}
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;
}
private static bool initStrandedFoundLogging()
{
bool ret = false;
try
{
TraceSource ts = new TraceSource("Stranded");
_tl = (FileLogTraceListener)ts.Listeners["StrandedFound"];
_tl.Location = LogFileLocation.ExecutableDirectory;
_tl.BaseFileName = "StrandedFound";
_tl.MaxFileSize = 83886080;
_tl.ReserveDiskSpace = 2500000000;
_tl.LogFileCreationSchedule = LogFileCreationScheduleOption.Daily;
_tl.AutoFlush = true;
ret = true;
}
catch (Exception exc)
{
AcDebug.Log($"Exception caught and logged in Program.initStrandedFoundLogging{Environment.NewLine}{exc.Message}");
}
return ret;
}
private static void log(
string text)
{
if (_tl != null)
_tl.WriteLine(text);
}
}
}