For workspaces in select depots, show the depot's latest transaction the last time the workspace was successfully updated. Flags workspaces that are in an inconsistent state (update cancellation/failure) by displaying their {update - target} levels. Results are sent to the console.
<?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>
<!-- depots whose workspaces should be included in the report -->
</depots>
</Depots>
<system.diagnostics>
<assert assertuienabled="false"/>
<sources>
<source name="WSpaceTransLevel">
<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"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>
using System.Collections.Generic;
namespace WSpaceTransLevel
{
class Program
{
#region class variables
private static DepotsCollection _selDepots;
private static AcWorkspaces _wspaces;
#endregion
static int Main()
{
if (!init()) return 1;
Task<bool> rpt = reportAsync();
bool ret = rpt.Result;
return (ret) ? 0 : 1;
}
private static async Task<bool> reportAsync()
{
int num = (
from ws in _wspaces
where ws.UpdateLevel > 0 && ws.TargetLevel > 0
select ws).Count();
List<Task<XElement>> tasks = new List<Task<XElement>>(num);
foreach (AcWorkspace ws in _wspaces.OrderBy(n => n))
{
if (ws.UpdateLevel > 0 && ws.TargetLevel > 0)
tasks.Add(latestTransAsync(ws));
else
Console.WriteLine($"{ws} off {ws.getBasis()} in depot {ws.Depot} needs an update.");
}
XElement[] arr = await Task.WhenAll(tasks);
if (arr == null || arr.Any(n => n == null)) return false;
foreach (XElement t in arr.OrderBy(n => n.Annotation<AcWorkspace>().Depot)
.ThenByDescending(n => n.acxTime("time"))
.ThenBy(n => n.Annotation<AcWorkspace>().Name))
{
AcWorkspace ws = t.Annotation<AcWorkspace>();
string levels = (ws.UpdateLevel == ws.TargetLevel) ? String.Empty : $", {{{ws.UpdateLevel} - {ws.TargetLevel}}}";
Console.WriteLine($"The last time {ws} off {ws.getBasis()} was successfully updated,{Environment.NewLine}" +
$"the latest transaction {(int)t.Attribute("id")} in depot {ws.Depot} occurred on {t.acxTime("time")}{levels}");
}
return true;
}
private static async Task<XElement> latestTransAsync(AcWorkspace wspace)
{
XElement trans = null;
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;
}
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;
Task<bool> wslist = initWSListAsync();
if (!wslist.Result)
{
AcDebug.Log($"Workspaces list initialization failed. See log file:{Environment.NewLine}{AcDebug.getLogFile()}");
return false;
}
return true;
}
private static bool initAppConfigData()
{
bool ret = false;
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;
}
private static async Task<bool> initWSListAsync()
{
AcDepots depots = new AcDepots();
if (!(await depots.initAsync(_selDepots))) return false;
_wspaces = new AcWorkspaces(depots, allWSpaces: true, includeHidden: false);
if (!(await _wspaces.initAsync())) return false;
return true;
}
}
}