Skip to content

Commit e026726

Browse files
committed
Added "--start-paused" CLI option, since System.CommandLine no longer supports "[debug]" directive.
See related issues: dotnet/command-line-api#1613 dotnet/command-line-api#1607
1 parent 729bc70 commit e026726

File tree

1 file changed

+36
-11
lines changed

1 file changed

+36
-11
lines changed

src/RhetosCli/Program.cs

+36-11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ You should have received a copy of the GNU Affero General Public License
2626
using System;
2727
using System.Collections.Generic;
2828
using System.CommandLine;
29+
using System.Diagnostics;
2930
using System.IO;
3031
using System.Linq;
3132
using System.Threading.Tasks;
@@ -93,28 +94,38 @@ enum VerbosityLevel
9394
public static int Run(string[] args)
9495
{
9596
var verbosityOption = new Option<VerbosityLevel>("--verbosity", () => VerbosityLevel.Normal, "Output verbosity level. Allowed values are normal and diagnostic.");
96-
var traceOption = new Option<string[]>("--trace", () => Array.Empty<string>(), "Output additional trace loggers specified by name.");
97+
var traceOption = new Option<string[]>("--trace", "Output additional trace loggers specified by name.");
9798
var msbuildFormatOption = new Option<bool>("--msbuild-format", () => false, "Adjust error output format for MSBuild integration.");
99+
var startPausedOption = new Option<bool>("--start-paused", "Start paused, to allow attaching a debugger. Works only on interactive environment.");
98100
var rootCommand = new RootCommand
99101
{
100102
verbosityOption,
101103
traceOption,
102-
msbuildFormatOption
104+
msbuildFormatOption,
105+
startPausedOption,
103106
};
104107

105-
// Using 'CurrentDirectory' by default, because rhetos.exe on *build* is expected to be located in NuGet package cache.
106-
var projectRootFolderArgument = new Argument<DirectoryInfo>("project-root-folder", () => new DirectoryInfo(Environment.CurrentDirectory)) { Description = "Project folder where csproj file is located. If not specified, current working directory is used by default." };
108+
//===============================================
109+
// 'build' command:
110+
111+
// Using CurrentDirectory by default, because rhetos.exe on *build* is expected to be located in NuGet package cache.
112+
var projectRootFolderArgument = new Argument<DirectoryInfo>("project-root-folder", () => new DirectoryInfo(Environment.CurrentDirectory)) { Description = "Project folder where .csproj file is located. If not specified, current working directory is used by default." };
107113
var buildCommand = new Command("build", "Generates C# code, database model file and other project assets.")
108114
{
109115
projectRootFolderArgument
110116
};
111-
buildCommand.SetHandler((DirectoryInfo projectRootFolder, bool msbuildFormat, VerbosityLevel verbosity, string[] trace) =>
112-
{
113-
var program = new Program(verbosity, trace, msbuildFormat);
114-
return program.SafeExecuteCommand(() => program.Build(projectRootFolder.FullName), "Build");
115-
}, projectRootFolderArgument, msbuildFormatOption, verbosityOption, traceOption);
117+
buildCommand.SetHandler((DirectoryInfo projectRootFolder, bool msbuildFormat, VerbosityLevel verbosity, string[] trace, bool startPaused) =>
118+
{
119+
StartPausedIfEnabled(startPaused);
120+
var program = new Program(verbosity, trace, msbuildFormat);
121+
return program.SafeExecuteCommand(() => program.Build(projectRootFolder.FullName), "Build");
122+
},
123+
projectRootFolderArgument, msbuildFormatOption, verbosityOption, traceOption, startPausedOption);
116124
rootCommand.AddCommand(buildCommand);
117125

126+
//===============================================
127+
// 'dbupdate' command:
128+
118129
var startupAssemblyArgument = new Argument<FileInfo>("startup-assembly") { Description = "Startup assembly of the host application." };
119130
var shortTransactionsOption = new Option<bool>("--short-transactions", "Commit transaction after creating or dropping each database object.");
120131
var skipRecomputeOption = new Option<bool>("--skip-recompute", "Skip automatic update of computed data with KeepSynchronized. See output log for data that needs updating.");
@@ -132,19 +143,33 @@ public static int Run(string[] args)
132143
skipRecomputeOption,
133144
executeCommandInCurrentProcessOption
134145
};
135-
dbUpdateCommand.SetHandler((FileInfo startupAssembly, bool shortTransactions, bool skipRecompute, bool executeCommandInCurrentProcess, bool msbuildFormat, VerbosityLevel verbosity, string[] trace) =>
146+
dbUpdateCommand.SetHandler((FileInfo startupAssembly, bool shortTransactions, bool skipRecompute, bool executeCommandInCurrentProcess, bool msbuildFormat, VerbosityLevel verbosity, string[] trace, bool startPaused) =>
136147
{
148+
StartPausedIfEnabled(startPaused);
137149
var program = new Program(verbosity, trace, msbuildFormat);
138150
if (executeCommandInCurrentProcess)
139151
return program.SafeExecuteCommand(() => program.DbUpdate(startupAssembly.FullName, shortTransactions, skipRecompute), "DbUpdate");
140152
else
141153
return program.InvokeDbUpdateAsExternalProcess(startupAssembly.FullName, args);
142-
}, startupAssemblyArgument, shortTransactionsOption, skipRecomputeOption, executeCommandInCurrentProcessOption, msbuildFormatOption, verbosityOption, traceOption);
154+
},
155+
startupAssemblyArgument, shortTransactionsOption, skipRecomputeOption, executeCommandInCurrentProcessOption, msbuildFormatOption, verbosityOption, traceOption, startPausedOption);
143156
rootCommand.AddCommand(dbUpdateCommand);
144157

158+
//===============================================
159+
145160
return rootCommand.Invoke(args);
146161
}
147162

163+
private static void StartPausedIfEnabled(bool startPaused)
164+
{
165+
if (startPaused && Environment.UserInteractive)
166+
{
167+
var currentProcess = Process.GetCurrentProcess();
168+
Console.WriteLine($"Attach the debugger to process '{currentProcess.MainModule?.ModuleName}' ({currentProcess.Id}) and press any key to continue ...");
169+
Console.ReadKey();
170+
};
171+
}
172+
148173
private Task<int> SafeExecuteCommand(Action action, string commandName)
149174
{
150175
var logger = _logProvider.GetLogger("Rhetos " + commandName);

0 commit comments

Comments
 (0)