diff --git a/src/app/Fake.Core.CommandLineParsing/docopt.fs/Docopt/UsageParser.fs b/src/app/Fake.Core.CommandLineParsing/docopt.fs/Docopt/UsageParser.fs index 80b0454170e..b6775542c12 100644 --- a/src/app/Fake.Core.CommandLineParsing/docopt.fs/Docopt/UsageParser.fs +++ b/src/app/Fake.Core.CommandLineParsing/docopt.fs/Docopt/UsageParser.fs @@ -1,7 +1,7 @@ namespace Fake.Core exception DocoptException of string - with override x.Message = sprintf "DocoptException: %s" x.Data0 + with override x.Message = sprintf "%s" x.Data0 namespace Fake.Core.CommandLineParsing @@ -12,13 +12,17 @@ open System.Text exception private InternalException of ErrorMessageList exception UsageException of string - with override x.Message = sprintf "UsageException: %s" x.Data0 + with override x.Message = sprintf "%s" x.Data0 module private Helpers = let raiseArgvException errlist' = let pos = Position(null, 0L, 0L, 0L) in let perror = ParserError(pos, null, errlist') in raise (DocoptException(perror.ToString())) + let improveErrorText (lnNr:int64) (colNr:int64) (arg:string) (oldText:string) = + oldText.Replace( + sprintf "argv: Ln: %d Col: %d" lnNr colNr, + sprintf "Argument %d ('%s')" (colNr + 1L) arg) let unexpectedShort = string >> ( + ) "short option -" >> unexpected @@ -851,11 +855,14 @@ type UsageParser(usageStrings':string array, sections:(string * SafeOptions) lis let state = ArgumentStream.create argv Map.empty let reply = pAstParser state let errors = ErrorMessageList.ToSortedArray(reply.Error) - let parseError = ParserError(Position("argv", int64 state.Position.ArgIndex,0L,int64 state.Position.ArgIndex), state.UserState, reply.Error) + let argIdx = int64 state.Position.ArgIndex + let parseError = ParserError(Position("argv", argIdx,0L,argIdx), state.UserState, reply.Error) let errorText = use sw = new System.IO.StringWriter() parseError.WriteTo(sw) sw.ToString() + |> Helpers.improveErrorText 0L argIdx (if argIdx >= 0L && int argIdx < argv.Length then argv.[int argIdx] else "<>") + match reply.Status = ReplyStatus.Ok, errors, state.IsEnd with | true, [||], true -> reply.Result | _, _ , true -> raise <| DocoptException (sprintf "errors %s: %s" (printReplyStatus reply.Status) errorText) diff --git a/src/app/Fake.netcore/Cli.fs b/src/app/Fake.netcore/Cli.fs index bbcbeaa4ee9..5badbdec912 100644 --- a/src/app/Fake.netcore/Cli.fs +++ b/src/app/Fake.netcore/Cli.fs @@ -5,6 +5,23 @@ module Cli open System open Fake.Core.CommandLineParsing +let fakeArgsHint = + """ +General: + + Fake command line is devided into runtime and script arguments. + Runtime arguments control compilation and processing of the script, + while script arguments are specific for the script or provided by + a NuGet package. + In most use cases you use the "Fake.Core.Target"-Module and therefore + inherit the correspondig command line interface. While these arguments + are not strictly part of the runtime we still show both below to + make it easier for newcomers. + + -- RUNTIME ARGUMENTS SECTION -- + +""" + let fakeUsage = """ Usage: @@ -37,4 +54,37 @@ Fake Build Options [build_opts]: --fsiargs [*] Arguments passed to the f# interactive. -f, --script The script to execute (defaults to `build.fsx`). +""" + +let fakeAdditionalHelp = """ + + -- SCRIPT ARGUMENTS SECTION -- + +THIS SECTION ONLY APPLIES IF YOU USE THE +'Fake.Core.Target' PACKAGE! +You can use the following arguments in place of ``: + +Usage: + fake-run --list + fake-run --version + fake-run --help | -h + fake-run [target_opts] [target ] [--] [...] + +Target Module Options [target_opts]: + -t, --target + Run the given target (ignored if positional +argument 'target' is given) + -e, --environment-variable [*] + Set an environment variable. Use 'key=val'. +Consider using regular arguments, see https://fake.build/core-targets.html + -s, --single-target Run only the specified target. + -p, --parallel Run parallel with the given number of tasks. + +Example: + +To use verbose mode (from [fake_opts]) and print all +targets use "fake -v build -- --list". Because "--list" +doesn't conflict with any of the [build_opts], you can use +"fake -v build --list" +""" \ No newline at end of file diff --git a/src/app/Fake.netcore/Program.fs b/src/app/Fake.netcore/Program.fs index 615007c2f06..eafcc7d5818 100644 --- a/src/app/Fake.netcore/Program.fs +++ b/src/app/Fake.netcore/Program.fs @@ -229,12 +229,15 @@ let handleAction (verboseLevel:VerboseLevel) (action:CliAction) = traceFAKE "Paket.Core: %s" Fake.Runtime.FakeRuntimeHints.paketVersion 0 | ShowHelp -> + printf "%s" Cli.fakeArgsHint printf "%s" Cli.fakeUsage - printfn "Hint: Run 'fake run --help' to get help from your script." + printf "%s" Cli.fakeAdditionalHelp 0 | InvalidUsage str -> eprintfn "%s" str - printfn "%s" Cli.fakeUsage + printf "%s" Cli.fakeArgsHint + printf "%s" Cli.fakeUsage + printf "%s" Cli.fakeAdditionalHelp 1 | RunOrBuild arg -> let success = runOrBuild arg @@ -334,7 +337,16 @@ let main (args:string[]) = exitCode <- handleAction verbLevel results with | exn -> - printfn "Error while parsing command line, usage is:\n%s" Cli.fakeUsage + printfn "Error while parsing command line, usage is:" + printf "%s" Cli.fakeArgsHint + printf "%s" Cli.fakeUsage + printf "%s" Cli.fakeAdditionalHelp + + // need to enable this as otherwise no proper error is reported + use consoleTrace = + // When silent we don't want Paket output + Paket.Logging.event.Publish + |> Observable.subscribe Paket.Logging.traceToConsole reportExn VerboseLevel.Normal exn exitCode <- 1 Console.OutputEncoding <- encoding