-
Notifications
You must be signed in to change notification settings - Fork 588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better Old-Style Arg Parsing #1301
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,18 +4,35 @@ open Fake | |
|
||
let printAllParams() = printfn "FAKE.exe [buildScript] [Target] Variable1=Value1 Variable2=Value2 ... " | ||
|
||
(* | ||
This is a set of flags that exist in code lower in the target processing that MUST be normalized to a certain form. This is necessary because | ||
If any old styole variables are present in the FAKE invocation, Argu parsing will fail and we will not have parsed out those commands correctly | ||
from the overall command line. | ||
|
||
You can typically find usages of 'hasBuildParam' in this codebase to find places where these values are required. | ||
*) | ||
let specialFlags = | ||
[ | ||
"-st", "single-target" | ||
"--single-target", "single-target" | ||
"-pd", "details" | ||
"--print-details", "details" | ||
] |> Map.ofList | ||
|
||
let parseArgs cmdArgs = | ||
let splitter = [| '=' |] | ||
let split (arg:string) = | ||
let pos = arg.IndexOfAny splitter | ||
[| arg.Substring(0, pos); arg.Substring(pos + 1, arg.Length - pos - 1) |] | ||
let (|KeyValue|Flag|TargetName|) ((i,arg) : int * string) = | ||
if i = 0 then TargetName arg | ||
else | ||
match arg.IndexOf '=' with | ||
| -1 -> Flag arg | ||
| i -> KeyValue (arg.Substring(0, i), arg.Substring(i + 1, arg.Length - i - 1)) | ||
|
||
cmdArgs | ||
|> Seq.skip 1 | ||
|> Seq.mapi (fun (i : int) (arg : string) -> | ||
if arg.Contains "=" then | ||
let s = split arg | ||
if s.[0] = "logfile" then addXmlListener s.[1] | ||
s.[0], s.[1] | ||
else if i = 0 then "target", arg | ||
else arg, "true") | ||
|> Seq.mapi (fun i a -> match (i, a) with | ||
| TargetName t -> "target", t | ||
| Flag f when Map.containsKey f specialFlags -> Map.find f specialFlags, "true" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only new case, really, where we expand out new-style flags that had special handling in the code (See Program.fs where we yield ('single-target', true) for the new-style args as an example). |
||
| Flag f -> f, "true" | ||
| KeyValue (k,v) when k = "logfile" -> addXmlListener v; (k,v) | ||
| KeyValue kvp -> kvp ) | ||
|> Seq.toList |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,15 +132,16 @@ try | |
match Boot.ParseCommandLine(cmdArgs) with | ||
| None -> | ||
let buildScriptArg = if cmdArgs.Length > 1 && cmdArgs.[1].EndsWith ".fsx" then cmdArgs.[1] else Seq.head buildScripts | ||
let fakeArgs = cmdArgs |> Array.filter (fun x -> x.StartsWith "-d:" = false) | ||
let fsiArgs = cmdArgs |> Array.filter (fun x -> x.StartsWith "-d:") |> Array.toList | ||
let args = CommandlineParams.parseArgs (fakeArgs |> Seq.filter ((<>) buildScriptArg) |> Seq.filter ((<>) "details")) | ||
let fsiArgs, fakeArgs = cmdArgs |> Array.partition (fun x -> x.StartsWith "-d:") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that '-pd' and '--print-details' are being expanded, we can't go check back in |
||
let args = CommandlineParams.parseArgs (fakeArgs |> Seq.filter ((<>) buildScriptArg)) | ||
|
||
traceStartBuild() | ||
let printDetails = containsParam "details" cmdArgs | ||
let printDetails = args |> List.exists (fst >> ((=) "details")) | ||
let argsMinusDetails = args |> List.filter (fst >> ((=) "details")) | ||
let fsiArgsList = fsiArgs |> Seq.toList | ||
if printDetails then | ||
printEnvironment cmdArgs args | ||
if not (runBuildScript printDetails buildScriptArg fsiArgs args true) then Environment.ExitCode <- 1 | ||
if not (runBuildScript printDetails buildScriptArg fsiArgsList argsMinusDetails true) then Environment.ExitCode <- 1 | ||
else if printDetails then log "Ready." | ||
| Some handler -> | ||
handler.Interact() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same logic from the previous version, just captured into an AP to make it very clear what case is what.