runtime: Potential for conflict between runtime args and app args

When running an app with the muxer, you pass runtime args like --roll-forward before the dll like so:

dotnet --roll-forward major myapp.dll myapparg1 ... myappargN

The dll between the runtime args and the app args removed any ambiguity. However, when running an app via apphost, runtime args are passed liked so:

myapp.exe --roll-forward major myapparg1 .. myappargN

Arguments are consumed by host while recognized, and the rest go to the app. Unforunately, this is ambiguous: what if myapp’s Main(string[] args) expects to handle --roll-forward with its own app-specific meaning?

It has been brought to my attention that we have already shipped this way, so it would be breaking to change the scheme for all arguments that are supported in past versions. If we can’t break, I would still like this issue to cover the long-term case of adding new options. The current scheme means that every new runtime option allowed in this command line position is technically a breaking change.

When I raised this elsewhere, the analogy to the -- delimiter used in many places came up, but I still don’t think this would solve it as the app may very well have its own interpretation of --. IMHO, what we use here should not occupy nice-looking, common real estate on the command line. To the extent that we try to make it look nice, we increase the risk of colliding with the apps.

If we were able to start from scratch, I would suggest a scheme like

myapp.exe --$runtime::roll-forward

And we say that the --$runtime:: prefix is reserved. I don’t mean to have a strong opinion for this exact syntax, just trying to illustrate the idea of something that is obscure enough to not conflict with common patterns and provides a sort of namespace where more runtime options can go without risk.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 18 (18 by maintainers)

Most upvoted comments

Perhaps we can combine namespacing and square brackets. We say that in the square bracket world of meta options, there are namespaces. This is our new real estate to specify, right?

One thing to consider is that we should keep the host parsing and stripping of its options simple, though. It starts to get a lot more complicated if it’s strip everything from square brackets with our namespace, and remove square brackets entirely if nothing remains, etc.

@jonsequitor looked at the issue of orthogonal information in the context of directives for System.CommandLine.

A lot of characters we might want to se already have meaning in some context or another.

While the @@ syntax above looks like it would work, I’m concerned about readability. I like the namespace idea early on:

myapp.exe --$runtime::roll-forward

if there is no issue with it. But I also keep coming back to the idea of orthogonal switches being set off with clear orthogonal surrounding delimiters (square brackets only because Jon found them available):

myapp [roll-forward major] [potato] @@ --potato --myapparg1 foo

or

myapp [--roll-forward major --potato] @@ --potato --myapparg1 foo

However, I think this whole conversation would go a lot better if you had adopted the standard unknown switch name of banana rather than switching the switch to potato!

I think I understood the existing semantics of the typical -- scheme less well then you, so I was less confused by it 😉

I would expect it to work like this:

myapp --roll-forward major --potato @@ --potato --myapparg1 foo

The host would scan until it sees @@. If it doesn’t, it doesn’t look at any of arguments string. If it does, it processes/eats everything up until and including @@ and passes the rest to the app. This is similar to other schemes, right?