Skip to content

Commit

Permalink
initial analyzers module
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmy Byrd committed Mar 24, 2020
1 parent 27407a8 commit fb881a2
Show file tree
Hide file tree
Showing 4 changed files with 403 additions and 69 deletions.
6 changes: 6 additions & 0 deletions Content/Library/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
"commands": [
"fcswatch"
]
},
"fsharp-analyzers": {
"version": "0.4.0",
"commands": [
"fsharp-analyzers"
]
}
}
}
174 changes: 105 additions & 69 deletions Content/Library/build.fsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Argu
#load ".fake/build.fsx/intellisense.fsx"
#load "docsTool/CLI.fs"
#if !FAKE
Expand Down Expand Up @@ -134,70 +135,68 @@ let rec retryIfInCI times fn =
let isReleaseBranchCheck () =
if Git.Information.getBranchName "" <> releaseBranch then failwithf "Not on %s. If you want to release please switch to this branch." releaseBranch

let isEmptyChange = function
| Changelog.Change.Added s
| Changelog.Change.Changed s
| Changelog.Change.Deprecated s
| Changelog.Change.Fixed s
| Changelog.Change.Removed s
| Changelog.Change.Security s
| Changelog.Change.Custom (_, s) ->
String.IsNullOrWhiteSpace s.CleanedText

let isChangelogEmpty () =
let isEmpty =
(latestEntry.Changes |> Seq.forall isEmptyChange)
|| latestEntry.Changes |> Seq.isEmpty
if isEmpty then failwith "No changes in CHANGELOG. Please add your changes under a heading specified in https://keepachangelog.com/"
module Changelog =

let isEmptyChange = function
| Changelog.Change.Added s
| Changelog.Change.Changed s
| Changelog.Change.Deprecated s
| Changelog.Change.Fixed s
| Changelog.Change.Removed s
| Changelog.Change.Security s
| Changelog.Change.Custom (_, s) ->
String.IsNullOrWhiteSpace s.CleanedText

let isChangelogEmpty () =
let isEmpty =
(latestEntry.Changes |> Seq.forall isEmptyChange)
|| latestEntry.Changes |> Seq.isEmpty
if isEmpty then failwith "No changes in CHANGELOG. Please add your changes under a heading specified in https://keepachangelog.com/"

let mkLinkReference (newVersion : SemVerInfo) (changelog : Changelog.Changelog) =
if changelog.Entries |> List.isEmpty then
// No actual changelog entries yet: link reference will just point to the Git tag
sprintf "[%s]: %s/releases/tag/%s" newVersion.AsString gitHubRepoUrl (tagFromVersionNumber newVersion.AsString)
else
let versionTuple version = (version.Major, version.Minor, version.Patch)
// Changelog entries come already sorted, most-recent first, by the Changelog module
let prevEntry = changelog.Entries |> List.skipWhile (fun entry -> entry.SemVer.PreRelease.IsSome && versionTuple entry.SemVer = versionTuple newVersion) |> List.tryHead
let linkTarget =
match prevEntry with
| Some entry -> sprintf "%s/compare/%s...%s" gitHubRepoUrl (tagFromVersionNumber entry.SemVer.AsString) (tagFromVersionNumber newVersion.AsString)
| None -> sprintf "%s/releases/tag/%s" gitHubRepoUrl (tagFromVersionNumber newVersion.AsString)
sprintf "[%s]: %s" newVersion.AsString linkTarget

let mkReleaseNotes (linkReference : string) (latestEntry : Changelog.ChangelogEntry) =
if String.isNullOrEmpty linkReference then latestEntry.ToString()
else
// Add link reference target to description before building release notes, since in main changelog file it's at the bottom of the file
let description =
match latestEntry.Description with
| None -> linkReference
| Some desc when desc.Contains(linkReference) -> desc
| Some desc -> sprintf "%s\n\n%s" (desc.Trim()) linkReference
{ latestEntry with Description = Some description }.ToString()

let getVersionNumber envVarName ctx =
let args = ctx.Context.Arguments
let verArg =
args
|> List.tryHead
|> Option.defaultWith (fun () -> Environment.environVarOrDefault envVarName "")
if SemVer.isValid verArg then verArg
elif verArg.StartsWith("v") && SemVer.isValid verArg.[1..] then
let target = ctx.Context.FinalTarget
Trace.traceImportantfn "Please specify a version number without leading 'v' next time, e.g. \"./build.sh %s %s\" rather than \"./build.sh %s %s\"" target verArg.[1..] target verArg
verArg.[1..]
elif String.isNullOrEmpty verArg then
let target = ctx.Context.FinalTarget
Trace.traceErrorfn "Please specify a version number, either at the command line (\"./build.sh %s 1.0.0\") or in the %s environment variable" target envVarName
failwith "No version number found"
else
Trace.traceErrorfn "Please specify a valid version number: %A could not be recognized as a version number" verArg
failwith "Invalid version number"

