Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 38 additions & 28 deletions src/pkgchk-cli/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
let trace traceLogging =
if traceLogging then Console.grey >> console else ignore

let renderTables (values: seq<Spectre.Console.Table>) =
values |> Seq.iter Spectre.Console.AnsiConsole.Write
let returnError error =
error |> Console.error |> console
ReturnCodes.sysError

let runProc logging proc =
try
Expand All @@ -113,10 +114,6 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
|> Io.createProcess
|> runRestoreProcParse (runProc logging)

let returnError error =
error |> Console.error |> console
ReturnCodes.sysError

let getErrors procResults =
procResults
|> Seq.map (function
Expand All @@ -125,6 +122,9 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
|> Seq.filter String.isNotEmpty
|> Seq.distinct

let renderTables (values: seq<Spectre.Console.Table>) =
values |> Seq.iter Spectre.Console.AnsiConsole.Write

let liftHits procResults =
procResults
|> Seq.collect (function
Expand All @@ -145,6 +145,22 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =

let getHits = liftHits >> sortHits >> List.ofSeq

let rec genComment trace (settings: PackageCheckCommandSettings, hits, errorHits, hitCounts) attempt =
let markdown =
(hits, errorHits, hitCounts, settings.SeverityLevels)
|> Markdown.generate
|> String.joinLines

if markdown.Length < Github.maxCommentSize then
GithubComment.create settings.GithubSummaryTitle markdown
else
trace $"Shrinking Github output as too large (attempt #{attempt + 1})..."

if attempt >= 1 then
GithubComment.create settings.GithubSummaryTitle "_The report's too big for Github - Please check logs_"
else
genComment trace (settings, [], errorHits, hitCounts) (attempt + 1)

let returnCode (hits: ScaHit list) =
match hits with
| [] -> ReturnCodes.validationOk
Expand All @@ -153,22 +169,15 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
let reportFile outDir =
outDir |> Io.toFullPath |> Io.combine "pkgchk.md" |> Io.normalise

override _.Execute(context, settings) =
let trace = trace settings.TraceLogging

settings.SeverityLevels <- settings.SeverityLevels |> Array.filter String.isNotEmpty

if settings.NoBanner |> not then
nuget |> App.banner |> console

let validateSettings (settings: PackageCheckCommandSettings) =
if String.isNotEmpty settings.GithubPrId then
if String.isEmpty settings.GithubToken then
failwith "Missing Github token."

if String.isEmpty settings.GithubRepo then
failwith "Missing Github repository. Use the form <owner>/<name>."

let repo = GithubRepo.repo settings.GithubRepo
let repo = Github.repo settings.GithubRepo

if repo |> fst |> String.isEmpty then
failwith "The repository owner is missing. Use the form <owner>/<name>."
Expand All @@ -179,6 +188,16 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
if String.isInt settings.GithubPrId |> not then
failwith "The PR ID must be an integer."

override _.Execute(context, settings) =
let trace = trace settings.TraceLogging

settings.SeverityLevels <- settings.SeverityLevels |> Array.filter String.isNotEmpty

if settings.NoBanner |> not then
nuget |> App.banner |> console

validateSettings settings

match runRestore settings trace with
| Choice2Of2 error -> error |> returnError
| _ ->
Expand Down Expand Up @@ -238,24 +257,15 @@ type PackageCheckCommand(nuget: Tk.Nuget.INugetClient) =
&& String.isNotEmpty settings.GithubRepo
&& String.isNotEmpty settings.GithubPrId
then
trace "Building Github reports..."
let prId = String.toInt settings.GithubPrId
let repo = GithubRepo.repo settings.GithubRepo

let markdown =
(hits, errorHits, hitCounts, settings.SeverityLevels)
|> Markdown.generate
|> String.joinLines
let repo = Github.repo settings.GithubRepo
let client = Github.client settings.GithubToken

let comment = GithubComment.create settings.GithubSummaryTitle markdown
let comment = genComment trace (settings, hits, errorHits, hitCounts) 0

trace $"Posting {comment.title} report to Github repo {repo}..."

let client = Github.client settings.GithubToken

let _ = (comment |> Github.setPrComment client repo prId).Result

$"{comment.title} report sent to Github." |> Console.italic |> console



errorHits |> returnCode
17 changes: 12 additions & 5 deletions src/pkgchk-cli/Github.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,29 @@ type GithubComment =
{ GithubComment.title = (String.defaultValue "pkgchk summary" title)
body = body }

module GithubRepo =
module Github =

[<Literal>]
let maxCommentSize = 65536

let repo (value: string) =
match value.Split('/', StringSplitOptions.None) with
| [| owner; repo |] -> (owner, repo)
| _ -> ("", value)

module Github =

[<ExcludeFromCodeCoverage>]
let client token =
let header = new ProductHeaderValue(App.packageId)
let client = new GitHubClient(header)
client.Credentials <- new Credentials(token)
client :> IGitHubClient

let constructComment (comment: GithubComment) =
let commentTitle = $"# {comment.title}"
let commentBody = $"{commentTitle}{Environment.NewLine}{comment.body}"

(commentTitle, commentBody)

let getIssue (client: IGitHubClient) (owner: string, repo) id =
task {
try
Expand Down Expand Up @@ -58,8 +65,8 @@ module Github =

let setPrComment (client: IGitHubClient) (owner, repo) prId (comment: GithubComment) =
task {
let commentTitle = $"# {comment.title}"
let commentBody = $"{commentTitle}{Environment.NewLine}{comment.body}"

let (commentTitle, commentBody) = constructComment comment

// As there's no concret mechanism in Octokit to affinitise comments, we must use titles as the discriminator.
let! comments = getIssueComments client (owner, repo) prId
Expand Down
25 changes: 10 additions & 15 deletions src/pkgchk-cli/Markdown.fs
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,15 @@ module Markdown =
}

let formatHits (hits: seq<ScaHit>) =
let grps = hits |> Seq.groupBy (fun h -> h.projectPath) |> Seq.sortBy fst


(grps |> Seq.collect formatHitGroup)
hits
|> Seq.groupBy (fun h -> h.projectPath)
|> Seq.sortBy fst
|> Seq.collect formatHitGroup

let generate (hits, errorHits, countSummary, severities) =
let title = title errorHits

match hits with
| [] -> Seq.append title footer
| hits ->
seq {
yield! title
yield! formatHitCounts (severities, countSummary)
yield! formatHits hits
yield! footer
}
seq {
yield! title errorHits
yield! formatHitCounts (severities, countSummary)
yield! formatHits hits
yield! footer
}
18 changes: 0 additions & 18 deletions tests/pkgchk-cli.tests/GithubRepoTests.fs

This file was deleted.

13 changes: 13 additions & 0 deletions tests/pkgchk-cli.tests/GithubTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

open System
open FsUnit.Xunit
open FsCheck.Xunit
open NSubstitute
open Octokit
open Xunit
Expand Down Expand Up @@ -141,3 +142,15 @@ module GithubTests =
.Received(1)
.Update(fst repo, snd repo, comment.Id, Arg.Any<string>())
|> ignore

[<Property(Arbitrary = [| typeof<AlphaNumericString> |], Verbose = true)>]
let ``repo constructs owner/repo`` (name: string[]) =
let input = name |> pkgchk.String.join "/"

let expected =
if name.Length = 2 then
(name.[0], name.[1])
else
("", input)

input |> pkgchk.Github.repo = expected
1 change: 0 additions & 1 deletion tests/pkgchk-cli.tests/pkgchk-cli.tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<Compile Include="ConsoleTests.fs" />
<Compile Include="MarkdownTests.fs" />
<Compile Include="GithubCommentTests.fs" />
<Compile Include="GithubRepoTests.fs" />
<Compile Include="GithubTests.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
Expand Down