private static int Main2 (string [] arguments) { Lock process_lock; try { if (!Configuration.LoadConfiguration (arguments)) return 1; if (!Configuration.VerifyBuildBotConfiguration ()) return 1; process_lock = Lock.Create ("MonkeyWrench.Builder"); if (process_lock == null) { Logger.Log ("Builder could not acquire lock. Exiting"); return 1; } Logger.Log ("Builder lock aquired successfully."); } catch (Exception ex) { Logger.Log ("Could not aquire lock: {0}", ex.Message); return 1; } try { WebService = WebServices.Create (); WebService.CreateLogin (Configuration.Host, Configuration.WebServicePassword); response = WebService.GetBuildInfoMultiple (WebService.WebServiceLogin, Configuration.Host, true); if (!response.Host.enabled) { Logger.Log ("This host is disabled. Exiting."); return 0; } Logger.Log ("Builder will now build {0} lists of work items.", response.Work.Count); for (int i = 0; i < response.Work.Count; i++) { //foreach (var item in response.Work) Logger.Log ("Building list #{0}/{1}", i+ 1, response.Work.Count); Build (response.Work [i]);//item); } Logger.Log ("Builder finished successfully."); return 0; } catch (Exception ex) { Logger.Log ("An exception occurred: {0}", ex.ToString ()); return 1; } finally { process_lock.Unlock (); } }
public static int Main2(string [] args) { try { if (!Configuration.LoadConfiguration(args)) { return(1); } WebServices WebService = WebServices.Create(); WebService.CreateLogin(Configuration.SchedulerAccount, Configuration.SchedulerPassword); WebService.ExecuteScheduler(WebService.WebServiceLogin, Configuration.ForceFullUpdate); } catch (Exception ex) { Logger.Log("Scheduler exception: {0}", ex); } return(0); }
int Run(String[] args) { if (!Configuration.LoadConfiguration(new string[0])) { Console.WriteLine("Couldn't load configuration."); return(1); } ws = WebServices.Create(); ws.CreateLogin(Configuration.Host, Configuration.WebServicePassword); login = ws.WebServiceLogin; ws.Login(login); string command = args.Length > 0 ? args [0] : ""; if (command == "lane-config") { // Requires admin rights (because it uses GetLaneForEdit) if (args.Length < 2) { Console.WriteLine("Usage: lane-config <lane name>"); return(1); } string lane_name = args [1]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } Console.WriteLine("Lane: " + lane.lane); if (lane.parent_lane_id != null) { var parent_lane = ws.FindLane(login, lane.parent_lane_id, null).lane; if (parent_lane != null) { Console.WriteLine("Parent: " + parent_lane.lane); } } Console.WriteLine("Source control: " + lane.source_control); Console.WriteLine("Repository: " + lane.repository); Console.WriteLine("Mini/Max revision: " + lane.min_revision + "/" + (lane.max_revision != "" ? lane.max_revision : "<none>")); var res = ws.GetLaneForEdit(login, lane.id, null); foreach (var c in res.Commands) { Console.WriteLine("\t " + c.sequence + " " + c.command + " (" + c.filename + " " + c.arguments + ")"); } Console.WriteLine("Files:"); foreach (var f in res.Files) { Console.WriteLine("\t" + f.name); } Console.WriteLine("Hosts:"); foreach (var h in res.HostLaneViews) { Console.WriteLine("\t" + h.host); } } else if (command == "show-step") { // Requires admin rights if (args.Length < 3) { Console.WriteLine("Usage: show-step <lane> <step name>"); return(1); } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } var cmd = FindCmdByName(lane, cmd_name); if (cmd == null) { return(1); } PrintCmd(cmd); } else if (command == "add-step") { if (args.Length < 3) { Console.WriteLine("Usage: add-step <lane> <step name>"); return(1); } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } if (!CheckCmdExists(lane, cmd_name)) { return(1); } bool always = true; bool nonfatal = true; int timeout = 5; // FIXME: AddCommand () ignores this int seq = 0; ws.AddCommand(login, lane.id, cmd_name, always, nonfatal, timeout, seq); } else if (command == "edit-step") { if (args.Length < 3) { Console.WriteLine("Usage: edit-step <lane> <step name> [<edit options>]"); return(1); } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } var cmd = FindCmdByName(lane, cmd_name); if (cmd == null) { return(1); } int? seq = null; int? timeout = null; bool nonfatal = cmd.nonfatal; bool alwaysexecute = cmd.alwaysexecute; string filename = null; string arguments = null; string upload_files = null; OptionSet p = new OptionSet() .Add("seq=", v => seq = Int32.Parse(v)) .Add("timeout=", v => timeout = Int32.Parse(v)) .Add("nonfatal=", v => nonfatal = Boolean.Parse(v)) .Add("alwaysexecute=", v => alwaysexecute = Boolean.Parse(v)) .Add("filename=", v => filename = v) .Add("arguments=", v => arguments = v) .Add("upload-files=", v => upload_files = v); var new_args = p.Parse(args.Skip(3).ToArray()); if (new_args.Count > 0) { Console.WriteLine("Unknown arguments: " + String.Join(" ", new_args.ToArray())); return(1); } PrintCmd(cmd); if (seq != null) { ws.EditCommandSequence(login, cmd.id, (int)seq); } if (filename != null) { ws.EditCommandFilename(login, cmd.id, filename); } if (arguments != null) { ws.EditCommandArguments(login, cmd.id, arguments); } if (upload_files != null) { ws.EditCommandUploadFiles(login, cmd.id, upload_files); } if (timeout != null) { ws.EditCommandTimeout(login, cmd.id, (int)timeout); } if (alwaysexecute != cmd.alwaysexecute) { ws.SwitchCommandAlwaysExecute(login, cmd.id); } if (nonfatal != cmd.nonfatal) { ws.SwitchCommandNonFatal(login, cmd.id); } cmd = FindCmdByName(lane, cmd_name); if (cmd == null) { return(1); } Console.WriteLine("=>"); PrintCmd(cmd); } else if (command == "add-lane-file") { if (args.Length < 3) { Console.WriteLine("Usage: add-lane-file <lane> <lane file name>"); return(1); } string lane_name = args [1]; string lane_file_name = args [2]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } var res = ws.GetLaneForEdit(login, lane.id, null); var file = (from f in res.Files where f.name == lane_file_name select f).FirstOrDefault(); if (file != null) { Console.WriteLine("A file named '" + lane_file_name + "' already exists in lane '" + lane.lane + "'."); return(1); } ws.CreateLanefile(login, lane.id, lane_file_name); } else if (command == "edit-lane-file") { if (args.Length < 4) { Console.WriteLine("Usage: edit-lane-file <lane> <lane file name> <filename>"); return(1); } string lane_name = args [1]; string lane_file_name = args [2]; string filename = args [3]; var lane = FindLaneByName(lane_name); if (lane == null) { return(1); } var res = ws.GetLaneForEdit(login, lane.id, null); var file = (from f in res.Files where f.name == lane_file_name select f).FirstOrDefault(); if (file == null) { Console.WriteLine("No file named '" + lane_file_name + "' in lane '" + lane.lane + "'."); return(1); } file.contents = File.ReadAllText(filename); ws.EditLaneFile(login, file); } else if (command == "lanes") { var res = ws.GetLanes(login); foreach (var l in res.Lanes) { Console.WriteLine(l.lane); } } else if (command == "lane-tree") { var res = ws.GetLanes(login); var tree = new Dictionary <DBLane, List <DBLane> > (); foreach (var l in res.Lanes) { tree [l] = new List <DBLane> (); } foreach (var l in res.Lanes) { if (l.parent_lane_id != null) { var parent_lane = (from l2 in res.Lanes where l2.id == l.parent_lane_id select l2).First(); tree [parent_lane].Add(l); } } foreach (var l in tree.Keys) { if (l.parent_lane_id == null) { PrintLaneTree(tree, l, 0); } } } else if (command == "rev") { if (args.Length < 4) { Console.WriteLine("Usage: rev <lane> <host> <revision>"); return(1); } string lane_name = args [1]; string host_name = args [2]; string rev_name = args [3]; var lane = ws.FindLane(login, null, lane_name).lane; if (lane == null) { Console.WriteLine("Lane '" + lane_name + "' not found."); return(1); } var host = ws.FindHost(login, null, host_name).Host; var res = ws.FindRevisionForLane(login, null, rev_name, lane.id, null); var rev = res.Revision; if (res.Revision == null) { Console.WriteLine("Revision '" + rev_name + "' not found."); return(1); } var res2 = ws.GetViewLaneData(login, lane.id, null, host.id, null, rev.id, null); Console.WriteLine("" + rev.revision + " " + rev.author + " " + (DBState)res2.RevisionWork.state); int vindex = 0; foreach (var view in res2.WorkViews) { Console.WriteLine("\t " + view.command + " " + (DBState)view.state); foreach (var fview in res2.WorkFileViews[vindex]) { if (fview.work_id == view.id) { Console.WriteLine("\t\t" + fview.filename); } } vindex++; } } else if (command == "lane") { if (args.Length < 3) { Console.WriteLine("Usage: lane <lane> <host>"); return(1); } string lane_name = args [1]; string host_name = args [2]; int limit = 10; OptionSet p = new OptionSet() .Add("limit=", v => limit = Int32.Parse(v)); p.Parse(args.Skip(3).ToArray()); var lane = ws.FindLane(login, null, lane_name).lane; if (lane == null) { Console.WriteLine("Lane '" + lane_name + "' not found."); return(1); } //var cmds = ws.GetCommands (login, lane.id); //var cmd = (from c in cmds.Commands where c.command == "package" select c).First (); var hosts = ws.GetHosts(login); var host = (from h in hosts.Hosts where h.host == host_name select h).FirstOrDefault(); if (host == null) { Console.WriteLine("Host '" + host_name + "' not found."); return(1); } var revs = ws.GetRevisions(login, null, lane.lane, limit, 0); foreach (var rev in revs.Revisions) { var watch = new Stopwatch(); watch.Start(); var res3 = ws.GetViewLaneData(login, lane.id, null, host.id, null, rev.id, null); watch.Stop(); if (res3.RevisionWork == null) { Console.WriteLine("Host/lane pair not found."); return(1); } DBState state = (DBState)res3.RevisionWork.state; string extra = ""; if (state == DBState.Executing || state == DBState.Issues) { int nsteps = 0; int ndone = 0; string step = ""; foreach (var view in res3.WorkViews) { nsteps++; DBState viewstate = (DBState)view.state; if (viewstate != DBState.NotDone && viewstate != DBState.Executing) { ndone++; } if (viewstate == DBState.Executing) { step = view.command; } } extra = " (" + nsteps + "/" + ndone + (step != "" ? " " + step : "") + ")"; } if (state == DBState.Issues || state == DBState.Failed) { string failed = ""; foreach (var view in res3.WorkViews) { if ((DBState)view.state == DBState.Failed) { if (failed != "") { failed += " "; } failed += view.command; } } if (failed != "") { extra += " (" + failed + ")"; } } Console.WriteLine("" + rev.revision + " " + rev.author + " " + state + extra); } } else if (command == "help") { PrintUsage(); } else { PrintUsage(); return(1); } ws.Logout(login); return(0); }
private static int Main2(string [] arguments) { Lock process_lock; ReportBuildBotStatusResponse status_response; BuildBotStatus status; try { if (!Configuration.LoadConfiguration(arguments)) { Logger.Log("Could not load configuration."); return(1); } if (!Configuration.VerifyBuildBotConfiguration()) { Logger.Log("Configuration verification failed."); return(1); } process_lock = Lock.Create("MonkeyWrench.Builder"); if (process_lock == null) { Logger.Log("Builder could not acquire lock. Exiting"); return(1); } Logger.Log("Builder lock aquired successfully."); } catch (Exception ex) { Logger.Log("Could not aquire lock: {0}", ex.Message); return(1); } try { WebService = WebServices.Create(); WebService.CreateLogin(Configuration.Host, Configuration.WebServicePassword); status = new BuildBotStatus(); status.Host = Configuration.Host; status.FillInAssemblyAttributes(); status_response = WebService.ReportBuildBotStatus(WebService.WebServiceLogin, status); if (status_response.Exception != null) { Logger.Log("Failed to report status: {0}", status_response.Exception.Message); return(1); } if (!string.IsNullOrEmpty(status_response.ConfiguredVersion) && status_response.ConfiguredVersion != status.AssemblyVersion) { if (!Update(status, status_response)) { Console.Error.WriteLine("Automatic update to: {0} / {1} failed (see log for details). Please update manually.", status_response.ConfiguredVersion, status_response.ConfiguredRevision); return(2); /* Magic return code that means "automatic update failed" */ } else { Console.WriteLine("The builder has been updated. Please run 'make build' again."); return(1); } } response = WebService.GetBuildInfoMultiple(WebService.WebServiceLogin, Configuration.Host, true); if (!response.Host.enabled) { Logger.Log("This host is disabled. Exiting."); return(0); } Logger.Log("Builder will now build {0} lists of work items.", response.Work.Count); for (int i = 0; i < response.Work.Count; i++) { //foreach (var item in response.Work) Logger.Log("Building list #{0}/{1}", i + 1, response.Work.Count); Build(response.Work [i]); //item); } Logger.Log("Builder finished successfully."); return(0); } catch (Exception ex) { Logger.Log("An exception occurred: {0}", ex.ToString()); return(1); } finally { process_lock.Unlock(); } }
private static int Main2 (string [] arguments) { Lock process_lock; ReportBuildBotStatusResponse status_response; BuildBotStatus status; try { if (!Configuration.LoadConfiguration (arguments)) return 1; if (!Configuration.VerifyBuildBotConfiguration ()) return 1; process_lock = Lock.Create ("MonkeyWrench.Builder"); if (process_lock == null) { Logger.Log ("Builder could not acquire lock. Exiting"); return 1; } Logger.Log ("Builder lock aquired successfully."); } catch (Exception ex) { Logger.Log ("Could not aquire lock: {0}", ex.Message); return 1; } try { WebService = WebServices.Create (); WebService.CreateLogin (Configuration.Host, Configuration.WebServicePassword); status = new BuildBotStatus (); status.Host = Configuration.Host; status.FillInAssemblyAttributes (); status_response = WebService.ReportBuildBotStatus (WebService.WebServiceLogin, status); if (status_response.Exception != null) { Logger.Log ("Failed to report status: {0}", status_response.Exception.Message); return 1; } if (!string.IsNullOrEmpty (status_response.ConfiguredVersion) && status_response.ConfiguredVersion != status.AssemblyVersion) { if (!Update (status, status_response)) { Console.Error.WriteLine ("Automatic update to: {0} / {1} failed (see log for details). Please update manually.", status_response.ConfiguredVersion, status_response.ConfiguredRevision); return 2; /* Magic return code that means "automatic update failed" */ } else { Console.WriteLine ("The builder has been updated. Please run 'make build' again."); return 1; } } response = WebService.GetBuildInfoMultiple (WebService.WebServiceLogin, Configuration.Host, true); if (!response.Host.enabled) { Logger.Log ("This host is disabled. Exiting."); return 0; } Logger.Log ("Builder will now build {0} lists of work items.", response.Work.Count); for (int i = 0; i < response.Work.Count; i++) { //foreach (var item in response.Work) Logger.Log ("Building list #{0}/{1}", i+ 1, response.Work.Count); Build (response.Work [i]);//item); } Logger.Log ("Builder finished successfully."); return 0; } catch (Exception ex) { Logger.Log ("An exception occurred: {0}", ex.ToString ()); return 1; } finally { process_lock.Unlock (); } }
int Run (String[] args) { if (!Configuration.LoadConfiguration (new string[0])) { Console.WriteLine ("Couldn't load configuration."); return 1; } ws = WebServices.Create (); ws.CreateLogin (Configuration.Host, Configuration.WebServicePassword); login = ws.WebServiceLogin; ws.Login (login); string command = args.Length > 0 ? args [0] : ""; if (command == "lane-config") { // Requires admin rights (because it uses GetLaneForEdit) if (args.Length < 2) { Console.WriteLine ("Usage: lane-config <lane name>"); return 1; } string lane_name = args [1]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; Console.WriteLine ("Lane: " + lane.lane); if (lane.parent_lane_id != null) { var parent_lane = ws.FindLane (login, lane.parent_lane_id, null).lane; if (parent_lane != null) Console.WriteLine ("Parent: " + parent_lane.lane); } Console.WriteLine ("Source control: " + lane.source_control); Console.WriteLine ("Repository: " + lane.repository); Console.WriteLine ("Mini/Max revision: " + lane.min_revision + "/" + (lane.max_revision != "" ? lane.max_revision : "<none>")); var res = ws.GetLaneForEdit (login, lane.id, null); foreach (var c in res.Commands) { Console.WriteLine ("\t " + c.sequence + " " + c.command + " (" + c.filename + " " + c.arguments + ")"); } Console.WriteLine ("Files:"); foreach (var f in res.Files) { Console.WriteLine ("\t" + f.name); } Console.WriteLine ("Hosts:"); foreach (var h in res.HostLaneViews) { Console.WriteLine ("\t" + h.host); } } else if (command == "show-step") { // Requires admin rights if (args.Length < 3) { Console.WriteLine ("Usage: show-step <lane> <step name>"); return 1; } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; var cmd = FindCmdByName (lane, cmd_name); if (cmd == null) return 1; PrintCmd (cmd); } else if (command == "add-step") { if (args.Length < 3) { Console.WriteLine ("Usage: add-step <lane> <step name>"); return 1; } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; if (!CheckCmdExists (lane, cmd_name)) return 1; bool always = true; bool nonfatal = true; int timeout = 5; // FIXME: AddCommand () ignores this int seq = 0; ws.AddCommand (login, lane.id, cmd_name, always, nonfatal, timeout, seq); } else if (command == "edit-step") { if (args.Length < 3) { Console.WriteLine ("Usage: edit-step <lane> <step name> [<edit options>]"); return 1; } string lane_name = args [1]; string cmd_name = args [2]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; var cmd = FindCmdByName (lane, cmd_name); if (cmd == null) return 1; int? seq = null; int? timeout = null; bool nonfatal = cmd.nonfatal; bool alwaysexecute = cmd.alwaysexecute; string filename = null; string arguments = null; string upload_files = null; OptionSet p = new OptionSet () .Add ("seq=", v => seq = Int32.Parse (v)) .Add ("timeout=", v => timeout = Int32.Parse (v)) .Add ("nonfatal=", v => nonfatal = Boolean.Parse (v)) .Add ("alwaysexecute=", v => alwaysexecute = Boolean.Parse (v)) .Add ("filename=", v => filename = v) .Add ("arguments=", v => arguments = v) .Add ("upload-files=", v => upload_files = v); var new_args = p.Parse (args.Skip (3).ToArray ()); if (new_args.Count > 0) { Console.WriteLine ("Unknown arguments: " + String.Join (" ", new_args.ToArray ())); return 1; } PrintCmd (cmd); if (seq != null) ws.EditCommandSequence (login, cmd.id, (int)seq); if (filename != null) ws.EditCommandFilename (login, cmd.id, filename); if (arguments != null) ws.EditCommandArguments (login, cmd.id, arguments); if (upload_files != null) ws.EditCommandUploadFiles (login, cmd.id, upload_files); if (timeout != null) ws.EditCommandTimeout (login, cmd.id, (int)timeout); if (alwaysexecute != cmd.alwaysexecute) ws.SwitchCommandAlwaysExecute (login, cmd.id); if (nonfatal != cmd.nonfatal) ws.SwitchCommandNonFatal (login, cmd.id); cmd = FindCmdByName (lane, cmd_name); if (cmd == null) return 1; Console.WriteLine ("=>"); PrintCmd (cmd); } else if (command == "add-lane-file") { if (args.Length < 3) { Console.WriteLine ("Usage: add-lane-file <lane> <lane file name>"); return 1; } string lane_name = args [1]; string lane_file_name = args [2]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; var res = ws.GetLaneForEdit (login, lane.id, null); var file = (from f in res.Files where f.name == lane_file_name select f).FirstOrDefault (); if (file != null) { Console.WriteLine ("A file named '" + lane_file_name + "' already exists in lane '" + lane.lane + "'."); return 1; } ws.CreateLanefile (login, lane.id, lane_file_name); } else if (command == "edit-lane-file") { if (args.Length < 4) { Console.WriteLine ("Usage: edit-lane-file <lane> <lane file name> <filename>"); return 1; } string lane_name = args [1]; string lane_file_name = args [2]; string filename = args [3]; var lane = FindLaneByName (lane_name); if (lane == null) return 1; var res = ws.GetLaneForEdit (login, lane.id, null); var file = (from f in res.Files where f.name == lane_file_name select f).FirstOrDefault (); if (file == null) { Console.WriteLine ("No file named '" + lane_file_name + "' in lane '" + lane.lane + "'."); return 1; } file.contents = File.ReadAllText (filename); ws.EditLaneFile (login, file); } else if (command == "lanes") { var res = ws.GetLanes (login); foreach (var l in res.Lanes) Console.WriteLine (l.lane); } else if (command == "lane-tree") { var res = ws.GetLanes (login); var tree = new Dictionary<DBLane, List<DBLane>> (); foreach (var l in res.Lanes) { tree [l] = new List<DBLane> (); } foreach (var l in res.Lanes) { if (l.parent_lane_id != null) { var parent_lane = (from l2 in res.Lanes where l2.id == l.parent_lane_id select l2).First (); tree [parent_lane].Add (l); } } foreach (var l in tree.Keys) { if (l.parent_lane_id == null) PrintLaneTree (tree, l, 0); } } else if (command == "rev") { if (args.Length < 4) { Console.WriteLine ("Usage: rev <lane> <host> <revision>"); return 1; } string lane_name = args [1]; string host_name = args [2]; string rev_name = args [3]; var lane = ws.FindLane (login, null, lane_name).lane; if (lane == null) { Console.WriteLine ("Lane '" + lane_name + "' not found."); return 1; } var host = ws.FindHost (login, null, host_name).Host; var res = ws.FindRevisionForLane (login, null, rev_name, lane.id, null); var rev = res.Revision; if (res.Revision == null) { Console.WriteLine ("Revision '" + rev_name + "' not found."); return 1; } var res2 = ws.GetViewLaneData (login, lane.id, null, host.id, null, rev.id, null); Console.WriteLine ("" + rev.revision + " " + rev.author + " " + (DBState)res2.RevisionWork.state); int vindex = 0; foreach (var view in res2.WorkViews) { Console.WriteLine ("\t " + view.command + " " + (DBState)view.state); foreach (var fview in res2.WorkFileViews [vindex]) { if (fview.work_id == view.id) Console.WriteLine ("\t\t" + fview.filename); } vindex ++; } } else if (command == "lane") { if (args.Length < 3) { Console.WriteLine ("Usage: lane <lane> <host>"); return 1; } string lane_name = args [1]; string host_name = args [2]; int limit = 10; OptionSet p = new OptionSet () .Add ("limit=", v => limit = Int32.Parse (v)); p.Parse (args.Skip (3).ToArray ()); var lane = ws.FindLane (login, null, lane_name).lane; if (lane == null) { Console.WriteLine ("Lane '" + lane_name + "' not found."); return 1; } //var cmds = ws.GetCommands (login, lane.id); //var cmd = (from c in cmds.Commands where c.command == "package" select c).First (); var hosts = ws.GetHosts (login); var host = (from h in hosts.Hosts where h.host == host_name select h).FirstOrDefault (); if (host == null) { Console.WriteLine ("Host '" + host_name + "' not found."); return 1; } var revs = ws.GetRevisions (login, null, lane.lane, limit, 0); foreach (var rev in revs.Revisions) { var watch = new Stopwatch (); watch.Start (); var res3 = ws.GetViewLaneData (login, lane.id, null, host.id, null, rev.id, null); watch.Stop (); if (res3.RevisionWork == null) { Console.WriteLine ("Host/lane pair not found."); return 1; } DBState state = (DBState)res3.RevisionWork.state; string extra = ""; if (state == DBState.Executing || state == DBState.Issues) { int nsteps = 0; int ndone = 0; string step = ""; foreach (var view in res3.WorkViews) { nsteps ++; DBState viewstate = (DBState)view.state; if (viewstate != DBState.NotDone && viewstate != DBState.Executing) ndone ++; if (viewstate == DBState.Executing) step = view.command; } extra = " (" + nsteps + "/" + ndone + (step != "" ? " " + step : "") + ")"; } if (state == DBState.Issues || state == DBState.Failed) { string failed = ""; foreach (var view in res3.WorkViews) { if ((DBState)view.state == DBState.Failed) { if (failed != "") failed += " "; failed += view.command; } } if (failed != "") extra += " (" + failed + ")"; } Console.WriteLine ("" + rev.revision + " " + rev.author + " " + state + extra); } } else if (command == "help") { PrintUsage (); } else { PrintUsage (); return 1; } ws.Logout (login); return 0; }