let allReleaseChecks () =
isReleaseBranchCheck ()
isChangelogEmpty ()


let mkLinkReference (newVersion : SemVerInfo) (changelog : Changelog.Changelog) =
if changelog.Entries |> List.isEmpty then
// No actual changelog entries yet: link reference will just point to the Git tag
sprintf "[%s]: %s/releases/tag/%s" newVersion.AsString gitHubRepoUrl (tagFromVersionNumber newVersion.AsString)
else
let versionTuple version = (version.Major, version.Minor, version.Patch)
// Changelog entries come already sorted, most-recent first, by the Changelog module
let prevEntry = changelog.Entries |> List.skipWhile (fun entry -> entry.SemVer.PreRelease.IsSome && versionTuple entry.SemVer = versionTuple newVersion) |> List.tryHead
let linkTarget =
match prevEntry with
| Some entry -> sprintf "%s/compare/%s...%s" gitHubRepoUrl (tagFromVersionNumber entry.SemVer.AsString) (tagFromVersionNumber newVersion.AsString)
| None -> sprintf "%s/releases/tag/%s" gitHubRepoUrl (tagFromVersionNumber newVersion.AsString)
sprintf "[%s]: %s" newVersion.AsString linkTarget

let mkReleaseNotes (linkReference : string) (latestEntry : Changelog.ChangelogEntry) =
if String.isNullOrEmpty linkReference then latestEntry.ToString()
else
// Add link reference target to description before building release notes, since in main changelog file it's at the bottom of the file
let description =
match latestEntry.Description with
| None -> linkReference
| Some desc when desc.Contains(linkReference) -> desc
| Some desc -> sprintf "%s\n\n%s" (desc.Trim()) linkReference
{ latestEntry with Description = Some description }.ToString()

let getVersionNumber envVarName ctx =
let args = ctx.Context.Arguments
let verArg =
args
|> List.tryHead
|> Option.defaultWith (fun () -> Environment.environVarOrDefault envVarName "")
if SemVer.isValid verArg then verArg
elif verArg.StartsWith("v") && SemVer.isValid verArg.[1..] then
let target = ctx.Context.FinalTarget
Trace.traceImportantfn "Please specify a version number without leading 'v' next time, e.g. \"./build.sh %s %s\" rather than \"./build.sh %s %s\"" target verArg.[1..] target verArg
verArg.[1..]
elif String.isNullOrEmpty verArg then
let target = ctx.Context.FinalTarget
Trace.traceErrorfn "Please specify a version number, either at the command line (\"./build.sh %s 1.0.0\") or in the %s environment variable" target envVarName
failwith "No version number found"
else
Trace.traceErrorfn "Please specify a valid version number: %A could not be recognized as a version number" verArg
failwith "Invalid version number"

module dotnet =
let watch cmdParam program args =
Expand All @@ -219,6 +218,21 @@ module dotnet =
let fcswatch optionConfig args =
tool optionConfig "fcswatch" args

let fsharpAnalyzer optionConfig args =
tool optionConfig "fsharp-analyzers" args

module FSharpAnalyzers =
type Arguments =
| Project of string
| Analyzers_Path of string
| Fail_On_Warnings of string list
| Ignore_Files of string list
| Verbose
with
interface IArgParserTemplate with
member s.Usage = ""


open DocsTool.CLIArgs
module DocsTool =
open Argu
Expand Down Expand Up @@ -258,10 +272,15 @@ module DocsTool =
) "run" (sprintf "-- watch %s" (watchCLI()))
|> failOnBadExitAndPrint

let allReleaseChecks () =
isReleaseBranchCheck ()
Changelog.isChangelogEmpty ()

//-----------------------------------------------------------------------------
// Target Implementations
//-----------------------------------------------------------------------------


