diff --git a/Fake.sln b/Fake.sln index 641cabab5bd..113d6e2f4cf 100644 --- a/Fake.sln +++ b/Fake.sln @@ -114,6 +114,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.JavaScript.Yarn", "src EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.Sql.DacPac", "src/app/Fake.Sql.DacPac/Fake.Sql.DacPac.fsproj", "{3BC4A91C-3381-4BF9-BF11-8E06706CF878}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.Tools.Pickles", "src/app/Fake.Tools.Pickles/Fake.Tools.Pickles.fsproj", "{2EC1798B-3AD5-42FE-9406-F358B995ACC3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -736,6 +738,18 @@ Global {3BC4A91C-3381-4BF9-BF11-8E06706CF878}.Release|x64.Build.0 = Release|Any CPU {3BC4A91C-3381-4BF9-BF11-8E06706CF878}.Release|x86.ActiveCfg = Release|Any CPU {3BC4A91C-3381-4BF9-BF11-8E06706CF878}.Release|x86.Build.0 = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|x64.ActiveCfg = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|x64.Build.0 = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|x86.ActiveCfg = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Debug|x86.Build.0 = Debug|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|Any CPU.Build.0 = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|x64.ActiveCfg = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|x64.Build.0 = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|x86.ActiveCfg = Release|Any CPU + {2EC1798B-3AD5-42FE-9406-F358B995ACC3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -794,6 +808,7 @@ Global {B636A082-4DB4-439D-8A37-E5214BDC00A3} = {901F162F-8925-4390-89C5-9EE2C343F744} {DE7579F2-C20F-4C35-BC04-C10362912243} = {901F162F-8925-4390-89C5-9EE2C343F744} {3BC4A91C-3381-4BF9-BF11-8E06706CF878} = {7BFFAE76-DEE9-417A-A79B-6A6644C4553A} + {2EC1798B-3AD5-42FE-9406-F358B995ACC3} = {7BFFAE76-DEE9-417A-A79B-6A6644C4553A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {058A0C5E-2216-4306-8AFB-0AE28320C26A} diff --git a/build.fsx b/build.fsx index 5e95cbb0016..0e91c797869 100644 --- a/build.fsx +++ b/build.fsx @@ -292,6 +292,7 @@ let dotnetAssemblyInfos = "Fake.netcore", "Command line tool" "Fake.Runtime", "Core runtime features" "Fake.Tools.Git", "Running git commands" + "Fake.Tools.Pickles", "Convert Gherkin to HTML" "Fake.Testing.Common", "Common testing data types" "Fake.Tracing.NAntXml", "NAntXml" "Fake.Windows.Chocolatey", "Running and packaging with Chocolatey" diff --git a/help/markdown/fake-tools-pickles.md b/help/markdown/fake-tools-pickles.md new file mode 100644 index 00000000000..086bf2cef82 --- /dev/null +++ b/help/markdown/fake-tools-pickles.md @@ -0,0 +1,31 @@ +# Convert Gherkin to HTML with Pickles + +[Pickles] is a Living Documentation generator: it takes your Specification (written in Gherkin, with Markdown descriptions) and turns them into an always up-to-date documentation of the current state of your software - in a variety of formats. + +## Minimal working example + +```fsharp +#r "paket: +nuget Fake.Core.Target +nuget Fake.IO.FileSystem +nuget Fake.Tools.Pickles //" + +open Fake.Core +open Fake.Core.TargetOperators +open Fake.IO.FileSystemOperators +open Fake.Tools +open System.IO + +let currentDirectory = Directory.GetCurrentDirectory() + +Target.create "BuildDoc" (fun _ -> + Pickles.convert (fun p -> + { p with FeatureDirectory = currentDirectory "Specs" + OutputDirectory = currentDirectory "SpecDocs" + OutputFileFormat = Pickles.DocumentationFormat.DHTML }) +) + +Target.runOrDefault "BuildDoc" +``` + +[Pickles]: http://www.picklesdoc.com/ \ No newline at end of file diff --git a/help/templates/template.cshtml b/help/templates/template.cshtml index 4a4c303bc46..404c0c06b62 100644 --- a/help/templates/template.cshtml +++ b/help/templates/template.cshtml @@ -128,6 +128,7 @@ Tools
  • diff --git a/src/app/Fake.Tools.Pickles/AssemblyInfo.fs b/src/app/Fake.Tools.Pickles/AssemblyInfo.fs new file mode 100644 index 00000000000..e1cae8c93b8 --- /dev/null +++ b/src/app/Fake.Tools.Pickles/AssemblyInfo.fs @@ -0,0 +1,17 @@ +// Auto-Generated by FAKE; do not edit +namespace System +open System.Reflection + +[] +[] +[] +[] +[] +do () + +module internal AssemblyVersionInformation = + let [] AssemblyTitle = "FAKE - F# Make Convert Gherkin to HTML" + let [] AssemblyProduct = "FAKE - F# Make" + let [] AssemblyVersion = "5.0.0" + let [] AssemblyInformationalVersion = "5.0.0-rc005" + let [] AssemblyFileVersion = "5.0.0" diff --git a/src/app/Fake.Tools.Pickles/Fake.Tools.Pickles.fsproj b/src/app/Fake.Tools.Pickles/Fake.Tools.Pickles.fsproj new file mode 100644 index 00000000000..9cc62bf2750 --- /dev/null +++ b/src/app/Fake.Tools.Pickles/Fake.Tools.Pickles.fsproj @@ -0,0 +1,25 @@ + + + net46;netstandard1.6;netstandard2.0 + $(DefineConstants);NO_DOTNETCORE_BOOTSTRAP + Fake.Tools.Pickles + Library + + + $(DefineConstants);NETSTANDARD;USE_HTTPCLIENT + + + $(DefineConstants);RELEASE + + + + + + + + + + + + + diff --git a/src/app/Fake.Tools.Pickles/Pickles.fs b/src/app/Fake.Tools.Pickles/Pickles.fs new file mode 100644 index 00000000000..3e416b57be0 --- /dev/null +++ b/src/app/Fake.Tools.Pickles/Pickles.fs @@ -0,0 +1,224 @@ +/// Contains tasks to run the [Pickles](http://www.picklesdoc.com/) living documentation generator +/// +/// ## Sample usage +/// +/// ``` +/// open Fake.Tools +/// +/// Target "BuildDoc" (fun _ -> +/// Pickles.convert (fun p -> { p with +/// FeatureDirectory = currentDirectory @@ "Specs" +/// OutputDirectory = currentDirectory @@ "SpecDocs" }) +/// ) +/// ``` +/// + +[] +module Fake.Tools.Pickles + +open System +open System.Text +open Fake.Core +open Fake.IO +open Fake.IO.Globbing +open Fake.IO.FileSystemOperators +open System.IO + +(* +.\packages\Pickles.CommandLine\tools\pickles.exe --help +Pickles version 2.18.1.0 + -f, --feature-directory=VALUE + directory to start scanning recursively for + features + -o, --output-directory=VALUE + directory where output files will be placed + --trfmt, --test-results-format=VALUE + the format of the linked test results + (nunit|nunit3|xunit|xunit2|mstest + |cucumberjson|specrun|vstest) + --lr, --link-results-file=VALUE + the path to the linked test results file (can be + a semicolon-separated list of files) + --sn, --system-under-test-name=VALUE + the name of the system under test + --sv, --system-under-test-version=VALUE + the version of the system under test + -l, --language=VALUE the language of the feature files + --df, --documentation-format=VALUE + the format of the output documentation + -v, --version + -h, -?, --help + --exp, --include-experimental-features + whether to include experimental features + --cmt, --enableComments=VALUE + whether to enable comments in the output + --et, --excludeTags=VALUE + exclude scenarios that match this tag +*) + +/// Option which allows to specify if failure of pickles should break the build. +type ErrorLevel = + /// This option instructs FAKE to break the build if pickles fails to execute + | Error + /// With this option set, no exception is thrown if pickles fails to execute + | DontFailBuild + +/// The format of the test results +type TestResultsFormat = + | NUnit + | NUnit3 + | XUnit + | XUnit2 + | MSTest + | CucumberJSON + | SpecRun + | VSTest + + type DocumentationFormat = + | DHTML + | HTML + | Word + | JSON + | Excel + +/// The Pickles parameter type +type PicklesParams = + { /// The path to the Pickles console tool: 'pickles.exe' + ToolPath : string + /// The directory to start scanning recursively for features + FeatureDirectory: string + /// The language of the feature files + FeatureFileLanguage: string option + /// The directory where output files will be placed + OutputDirectory: string + /// The format of the output documentation + OutputFileFormat: DocumentationFormat + /// the format of the linked test results + TestResultsFormat: TestResultsFormat + /// the paths to the linked test results files + LinkedTestResultFiles: string list + /// The name of the system under test + SystemUnderTestName: string option + /// The version of the system under test + SystemUnderTestVersion: string option + /// Maximum time to allow xUnit to run before being killed. + TimeOut : TimeSpan + /// Option which allows to specify if failure of pickles should break the build. + ErrorLevel : ErrorLevel + /// Option which allows to enable some experimental features + IncludeExperimentalFeatures : bool option + } + +let private currentDirectory = Directory.GetCurrentDirectory() + +/// The Pickles default parameters +/// +/// ## Defaults +/// +/// - `ToolPath` - The `pickles.exe` if it exists in a subdirectory of the current directory +/// - `FeatureDirectory` - 'currentDirectory' +/// - `FeatureFileLanguage` - 'None' (defaults to `en`) +/// - `OutputDirectory` - `currentDirectory @@ "Documentation"` +/// - `OutputFileFormat` - `DHTML` +/// - `TestResultsFormat` - `Nunit` +/// - `LinkedTestResultFiles` - [] +/// - `SystemUnderTestName` - `None` +/// - `SystemUnderTestVersion` - `None` +/// - `TimeOut` - 5 minutes +/// - `ErrorLevel` - `Error` +/// - `IncludeExperimentalFeatures` - `None` +let private PicklesDefaults = + { + ToolPath = Tools.findToolInSubPath "pickles.exe" currentDirectory + FeatureDirectory = currentDirectory + FeatureFileLanguage = None + OutputDirectory = currentDirectory "Documentation" + OutputFileFormat = DHTML + TestResultsFormat = NUnit + LinkedTestResultFiles = [] + SystemUnderTestName = None + SystemUnderTestVersion = None + TimeOut = TimeSpan.FromMinutes 5. + ErrorLevel = Error + IncludeExperimentalFeatures = None + } + +let private buildPicklesArgs parameters = + let outputFormat = match parameters.OutputFileFormat with + | DHTML -> "dhtml" + | HTML -> "html" + | Word -> "word" + | JSON -> "json" + | Excel -> "excel" + + let testResultFormat = match parameters.LinkedTestResultFiles with + | [] -> None + | _ -> match parameters.TestResultsFormat with + | NUnit -> Some "nunit" + | NUnit3 -> Some "nunit3" + | XUnit -> Some "xunit" + | XUnit2 -> Some "xunit2" + | MSTest -> Some "mstest" + | CucumberJSON -> Some "cucumberjson" + | SpecRun -> Some "specrun" + | VSTest -> Some "vstest" + + let linkedResultFiles = match parameters.LinkedTestResultFiles with + | [] -> None + | _ -> parameters.LinkedTestResultFiles + |> Seq.map (fun f -> sprintf "\"%s\"" f) + |> String.concat ";" + |> Some + let experimentalFeatures = match parameters.IncludeExperimentalFeatures with + | Some true -> Some "--exp" + | _ -> None + + new StringBuilder() + |> StringBuilder.appendWithoutQuotes (sprintf " -f \"%s\"" parameters.FeatureDirectory) + |> StringBuilder.appendWithoutQuotes (sprintf " -o \"%s\"" parameters.OutputDirectory) + |> StringBuilder.appendIfSome parameters.SystemUnderTestName (sprintf " --sn %s") + |> StringBuilder.appendIfSome parameters.SystemUnderTestVersion (sprintf " --sv %s") + |> StringBuilder.appendIfSome parameters.FeatureFileLanguage (sprintf " -l %s") + |> StringBuilder.appendWithoutQuotes (sprintf " --df %s" outputFormat) + |> StringBuilder.appendIfSome testResultFormat (sprintf " --trfmt %s") + |> StringBuilder.appendIfSome linkedResultFiles (sprintf " --lr %s") + |> StringBuilder.appendIfSome experimentalFeatures (sprintf "%s") + |> StringBuilder.toText + +module internal ResultHandling = + let (|OK|Failure|) = function + | 0 -> OK + | x -> Failure x + + let buildErrorMessage = function + | OK -> None + | Failure errorCode -> + Some (sprintf "Pickles reported an error (Error code %d)" errorCode) + + let failBuildWithMessage = function + | DontFailBuild -> Trace.traceImportant + | _ -> failwith + + let failBuildIfPicklesReportedError errorLevel = + buildErrorMessage + >> Option.iter (failBuildWithMessage errorLevel) + +/// Runs pickles living documentation generator via the given tool +/// Will fail if the pickles command line tool terminates with a non zero exit code. +/// +/// The pickles command line tool terminates with a non-zero exit code if there +/// is any error. +/// +/// ## Parameters +/// - `setParams` - Function used to manipulate the default `PicklesParams` value +let convert setParams = + use __ = Trace.traceTask "Pickles" "" + let parameters = setParams PicklesDefaults + let makeProcessStartInfo info = + { info with FileName = parameters.ToolPath + WorkingDirectory = "." + Arguments = parameters |> buildPicklesArgs } + + let result = Process.execSimple makeProcessStartInfo parameters.TimeOut + + ResultHandling.failBuildIfPicklesReportedError parameters.ErrorLevel result diff --git a/src/app/Fake.Tools.Pickles/paket.references b/src/app/Fake.Tools.Pickles/paket.references new file mode 100644 index 00000000000..2c8a7ddfd73 --- /dev/null +++ b/src/app/Fake.Tools.Pickles/paket.references @@ -0,0 +1,4 @@ +group netcore + +FSharp.Core +NETStandard.Library \ No newline at end of file diff --git a/src/legacy/FakeLib/PicklesHelper.fs b/src/legacy/FakeLib/PicklesHelper.fs index 7a3654038e8..a6a0812c9bc 100644 --- a/src/legacy/FakeLib/PicklesHelper.fs +++ b/src/legacy/FakeLib/PicklesHelper.fs @@ -1,4 +1,5 @@ /// Contains tasks to run the [Pickles](http://www.picklesdoc.com/) living documentation generator +[] module Fake.PicklesHelper open System @@ -33,6 +34,7 @@ Pickles version 2.6.1.0 whether to include experimental features *) +[] /// Option which allows to specify if failure of pickles should break the build. type PicklesErrorLevel = /// This option instructs FAKE to break the build if pickles fails to execute @@ -40,6 +42,7 @@ type PicklesErrorLevel = /// With this option set, no exception is thrown if pickles fails to execute | DontFailBuild +[] /// The format of the test results type TestResultsFormat = | Nunit @@ -52,6 +55,7 @@ type TestResultsFormat = | SpecRun | VSTest +[] type DocumentationFormat = | DHTML | HTML @@ -59,6 +63,7 @@ type TestResultsFormat = | JSON | Excel +[] /// The Pickles parameter type [] type PicklesParams = @@ -104,6 +109,7 @@ type PicklesParams = /// - `TimeOut` - 5 minutes /// - `ErrorLevel` - `Error` /// - `IncludeExperimentalFeatures` - `None` +[] let PicklesDefaults = { ToolPath = findToolInSubPath "pickles.exe" currentDirectory @@ -190,14 +196,7 @@ module internal ResultHandling = /// /// ## Parameters /// - `setParams` - Function used to manipulate the default `PicklesParams` value -/// -/// ## Sample usage -/// -/// Target "BuildDoc" (fun _ -> -/// Pickles (fun p -> { p with -/// FeatureDirectory = currentDirectory @@ "Specs" -/// OutputDirectory = currentDirectory @@ "SpecDocs" }) -/// ) +[] let Pickles setParams = use __ = traceStartTaskUsing "Pickles" "" let parameters = setParams PicklesDefaults