command-line-api
command-line-api copied to clipboard
CLI fails on read-only file system
Steps to reproduce:
- Use
CommandLineBuilder
with.UseDefaults()
- Build a Docker image and run with
--read-only
to use a read-only file system
Expected result: CommandLine shouldn't use RegisterWithDotnetSuggest by default (or at least shouldn't create new files)
Actual result:
Unhandled exception: System.IO.IOException: Read-only file system : '/tmp/system-commandline-sentinel-files'
at [System.IO](http://system.io/).FileSystem.CreateDirectory(String fullPath, UnixFileMode unixCreateMode)
at [System.IO](http://system.io/).DirectoryInfo.Create()
at System.CommandLine.Invocation.FeatureRegistration.EnsureRegistered(Func`1 onInitialize)
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
Workaround:
// call extensions explicitly because .UseDefaults() calls .RegisterWithDotnetSuggest()
var rootCommand = new RootCommand("My App");
var commandLineBuilder = new CommandLineBuilder(rootCommand);
commandLineBuilder
.UseVersionOption()
.UseHelp()
.UseParseDirective()
.UseSuggestDirective()
.UseTypoCorrections()
.UseParseErrorReporting()
.UseExceptionHandler()
.CancelOnProcessTermination();
var parser = commandLineBuilder.Build();
return await parser.InvokeAsync(args);
I recently ran into this as well, except instead of it being a docker readonly file system, it is a readonly file system managed by kubernetes.
Our code avoids the CommandLineBuilder and invokes the command directly. I assume it is some default middleware that needs file system access, seemingly the UseSuggestDirective()
based on searching I've done.
var rootCmd = new RootCommand("My Service");
Environment.ExitCode = rootCmd.Invoice(args);