dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.93k stars 788 forks source link

fsi.CommandLineArgs different behavior on -d/-r/-I args, ignores --. #10819

Open JamesMarionTech opened 3 years ago

JamesMarionTech commented 3 years ago

fsi.CommandLineArgs is treating the -d, -r, and -I args differently to any other passed arg. When it has an arg ahead of it, the two args are joined together with a colon, rather than separated into two separate array items. This behaviour occurs even if these args follow -- (double dash).

An example of what happens: [| "-d:5"; |] instead of [| "-d"; "5"; |]

This is not an underlying issue with System.Environment.GetCommandLineArgs(), as that method provides the expected results.

Repro steps Create test.fsx with the following code: printfn "%A" fsi.CommandLineArgs Run with the following args to see the bare minimum needed for the bad cases: dotnet fsi test.fsx -d 5 // [| "test.fsx"; "-d:5"; |] dotnet fsi test.fsx -r 5 // [| "test.fsx"; "-r:5"; |] dotnet fsi test.fsx -I 5 // [| "test.fsx"; "-I:5"; |] Even running with -- doesn't change the result: dotnet fsi test.fsx -- -d 5 // [| "test.fsx"; "--"; "-d:5"; |] Run with the following args to see the expected behaviour: dotnet fsi test.fsx -b 5 // [| "test.fsx"; "-b"; "5"; |] dotnet fsi test.fsx -- -b 5 // [| "test.fsx"; "--"; "-b"; "5"; |] 5 can be anything.

Expected behavior

fsi.CommandLineArgs should be an array where the args separated by spaces are all individual strings. If this is not the case, then -- should prevent the args from being mutated if the args follow it.

Actual behavior

Two args are combined into one and separated by a colon in a string. To the left of the colon is -d, -r, or -I. To the right is the item that follows.

Known workarounds

Use System.Environment.GetCommandLineArgs() if these specific args need to be used.

Related information

Windows 10 .NET 5.0

KevinRansom commented 3 years ago

@JamesMarionTech , this is a real bug and also by design.

everything after the script is supposed to be the scripts arguments , although the parser sort of doesn't know that.

I will see if I can figure out a fix.

/d, /r and /I are all options with arguments, whereas, b is not.

--debug:{full|pdbonly|portable|embedded} Specify debugging type: full, portable, embedded, pdbonly. ('pdbonly' is the default
                                         if no debuggging type specified and enables attaching a debugger to a running program,
                                         'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded
                                         into the output file).

--define:<string>             Define conditional compilation symbols (Short form: -d)

--lib:<dir;...>                     Specify a directory for the include path which is used to resolve source files and
                                         assemblies (Short form: -I)
lkluc commented 2 years ago

Hello, I stumbled upon the same exact problem :

$ cat Test.fsx ; echo; echo; dotnet fsi Test.fsx -d DATA; dotnet fsi Test.fsx -- -d DATA; fsi Test.fsx -d DATA; fsi Test.fsx -- -d DATA
printfn "Content of fsi.CommandLineArgs : %A" fsi.CommandLineArgs

Content of fsi.CommandLineArgs : [|"Test.fsx"; "DATA"|]
Content of fsi.CommandLineArgs : [|"Test.fsx"; "--"; "-d:DATA"|]
Content of fsi.CommandLineArgs : [|"Test.fsx"; "-d:DATA"|]
Content of fsi.CommandLineArgs : [|"Test.fsx"; "--"; "-d:DATA"|]

None of the results seems acceptable for the "-d" option is totally messed up, and I'm not even sure if the "--" should pass through, it should be intercepted and filtered !

Thanks !