From 95691a563a2d2eace7561ea7aeaeee47a826ff0a Mon Sep 17 00:00:00 2001 From: Andreas Vilinski Date: Thu, 12 Dec 2019 10:09:21 +0100 Subject: [PATCH 1/2] add WorkingDirectory and dotnet tool support --- .../Fake.Testing.SonarQube.fsproj | 3 +- src/app/Fake.Testing.SonarQube/SonarQube.fs | 102 +++++++++++++----- .../Fake.Testing.SonarQube.fs | 1 - 3 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/app/Fake.Testing.SonarQube/Fake.Testing.SonarQube.fsproj b/src/app/Fake.Testing.SonarQube/Fake.Testing.SonarQube.fsproj index 154721120fd..5e0b514912e 100644 --- a/src/app/Fake.Testing.SonarQube/Fake.Testing.SonarQube.fsproj +++ b/src/app/Fake.Testing.SonarQube/Fake.Testing.SonarQube.fsproj @@ -1,4 +1,4 @@ - + netstandard2.0;net462 $(DefineConstants);NO_DOTNETCORE_BOOTSTRAP @@ -19,6 +19,7 @@ + diff --git a/src/app/Fake.Testing.SonarQube/SonarQube.fs b/src/app/Fake.Testing.SonarQube/SonarQube.fs index c0c725411eb..38eec44f9fc 100644 --- a/src/app/Fake.Testing.SonarQube/SonarQube.fs +++ b/src/app/Fake.Testing.SonarQube/SonarQube.fs @@ -1,10 +1,10 @@ -/// Contains a task to run the msbuild runner of [SonarQube analyzer](http://sonarqube.org). +/// Contains a task to run the [SonarQube](http://sonarqube.org) static code analyzer. +/// It uses the [SonarScanner for MSBuild](https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/) module Fake.Testing.SonarQube open System.IO open Fake.Core - open Fake.IO.Globbing - open Fake.IO.FileSystemOperators + open Fake.DotNet /// [omit] /// The supported commands of SonarQube. It is called with Begin before compilation, and End after compilation. @@ -12,7 +12,11 @@ module Fake.Testing.SonarQube /// Parameter type to configure the SonarQube runner. type SonarQubeParams = { - /// FileName of the SonarQube runner exe. + /// The directory where the SonarQube scanner process will be started. + WorkingDirectory : string + /// Tool type + ToolType : ToolType + /// FileName of the SonarQube runner exe. ToolsPath : string /// Organization which owns the SonarQube project Organization : string option @@ -28,9 +32,11 @@ module Fake.Testing.SonarQube Config : string option } - /// SonarQube default parameters - tries to locate MSBuild.SonarQube.exe in any subfolder. - let internal SonarQubeDefaults = - { ToolsPath = Tools.findToolInSubPath "MSBuild.SonarQube.Runner.exe" (Directory.GetCurrentDirectory() @@ "tools" @@ "SonarQube") + /// SonarQube default parameters + let internal SonarQubeDefaults = + { WorkingDirectory = Directory.GetCurrentDirectory () + ToolType = ToolType.Create() + ToolsPath = ProcessUtils.findLocalTool "TOOL" "MSBuild.SonarQube.Runner.exe" [ "." ] Organization = None Key = null Name = null @@ -47,42 +53,41 @@ module Fake.Testing.SonarQube |> Arguments.appendRawEscapedNotEmpty "/k:" parameters.Key |> Arguments.appendRawEscapedNotEmpty "/n:" parameters.Name |> Arguments.appendRawEscapedNotEmpty "/v:" parameters.Version - |> Arguments.appendRawEscapedOption "/o:" parameters.Organization - |> Arguments.appendRawEscapedOption "/s:" parameters.Config - + |> Arguments.appendRawEscapedOption "/o:" parameters.Organization + |> Arguments.appendRawEscapedOption "/s:" parameters.Config + let beginCall = parameters.Settings |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) beginInitialArguments - + let endInitialArguments = Arguments.Empty |> Arguments.appendRaw "end" |> Arguments.appendRawEscapedOption "/s:" parameters.Config - let endCall = + let endCall = parameters.Settings |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) endInitialArguments - + match call with | Begin -> beginCall | End -> endCall let private sonarQubeCall (call: SonarQubeCall) (parameters : SonarQubeParams) = - let sonarPath = parameters.ToolsPath - let result = - getSonarQubeCallParams call parameters - |> Arguments.toStartInfo - |> CreateProcess.fromRawCommandLine sonarPath - |> CreateProcess.withFramework - |> Proc.run - if result.ExitCode <> 0 then failwithf "Error during sonar qube call %s" (call.ToString()) + let args = getSonarQubeCallParams call parameters + CreateProcess.fromCommand(RawCommand(parameters.ToolsPath, args)) + |> CreateProcess.withToolType (parameters.ToolType.WithDefaultToolCommandName "sonarscanner") + |> CreateProcess.withWorkingDirectory parameters.WorkingDirectory + |> CreateProcess.ensureExitCode + |> Proc.run + |> ignore - /// This task to can be used to run the begin command of [Sonar Qube](http://sonarqube.org/) on a project. + /// This task can be used to run the begin command of [Sonar Qube](http://sonarqube.org/) on a project. /// ## Parameters /// /// - `setParams` - Function used to overwrite the SonarQube default parameters. /// /// ## Sample - + /// /// open Fake.Testing /// /// SonarQube.start (fun p -> @@ -91,31 +96,70 @@ module Fake.Testing.SonarQube /// Name = "MainTool" /// Version = "1.0 }) /// - let start setParams = + let start setParams = use __ = Trace.traceTask "SonarQube" "Begin" let parameters = setParams SonarQubeDefaults sonarQubeCall Begin parameters __.MarkSuccess() - /// This task to can be used to run the end command of [Sonar Qube](http://sonarqube.org/) on a project. + /// This task can be used to run the end command of [Sonar Qube](http://sonarqube.org/) on a project. /// ## Parameters /// /// - `setParams` - Function used to overwrite the SonarQube default parameters. /// /// ## Sample - + /// /// open Fake.Testing /// /// SonarQube.finish None /// /// SonarQube.finish (Some (fun p -> - /// {p with - /// Settings = ["sonar.login=login"; "sonar.password=password"] })) + /// { p with + /// Settings = ["sonar.login=login"; "sonar.password=password"] })) /// - let finish setParams = + let finish setParams = use __ = Trace.traceTask "SonarQube" "End" let parameters = match setParams with | Some setParams -> setParams SonarQubeDefaults | None -> (fun p -> { p with Settings = [] }) SonarQubeDefaults sonarQubeCall End parameters __.MarkSuccess() + + /// This task can be used to execute some code between + /// the `begin` and `end` [Sonar Qube](http://sonarqube.org/) on a project. + /// + /// ## Parameters + /// + /// - `setParams` - Function used to overwrite the SonarQube default parameters. + /// - `doBetween` - Function executed between `begin` and `end` [Sonar Qube](http://sonarqube.org/) commands. + /// + /// ## Sample + /// + /// ``` + /// open Fake.Testing + /// + /// Target.create "StaticAnalysis" (fun _ -> + /// let setParams p = + /// { p with Key = "ProjectKey" + /// Name = "ProjectName" + /// Version = "3.2.1" + /// Settings = + /// [ "sonar.host.url=" + SONAR_HOST_URL + /// "sonar.login=" + SONAR_TOKEN + /// "sonar.cs.opencover.reportsPaths=opencovercoverage.xml" + /// ] + /// // choose what you need + /// // https://fake.build/dotnet-cli.html#SDK-tools-local-global-clireference + /// ToolType = ToolType.CreateGlobalTool() // Start as dotnet global tool (`sonarscanner`) + /// ToolType = ToolType.CreateLocalTool() // Start as dotnet local tool (`dotnet sonarscanner`) + /// } + /// SonarQube.scan setParams (fun () -> + /// DotNet.build id + /// DotNet.test id + /// ) + /// ) + /// ``` + let scan setParams doBetween = + start setParams + doBetween() + finish (Some setParams) diff --git a/src/test/Fake.Core.UnitTests/Fake.Testing.SonarQube.fs b/src/test/Fake.Core.UnitTests/Fake.Testing.SonarQube.fs index 1c0e05f0886..4158b92d533 100644 --- a/src/test/Fake.Core.UnitTests/Fake.Testing.SonarQube.fs +++ b/src/test/Fake.Core.UnitTests/Fake.Testing.SonarQube.fs @@ -1,6 +1,5 @@ module Fake.Testing.SonarQubeTests -open System.IO open Fake.Core open Fake.Testing open Expecto From bde23993c41678a0f6b52a863dd8b9dde0e51599 Mon Sep 17 00:00:00 2001 From: Andreas Vilinski Date: Thu, 12 Dec 2019 10:18:51 +0100 Subject: [PATCH 2/2] fantomas --- src/app/Fake.Testing.SonarQube/SonarQube.fs | 304 ++++++++++---------- 1 file changed, 154 insertions(+), 150 deletions(-) diff --git a/src/app/Fake.Testing.SonarQube/SonarQube.fs b/src/app/Fake.Testing.SonarQube/SonarQube.fs index 38eec44f9fc..656d02510f9 100644 --- a/src/app/Fake.Testing.SonarQube/SonarQube.fs +++ b/src/app/Fake.Testing.SonarQube/SonarQube.fs @@ -2,164 +2,168 @@ /// It uses the [SonarScanner for MSBuild](https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/) module Fake.Testing.SonarQube - open System.IO - open Fake.Core - open Fake.DotNet +open System.IO +open Fake.Core +open Fake.DotNet - /// [omit] - /// The supported commands of SonarQube. It is called with Begin before compilation, and End after compilation. - type internal SonarQubeCall = Begin | End +/// [omit] +/// The supported commands of SonarQube. It is called with Begin before compilation, and End after compilation. +type internal SonarQubeCall = + | Begin + | End - /// Parameter type to configure the SonarQube runner. - type SonarQubeParams = { - /// The directory where the SonarQube scanner process will be started. - WorkingDirectory : string - /// Tool type - ToolType : ToolType - /// FileName of the SonarQube runner exe. - ToolsPath : string - /// Organization which owns the SonarQube project - Organization : string option - /// Key to identify the SonarQube project - Key : string - /// Name of the project - Name : string - /// Version number of the project - Version : string - /// Individual global settings for SonarQube - Settings : string list - /// Read settings from configuration file - Config : string option - } +/// Parameter type to configure the SonarQube runner. +type SonarQubeParams = + { /// The directory where the SonarQube scanner process will be started. + WorkingDirectory: string + /// Tool type + ToolType: ToolType + /// FileName of the SonarQube runner exe. + ToolsPath: string + /// Organization which owns the SonarQube project + Organization: string option + /// Key to identify the SonarQube project + Key: string + /// Name of the project + Name: string + /// Version number of the project + Version: string + /// Individual global settings for SonarQube + Settings: string list + /// Read settings from configuration file + Config: string option } - /// SonarQube default parameters - let internal SonarQubeDefaults = - { WorkingDirectory = Directory.GetCurrentDirectory () - ToolType = ToolType.Create() - ToolsPath = ProcessUtils.findLocalTool "TOOL" "MSBuild.SonarQube.Runner.exe" [ "." ] - Organization = None - Key = null - Name = null - Version = "1.0" - Settings = [] - Config = None } +/// SonarQube default parameters +let internal SonarQubeDefaults = + { WorkingDirectory = Directory.GetCurrentDirectory() + ToolType = ToolType.Create() + ToolsPath = ProcessUtils.findLocalTool "TOOL" "MSBuild.SonarQube.Runner.exe" [ "." ] + Organization = None + Key = null + Name = null + Version = "1.0" + Settings = [] + Config = None } - /// [omit] - /// Execute the external msbuild runner of SonarQube. Parameters are given to the command line tool as required. - let internal getSonarQubeCallParams (call: SonarQubeCall) (parameters : SonarQubeParams) = - let beginInitialArguments = - Arguments.Empty - |> Arguments.appendRaw "begin" - |> Arguments.appendRawEscapedNotEmpty "/k:" parameters.Key - |> Arguments.appendRawEscapedNotEmpty "/n:" parameters.Name - |> Arguments.appendRawEscapedNotEmpty "/v:" parameters.Version - |> Arguments.appendRawEscapedOption "/o:" parameters.Organization - |> Arguments.appendRawEscapedOption "/s:" parameters.Config +/// [omit] +/// Execute the external msbuild runner of SonarQube. Parameters are given to the command line tool as required. +let internal getSonarQubeCallParams (call: SonarQubeCall) (parameters: SonarQubeParams) = + let beginInitialArguments = + Arguments.Empty + |> Arguments.appendRaw "begin" + |> Arguments.appendRawEscapedNotEmpty "/k:" parameters.Key + |> Arguments.appendRawEscapedNotEmpty "/n:" parameters.Name + |> Arguments.appendRawEscapedNotEmpty "/v:" parameters.Version + |> Arguments.appendRawEscapedOption "/o:" parameters.Organization + |> Arguments.appendRawEscapedOption "/s:" parameters.Config - let beginCall = - parameters.Settings - |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) beginInitialArguments + let beginCall = + parameters.Settings + |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) beginInitialArguments - let endInitialArguments = - Arguments.Empty - |> Arguments.appendRaw "end" - |> Arguments.appendRawEscapedOption "/s:" parameters.Config - let endCall = - parameters.Settings - |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) endInitialArguments + let endInitialArguments = + Arguments.Empty + |> Arguments.appendRaw "end" + |> Arguments.appendRawEscapedOption "/s:" parameters.Config - match call with - | Begin -> beginCall - | End -> endCall + let endCall = + parameters.Settings + |> List.fold (fun arguments x -> arguments |> Arguments.appendRawEscaped "/d:" x) endInitialArguments - let private sonarQubeCall (call: SonarQubeCall) (parameters : SonarQubeParams) = - let args = getSonarQubeCallParams call parameters - CreateProcess.fromCommand(RawCommand(parameters.ToolsPath, args)) - |> CreateProcess.withToolType (parameters.ToolType.WithDefaultToolCommandName "sonarscanner") - |> CreateProcess.withWorkingDirectory parameters.WorkingDirectory - |> CreateProcess.ensureExitCode - |> Proc.run - |> ignore + match call with + | Begin -> beginCall + | End -> endCall - /// This task can be used to run the begin command of [Sonar Qube](http://sonarqube.org/) on a project. - /// ## Parameters - /// - /// - `setParams` - Function used to overwrite the SonarQube default parameters. - /// - /// ## Sample - /// - /// open Fake.Testing - /// - /// SonarQube.start (fun p -> - /// {p with - /// Key = "MyProject" - /// Name = "MainTool" - /// Version = "1.0 }) - /// - let start setParams = - use __ = Trace.traceTask "SonarQube" "Begin" - let parameters = setParams SonarQubeDefaults - sonarQubeCall Begin parameters - __.MarkSuccess() +let private sonarQubeCall (call: SonarQubeCall) (parameters: SonarQubeParams) = + let args = getSonarQubeCallParams call parameters + CreateProcess.fromCommand (RawCommand(parameters.ToolsPath, args)) + |> CreateProcess.withToolType (parameters.ToolType.WithDefaultToolCommandName "sonarscanner") + |> CreateProcess.withWorkingDirectory parameters.WorkingDirectory + |> CreateProcess.ensureExitCode + |> Proc.run + |> ignore - /// This task can be used to run the end command of [Sonar Qube](http://sonarqube.org/) on a project. - /// ## Parameters - /// - /// - `setParams` - Function used to overwrite the SonarQube default parameters. - /// - /// ## Sample - /// - /// open Fake.Testing - /// - /// SonarQube.finish None - /// - /// SonarQube.finish (Some (fun p -> - /// { p with - /// Settings = ["sonar.login=login"; "sonar.password=password"] })) - /// - let finish setParams = - use __ = Trace.traceTask "SonarQube" "End" - let parameters = match setParams with - | Some setParams -> setParams SonarQubeDefaults - | None -> (fun p -> { p with Settings = [] }) SonarQubeDefaults - sonarQubeCall End parameters - __.MarkSuccess() +/// This task can be used to run the begin command of [Sonar Qube](http://sonarqube.org/) on a project. +/// ## Parameters +/// +/// - `setParams` - Function used to overwrite the SonarQube default parameters. +/// +/// ## Sample +/// +/// open Fake.Testing +/// +/// SonarQube.start (fun p -> +/// { p with +/// Key = "MyProject" +/// Name = "MainTool" +/// Version = "1.0 }) +/// +let start setParams = + use __ = Trace.traceTask "SonarQube" "Begin" + let parameters = setParams SonarQubeDefaults + sonarQubeCall Begin parameters + __.MarkSuccess() - /// This task can be used to execute some code between - /// the `begin` and `end` [Sonar Qube](http://sonarqube.org/) on a project. - /// - /// ## Parameters - /// - /// - `setParams` - Function used to overwrite the SonarQube default parameters. - /// - `doBetween` - Function executed between `begin` and `end` [Sonar Qube](http://sonarqube.org/) commands. - /// - /// ## Sample - /// - /// ``` - /// open Fake.Testing - /// - /// Target.create "StaticAnalysis" (fun _ -> - /// let setParams p = - /// { p with Key = "ProjectKey" - /// Name = "ProjectName" - /// Version = "3.2.1" - /// Settings = - /// [ "sonar.host.url=" + SONAR_HOST_URL - /// "sonar.login=" + SONAR_TOKEN - /// "sonar.cs.opencover.reportsPaths=opencovercoverage.xml" - /// ] - /// // choose what you need - /// // https://fake.build/dotnet-cli.html#SDK-tools-local-global-clireference - /// ToolType = ToolType.CreateGlobalTool() // Start as dotnet global tool (`sonarscanner`) - /// ToolType = ToolType.CreateLocalTool() // Start as dotnet local tool (`dotnet sonarscanner`) - /// } - /// SonarQube.scan setParams (fun () -> - /// DotNet.build id - /// DotNet.test id - /// ) - /// ) - /// ``` - let scan setParams doBetween = - start setParams - doBetween() - finish (Some setParams) +/// This task can be used to run the end command of [Sonar Qube](http://sonarqube.org/) on a project. +/// ## Parameters +/// +/// - `setParams` - Function used to overwrite the SonarQube default parameters. +/// +/// ## Sample +/// +/// open Fake.Testing +/// +/// SonarQube.finish None +/// +/// SonarQube.finish (Some (fun p -> +/// { p with +/// Settings = ["sonar.login=login"; "sonar.password=password"] })) +/// +let finish setParams = + use __ = Trace.traceTask "SonarQube" "End" + + let parameters = + match setParams with + | Some setParams -> setParams SonarQubeDefaults + | None -> (fun p -> { p with Settings = [] }) SonarQubeDefaults + sonarQubeCall End parameters + __.MarkSuccess() + +/// This task can be used to execute some code between +/// the `begin` and `end` [Sonar Qube](http://sonarqube.org/) on a project. +/// +/// ## Parameters +/// +/// - `setParams` - Function used to overwrite the SonarQube default parameters. +/// - `doBetween` - Function executed between `begin` and `end` [Sonar Qube](http://sonarqube.org/) commands. +/// +/// ## Sample +/// +/// ``` +/// open Fake.Testing +/// +/// Target.create "StaticAnalysis" (fun _ -> +/// let setParams p = +/// { p with Key = "ProjectKey" +/// Name = "ProjectName" +/// Version = "3.2.1" +/// Settings = +/// [ "sonar.host.url=" + SONAR_HOST_URL +/// "sonar.login=" + SONAR_TOKEN +/// "sonar.cs.opencover.reportsPaths=opencovercoverage.xml" +/// ] +/// // choose what you need +/// // https://fake.build/dotnet-cli.html#SDK-tools-local-global-clireference +/// ToolType = ToolType.CreateGlobalTool() // Start as dotnet global tool (`sonarscanner`) +/// ToolType = ToolType.CreateLocalTool() // Start as dotnet local tool (`dotnet sonarscanner`) +/// } +/// SonarQube.scan setParams (fun () -> +/// DotNet.build id +/// DotNet.test id +/// ) +/// ) +/// ``` +let scan setParams doBetween = + start setParams + doBetween() + finish (Some setParams)