let clean _ =
["bin"; "temp" ; distDir; coverageReportDir]
|> Shell.cleanDirs
Expand Down Expand Up @@ -298,7 +317,7 @@ let updateChangelog ctx =
match changelog.Unreleased with
| None -> None, []
| Some u -> u.Description, u.Changes
let verStr = ctx |> getVersionNumber "RELEASE_VERSION"
let verStr = ctx |> Changelog.getVersionNumber "RELEASE_VERSION"
let newVersion = SemVer.parse verStr
changelog.Entries
|> List.tryFind (fun entry -> entry.SemVer = newVersion)
Expand All @@ -314,9 +333,9 @@ let updateChangelog ctx =
)
let versionTuple version = (version.Major, version.Minor, version.Patch)
let prereleaseEntries = changelog.Entries |> List.filter (fun entry -> entry.SemVer.PreRelease.IsSome && versionTuple entry.SemVer = versionTuple newVersion)
let prereleaseChanges = prereleaseEntries |> List.collect (fun entry -> entry.Changes |> List.filter (not << isEmptyChange))
let prereleaseChanges = prereleaseEntries |> List.collect (fun entry -> entry.Changes |> List.filter (not << Changelog.isEmptyChange))
let assemblyVersion, nugetVersion = Changelog.parseVersions newVersion.AsString
linkReferenceForLatestEntry <- mkLinkReference newVersion changelog
linkReferenceForLatestEntry <- Changelog.mkLinkReference newVersion changelog
let newEntry = Changelog.ChangelogEntry.New(assemblyVersion.Value, nugetVersion.Value, Some System.DateTime.Today, description, unreleasedChanges @ prereleaseChanges, false)
let newChangelog = Changelog.Changelog.New(changelog.Header, changelog.Description, None, newEntry :: changelog.Entries)
latestEntry <- newEntry
Expand All @@ -330,7 +349,7 @@ let updateChangelog ctx =
|> Changelog.save changelogFilename

// Now update the link references at the end of the file
linkReferenceForLatestEntry <- mkLinkReference newVersion changelog
linkReferenceForLatestEntry <- Changelog.mkLinkReference newVersion changelog
let linkReferenceForUnreleased = sprintf "[Unreleased]: %s/compare/%s...%s" gitHubRepoUrl (tagFromVersionNumber newVersion.AsString) "HEAD"
let tailLines = File.read changelogFilename |> List.ofSeq |> List.rev

Expand Down Expand Up @@ -382,6 +401,21 @@ let dotnetBuild ctx =

}) sln

let fsharpAnalyzers ctx =
let argParser = ArgumentParser.Create<FSharpAnalyzers.Arguments>(programName = "fsharp-analyzers")
!! srcGlob
|> Seq.iter(fun proj ->
let args =
[
FSharpAnalyzers.Arguments.Project proj
FSharpAnalyzers.Arguments.Fail_On_Warnings [
"OV001"
]
]
|> argParser.PrintCommandLineArgumentsFlat
dotnet.fsharpAnalyzer id args
)

let dotnetTest ctx =
let excludeCoverage =
!! testsGlob
Expand Down Expand Up @@ -487,7 +521,7 @@ let generateAssemblyInfo _ =

let dotnetPack ctx =
// Get release notes with properly-linked version number
let releaseNotes = latestEntry |> mkReleaseNotes linkReferenceForLatestEntry
let releaseNotes = latestEntry |> Changelog.mkReleaseNotes linkReferenceForLatestEntry
let args =
[
sprintf "/p:PackageVersion=%s" latestEntry.NuGetVersion
Expand Down Expand Up @@ -548,7 +582,7 @@ let githubRelease _ =

let files = !! distGlob
// Get release notes with properly-linked version number
let releaseNotes = latestEntry |> mkReleaseNotes linkReferenceForLatestEntry
let releaseNotes = latestEntry |> Changelog.mkReleaseNotes linkReferenceForLatestEntry

GitHub.createClientWithToken token
|> GitHub.draftNewRelease gitOwner gitRepoName (tagFromVersionNumber latestEntry.NuGetVersion) (latestEntry.SemVer.PreRelease <> None) (releaseNotes |> Seq.singleton)
Expand Down Expand Up @@ -614,6 +648,7 @@ Target.create "UpdateChangelog" updateChangelog
Target.createBuildFailure "RevertChangelog" revertChangelog // Do NOT put this in the dependency chain
Target.createFinal "DeleteChangelogBackupFile" deleteChangelogBackupFile // Do NOT put this in the dependency chain
Target.create "DotnetBuild" dotnetBuild
Target.create "FSharpAnalyzers" fsharpAnalyzers
Target.create "DotnetTest" dotnetTest
Target.create "GenerateCoverageReport" generateCoverageReport
Target.create "WatchTests" watchTests
Expand Down Expand Up @@ -661,6 +696,7 @@ Target.create "ReleaseDocs" releaseDocs

"DotnetRestore"
==> "DotnetBuild"
==> "FSharpAnalyzers"
==> "DotnetTest"
=?> ("GenerateCoverageReport", not disableCodeCoverage)
==> "DotnetPack"
Expand Down
5 changes: 5 additions & 0 deletions Content/Library/paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ group Docs
nuget FSharp.Literate
nuget Fable.React
nuget Dotnet.ProjInfo.Workspace.FCS

group Analyzers
source https://www.nuget.org/api/v2
source https://api.nuget.org/v3/index.json
nuget FSharp.Analyzers.Sample
Loading

0 comments on commit fb881a2

Please sign in to comment.