public void PackagePublisherPackageFolderMustRespectHierarchy() { const string ProjectName1 = "PackageTest03"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest03.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>(); string workingDirectory = "Packaging03"; string infoFolder = string.Format("{0}{1}some{1}directories{1}deeper{1}_PublishedWebsites{1}MyProject{1}", workingDirectory, System.IO.Path.DirectorySeparatorChar); string subInfoFolder = string.Format("{0}{1}AFolder{1}", infoFolder, System.IO.Path.DirectorySeparatorChar); string f1 = string.Format("{0}{1}a.txt", infoFolder, System.IO.Path.DirectorySeparatorChar); string f2 = string.Format("{0}{1}b.txt", subInfoFolder, System.IO.Path.DirectorySeparatorChar); var ios = new CCNet.Core.Util.IoService(); ios.DeleteIncludingReadOnlyObjects(infoFolder); ios.DeleteIncludingReadOnlyObjects("TheMegaWebSite"); System.IO.Directory.CreateDirectory(infoFolder); System.IO.Directory.CreateDirectory(subInfoFolder); System.IO.File.WriteAllText(f1, "somedata"); System.IO.File.WriteAllText(f2, "somedata"); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}Project-package.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar); Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location"); ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile); string expectedFiles = string.Empty; foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf) { System.Diagnostics.Debug.WriteLine(ze.Name); expectedFiles += ze.Name; } Assert.AreEqual(@"MegaWebSite/AFolder/b.txtMegaWebSite/a.txt", expectedFiles); }
public void StartServer_ForceBuildDependendProject_Wait_CheckingProjectDoesNotGetTriggered() { const string projectName1 = "InnerTriggerTest_CCNet1835"; const string projectName2 = "CheckBuild"; IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>(); string IntegrationFolder = System.IO.Path.Combine("scenarioTests", projectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "ProblemWithInnerTriggers_CCnet1835.xml"); string Project1StateFile = new System.IO.FileInfo(projectName1 + ".state").FullName; string Project2StateFile = new System.IO.FileInfo(projectName2 + ".state").FullName; IntegrationCompleted.Add(projectName1, false); IntegrationCompleted.Add(projectName2, false); const Int32 SecondsToWaitFromNow = 60; // adjust triggertime of project 1 to now + 60 seconds (SecondsToWaitFromNow) // this will give the unittest time to create an ok build of project2 // and let the schedule trigger work as normal : check if it is time to integrate and check on the status // 60 seconds should be ok, less time may give problems on slower machines // keep in mind that cruise server is also starting, so this time must also be taken into account // also we want the cruise server to wait for 1 minute, otherwise it starts integrating project 1 immediately System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument(); xdoc.Load(CCNetConfigFile); string xslt = string.Format(System.Globalization.CultureInfo.CurrentCulture, "/cruisecontrol/project[@name='{0}']/triggers/multiTrigger/triggers/scheduleTrigger", projectName1); var scheduleTrigger = xdoc.SelectSingleNode(xslt); if (scheduleTrigger == null) { throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Schedule trigger not found via xslt {0} in configfile {1}", xslt, CCNetConfigFile)); } string newIntegrationTime = System.DateTime.Now.AddSeconds(SecondsToWaitFromNow).ToString("HH:mm"); Log("--------------------------------------------------------------------------"); Log(string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} is scheduled to integrate at {1}", projectName1, newIntegrationTime)); Log("--------------------------------------------------------------------------"); scheduleTrigger.Attributes["time"].Value = newIntegrationTime; xdoc.Save(CCNetConfigFile); Log("Clear existing state file, to simulate first run : " + Project1StateFile); System.IO.File.Delete(Project1StateFile); Log("Clear existing state file, to simulate first run : " + Project2StateFile); System.IO.File.Delete(Project2StateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, projectName1); CCNet.Remote.Messages.ProjectRequest pr2 = new CCNet.Remote.Messages.ProjectRequest(null, projectName2); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); Log("Forcing build on project " + projectName2 + " so it has a ok build state"); CheckResponse(cruiseServer.ForceBuild(pr2)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete of : " + projectName2); while (!IntegrationCompleted[projectName2]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } Log("Waiting for integration to complete of : " + projectName1); while (!IntegrationCompleted[projectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(2, psr.Projects.Count, "Amount of projects in configfile is not correct." + CCNetConfigFile); CCNet.Remote.ProjectStatus ps = null; // checking data of project 1 foreach (var p in psr.Projects) { if (p.Name == projectName1) { ps = p; } } Assert.AreEqual(projectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName1); // checking data of project 2 foreach (var p in psr.Projects) { if (p.Name == projectName2) { ps = p; } } Assert.AreEqual(projectName2, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName2); }
public void PackagePublisherWithoutFlattenFiles() { const string ProjectName1 = "PackageTest02"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest02" + (Platform.IsWindows ? "" : "_linux") + ".xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>(); string workingDirectory = "Packaging02"; string InfoFolder = "Info"; string subInfoFolder = "Sub1"; string FolderContainingFiles = string.Format("{0}{3}{1}{3}{2}", workingDirectory, InfoFolder, subInfoFolder, System.IO.Path.DirectorySeparatorChar); string f1 = string.Format("{0}{1}a.txt", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar); string f2 = string.Format("{0}{1}b.txt", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar); string f3 = string.Format("{0}{1}c.rtf", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar); var ios = new CCNet.Core.Util.IoService(); ios.DeleteIncludingReadOnlyObjects(FolderContainingFiles); System.IO.Directory.CreateDirectory(FolderContainingFiles); System.IO.File.WriteAllText(f1, "somedata"); System.IO.File.WriteAllText(f2, "somedata"); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}TestPackage.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar); Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location"); ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile); List <string> actualFiles = new List <string>(); foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf) { System.Diagnostics.Debug.WriteLine(ze.Name); actualFiles.Add(ze.Name); } actualFiles.Sort(); Assert.AreEqual(@"Info/Sub1/a.txtInfo/Sub1/b.txt", String.Join("", actualFiles)); }
public void PackagePublisherPackageFolderMustRespectHierarchy() { const string ProjectName1 = "PackageTest03"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest03.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; IntegrationCompleted = new System.Collections.Generic.Dictionary<string, bool>(); string workingDirectory = "Packaging03"; string infoFolder = string.Format("{0}{1}some{1}directories{1}deeper{1}_PublishedWebsites{1}MyProject{1}", workingDirectory, System.IO.Path.DirectorySeparatorChar); string subInfoFolder = string.Format("{0}{1}AFolder{1}", infoFolder, System.IO.Path.DirectorySeparatorChar); string f1 = string.Format("{0}{1}a.txt", infoFolder, System.IO.Path.DirectorySeparatorChar); string f2 = string.Format("{0}{1}b.txt", subInfoFolder, System.IO.Path.DirectorySeparatorChar); var ios = new CCNet.Core.Util.IoService(); ios.DeleteIncludingReadOnlyObjects(infoFolder); ios.DeleteIncludingReadOnlyObjects("TheMegaWebSite"); System.IO.Directory.CreateDirectory(infoFolder); System.IO.Directory.CreateDirectory(subInfoFolder); System.IO.File.WriteAllText(f1, "somedata"); System.IO.File.WriteAllText(f2, "somedata"); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) System.IO.Directory.Delete(IntegrationFolder, true); CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler<ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) System.Threading.Thread.Sleep(250); Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler<ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}Project-package.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar); Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location"); ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile); string expectedFiles = string.Empty; foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf) { System.Diagnostics.Debug.WriteLine(ze.Name); expectedFiles += ze.Name; } Assert.AreEqual(@"MegaWebSite/AFolder/b.txtMegaWebSite/a.txt", expectedFiles); }
public void Simulate() { const string projectName1 = "triggerTest01"; const string projectName2 = "triggerTest02"; var integrationFolder = System.IO.Path.Combine("scenarioTests", projectName1); var ccNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "Triggers.xml"); var project1StateFile = new System.IO.FileInfo(projectName1 + ".state").FullName; var project2StateFile = new System.IO.FileInfo(projectName2 + ".state").FullName; IntegrationCompleted.Add(projectName1, false); IntegrationCompleted.Add(projectName2, false); const Int32 secondsToWaitFromNow = 120; // adjust triggertime of project 1 to now + 70 seconds (SecondsToWaitFromNow) // this will give the unittest time to create an ok build of project2 // and let the schedule trigger work as normal : check if it is time to integrate and check on the status // 70 seconds should be ok, less time may give problems on slower machines // keep in mind that cruise server is also starting, so this time must also be taken into account // also we want the cuise server to wait for 1 minute, otherwise it starts integrating project 1 immediately var xdoc = new System.Xml.XmlDocument(); xdoc.Load(ccNetConfigFile); var xslt = string.Format(System.Globalization.CultureInfo.CurrentCulture,"/cruisecontrol/project[@name='{0}']/triggers/scheduleTrigger", projectName1); var scheduleTrigger = xdoc.SelectSingleNode(xslt); if (scheduleTrigger == null) { throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Schedule trigger not found,via xslt {0} in configfile {1}", xslt, ccNetConfigFile)); } var newIntegrationTime = System.DateTime.Now.AddSeconds(secondsToWaitFromNow).ToString("HH:mm"); Log("--------------------------------------------------------------------------"); Log(string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0} is scheduled to integrate at {1}", projectName1, newIntegrationTime)); Log("--------------------------------------------------------------------------"); scheduleTrigger.Attributes["time"].Value = newIntegrationTime; xdoc.Save(ccNetConfigFile); Log("Clear existing state file, to simulate first run : " + project1StateFile); System.IO.File.Delete(project1StateFile); Log("Clear existing state file, to simulate first run : " + project2StateFile); System.IO.File.Delete(project2StateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(integrationFolder)) System.IO.Directory.Delete(integrationFolder, true); CCNet.Remote.Messages.ProjectStatusResponse psr; var pr1 = new CCNet.Remote.Messages.ProjectRequest(null, projectName1); var pr2 = new CCNet.Remote.Messages.ProjectRequest(null, projectName2); Log("Making CruiseServerFactory"); var csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + ccNetConfigFile); using (var cruiseServer = csf.Create(true, ccNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler<ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); Log("Forcing build on project " + projectName1 + " to test the innertrigger"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete of : " + projectName1); while (!IntegrationCompleted[projectName1]) { for (int i = 1; i <= 4; i++) System.Threading.Thread.Sleep(250); Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler<ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(2, psr.Projects.Count, "Amount of projects in configfile is not correct." + ccNetConfigFile); CCNet.Remote.ProjectStatus ps = null; // checking data of project 1 foreach (var p in psr.Projects) { if (p.Name == projectName1) ps = p; } Assert.AreEqual(projectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName1); // checking data of project 2 foreach (var p in psr.Projects) { if (p.Name == projectName2) ps = p; } Assert.AreEqual(projectName2, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Unknown , ps.BuildStatus, "wrong build state for project " + projectName2); }
/// <summary> /// Starts the actual application. /// </summary> /// <param name="args">The arguments for the application.</param> /// <param name="usesShadowCopying">A flag indicating whether shadow copying should be used.</param> /// <returns> /// The return code for the application. /// </returns> public int Run(string[] args, bool usesShadowCopying) { // Parse the command line arguments var webOptions = new WebApiOptions(); var consoleArgs = new ConsoleRunnerArguments(); var opts = new OptionSet(); opts.Add("h|?|help", "display this help screen", v => consoleArgs.ShowHelp = v != null) .Add("c|config=", "the configuration file to use (defaults to ccnet.conf)", v => consoleArgs.ConfigFile = v) .Add("r|remoting=", "turn remoting on/off (defaults to on)", v => consoleArgs.UseRemoting = v == "on") .Add("p|project=", "the project to integrate (???)", v => consoleArgs.Project = v) .Add("v|validate", "validate the configuration file and exit", v => consoleArgs.ValidateConfigOnly = v != null) .Add("l|logging=", "turn logging on/off (defaults to on)", v => consoleArgs.Logging = v == "on") .Add("sc|shadowCopy=", "turn shadow copying on/off (defaults to on)", v => usesShadowCopying = v == "on") .Add("e|errorpause=", "turn pause on error on/off (defaults to on)", v => consoleArgs.PauseOnError = v == "on") .Add("we|webEndPoint=", "the base endpoint for the web API (default none)", v => webOptions.BaseEndpoint = v); try { opts.Parse(args); } catch (OptionException e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); return 1; } // Display the help if (consoleArgs.ShowHelp) { DisplayHelp(opts); return 0; } ICruiseServerFactory factory = null; try { // Start the actual console runner if (webOptions.IsConfigured) { var apiFactory = new WebApiServerFactory(); apiFactory.StartWebApi(apiFactory, webOptions); factory = apiFactory; } else { factory = new CruiseServerFactory(); } runner = new ConsoleRunner(consoleArgs, factory); if (!usesShadowCopying) { Log.Warning("Shadow-copying has been turned off - hot-swapping will not work!"); } runner.Run(); return 0; } catch (Exception ex) { Log.Error(ex); if (consoleArgs.PauseOnError) { Console.WriteLine("An unexpected error has caused the console to crash"); Console.ReadKey(); } return 2; } finally { // Clean up runner = null; var disposable = factory as IDisposable; if (disposable != null) { disposable.Dispose(); } } }