Skip to content

Commit

Permalink
Merge upstream/main into aligned-anonymous-arg
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh DeGraw committed Jun 12, 2023
2 parents 3615dae + 4f2f9c1 commit eeb8f27
Show file tree
Hide file tree
Showing 37 changed files with 878 additions and 595 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ jobs:
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./output
publish_dir: ./output
- name: "Publish"
if: matrix.os == 'windows-latest' && github.ref == 'refs/heads/main'
env:
NUGET_KEY: ${{ secrets.NUGET_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: dotnet fsi build.fsx -p Release
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ Some common use cases include:
<!-- https://www.gresearch.co.uk/blog/article/improve-nuget-restores-with-static-graph-evaluation/ -->
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
<ServerGarbageCollection>true</ServerGarbageCollection>
<OtherFlags>$(OtherFlags) --test:GraphBasedChecking</OtherFlags>
<OtherFlags>$(OtherFlags) --test:GraphBasedChecking --test:ParallelOptimization --test:ParallelIlxGen</OtherFlags>
</PropertyGroup>

<!-- Versions -->
<PropertyGroup>
<FCSCommitHash>ba6647ebf5b94823c4d6fafd1e7d5f806d915ee0</FCSCommitHash>
<FCSCommitHash>5b74995780a0e9d24a5db025e68b31e6d910f71f</FCSCommitHash>
<StreamJsonRpcVersion>2.8.28</StreamJsonRpcVersion>
<FSharpCoreVersion>6.0.1</FSharpCoreVersion>
</PropertyGroup>
Expand Down
185 changes: 172 additions & 13 deletions build.fsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#r "nuget: Fun.Build, 0.3.8"
#r "nuget: CliWrap, 3.5.0"
#r "nuget: FSharp.Data, 5.0.2"
#r "nuget: Ionide.KeepAChangelog, 0.1.8"
#r "nuget: Humanizer.Core, 2.14.1"

open System
open System.IO
open Fun.Build
open CliWrap
open CliWrap.Buffered
open FSharp.Data
open System.Xml.Linq
open System.Xml.XPath
open Ionide.KeepAChangelog
open Ionide.KeepAChangelog.Domain
open SemVersion
open Humanizer

let (</>) a b = Path.Combine(a, b)

Expand Down Expand Up @@ -39,7 +46,7 @@ let semanticVersioning =

let pushPackage nupkg =
async {
let key = System.Environment.GetEnvironmentVariable("NUGET_KEY")
let key = Environment.GetEnvironmentVariable("NUGET_KEY")
let! result =
Cli
.Wrap("dotnet")
Expand Down Expand Up @@ -77,18 +84,6 @@ pipeline "Build" {
run
$"dotnet fsdocs build --clean --properties Configuration=Release --fscoptions \" -r:{semanticVersioning}\" --eval --strict --nonpublic"
}
stage "Push" {
whenCmdArg "--push"
run (fun _ ->
async {
let! exitCodes =
Directory.EnumerateFiles("bin", "*.nupkg", SearchOption.TopDirectoryOnly)
|> Seq.filter (fun nupkg -> not (nupkg.Contains("Fantomas.Client")))
|> Seq.map pushPackage
|> Async.Sequential
return Seq.max exitCodes
})
}
runIfOnlySpecified false
}

Expand Down Expand Up @@ -313,3 +308,167 @@ pipeline "Init" {
}
runIfOnlySpecified true
}

type GithubRelease =
{ Version: string
Title: string
Date: DateTime
PublishedDate: string option
Draft: string }

let mkGithubRelease (v: SemanticVersion, d: DateTime, cd: ChangelogData option) =
match cd with
| None -> failwith "Each Fantomas release is expected to have at least one section."
| Some cd ->
let version = $"{v.Major}.{v.Minor}.{v.Patch}"
let title =
let month = d.ToString("MMMM")
let day = d.Day.Ordinalize()
$"{month} {day} Release"

let prefixedVersion = $"v{version}"
let publishDate =
let cmdResult =
Cli
.Wrap("gh")
.WithArguments($"release view {prefixedVersion} --json publishedAt -t \"{{{{.publishedAt}}}}\"")
.WithValidation(CommandResultValidation.None)
.ExecuteBufferedAsync()
.Task.Result
if cmdResult.ExitCode <> 0 then
None
else
let output = cmdResult.StandardOutput.Trim()
let lastIdx = output.LastIndexOf("Z")
Some(output.Substring(0, lastIdx))

let sections =
[ "Added", cd.Added
"Changed", cd.Changed
"Fixed", cd.Fixed
"Deprecated", cd.Deprecated
"Removed", cd.Removed
"Security", cd.Security
yield! (Map.toList cd.Custom) ]
|> List.choose (fun (header, lines) ->
if lines.IsEmpty then
None
else
lines
|> List.map (fun line -> line.TrimStart())
|> String.concat "\n"
|> sprintf "### %s\n%s" header
|> Some)
|> String.concat "\n\n"

let draft =
$"""# {version}
{sections}"""

{ Version = version
Title = title
Date = d
PublishedDate = publishDate
Draft = draft }

let getReleaseNotes currentRelease (lastRelease: GithubRelease) =
let date = lastRelease.PublishedDate.Value
let authorMsg =
let authors =
Cli
.Wrap("gh")
.WithArguments(
$"pr list -S \"state:closed base:main closed:>{date} -author:app/robot\" --json author --jq \".[].author.login\""
)
.ExecuteBufferedAsync()
.Task.Result.StandardOutput.Split([| '\n' |], StringSplitOptions.RemoveEmptyEntries)
|> Array.distinct
|> Array.sort

if authors.Length = 1 then
$"Special thanks to %s{authors.[0]}!"
else
let lastAuthor = Array.last authors
let otherAuthors =
if authors.Length = 2 then
$"@{authors.[0]}"
else
authors
|> Array.take (authors.Length - 1)
|> Array.map (sprintf "@%s")
|> String.concat ", "
$"Special thanks to %s{otherAuthors} and @%s{lastAuthor}!"

$"""{currentRelease.Draft}
{authorMsg}
[https://www.nuget.org/packages/fantomas/{currentRelease.Version}](https://www.nuget.org/packages/fantomas/{currentRelease.Version})
"""

let getCurrentAndLastReleaseFromChangelog () =
let changelog = FileInfo(__SOURCE_DIRECTORY__ </> "CHANGELOG.md")
let changeLogResult =
match Parser.parseChangeLog changelog with
| Error error -> failwithf "%A" error
| Ok result -> result

let lastReleases =
changeLogResult.Releases
|> List.filter (fun (v, _, _) -> String.IsNullOrEmpty v.Prerelease)
|> List.sortByDescending (fun (_, d, _) -> d)
|> List.take 2

match lastReleases with
| [ current; last ] -> mkGithubRelease current, mkGithubRelease last
| _ -> failwith "Could not find the current and last release from CHANGELOG.md"

pipeline "Release" {
workingDir __SOURCE_DIRECTORY__
stage "Release" {
run (fun _ ->
async {
let currentRelease, lastRelease = getCurrentAndLastReleaseFromChangelog ()

if Option.isSome currentRelease.PublishedDate then
return 0
else
// Push packages to NuGet
let nugetPackages =
Directory.EnumerateFiles("bin", "*.nupkg", SearchOption.TopDirectoryOnly)
|> Seq.filter (fun nupkg -> not (nupkg.Contains("Fantomas.Client")))
|> Seq.toArray

let! nugetExitCodes = nugetPackages |> Array.map pushPackage |> Async.Sequential

let notes = getReleaseNotes currentRelease lastRelease
let noteFile = Path.GetTempFileName()
File.WriteAllText(noteFile, notes)
let files = nugetPackages |> String.concat " "

// We create a draft release for minor and majors. Those that requires a manual publish.
// This is to allow us to add additional release notes when it makes sense.
let! draftResult =
let isDraft =
let isRevision = lastRelease.Version.Split('.') |> Array.last |> int |> (<>) 0
if isRevision then String.Empty else "--draft"

Cli
.Wrap("gh")
.WithArguments(
$"release create v{currentRelease.Version} {files} {isDraft} --title \"{currentRelease.Title}\" --notes-file \"{noteFile}\""
)
.WithValidation(CommandResultValidation.None)
.ExecuteAsync()
.Task
|> Async.AwaitTask

if File.Exists noteFile then
File.Delete(noteFile)

return Seq.max [| yield! nugetExitCodes; yield draftResult.ExitCode |]
})
}
runIfOnlySpecified true
}
Binary file added docs/images/users/fshttp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ <h2 class="mb-4 text-primary" id="who-uses-fantomas">Who uses Fantomas?</h2>
<a class="tile" href="https://github.com/fsprojects/fake" data-bs-toggle="tooltip" title="fsprojects/FAKE">
<img src="./images/users/fake.png" alt="FAKE logo">
</a>
<a class="tile" href="https://github.com/fsprojects/FsHttp" data-bs-toggle="tooltip" title="fsprojects/FsHttp">
<img src="./images/users/fshttp.png" alt="FsHttp logo">
</a>
<a class="tile" href="#get-started" id="your-logo-here">
<p>Your logo here?</p>
</a>
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "7.0.400-preview.23218.20",
"version": "7.0.400-preview.23272.51",
"rollForward": "latestPatch"
}
}
11 changes: 10 additions & 1 deletion src/Fantomas.Client.Tests/EndToEndTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@ type EndToEndTests() =

// This sdk version must match the version used in this repository.
// It will be the version which the CI/CD pipeline has access to.
do! dotnet "new globaljson --sdk-version 7.0.202 --roll-forward latestPatch"
let! dotnetVersionResult =
Cli
.Wrap("dotnet")
.WithWorkingDirectory(__SOURCE_DIRECTORY__)
.WithArguments("--version")
.ExecuteBufferedAsync()
.Task

let dotnetVersion = dotnetVersionResult.StandardOutput.Trim()
do! dotnet $"new globaljson --sdk-version %s{dotnetVersion} --roll-forward latestPatch"
do! dotnet "new tool-manifest"

do!
Expand Down
25 changes: 0 additions & 25 deletions src/Fantomas.Core.Tests/ClassTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1041,31 +1041,6 @@ type C() =
member _.Run() = 1
"""

[<Test>]
let ``explicit class/end with members, idempotent`` () =
formatSourceString
false
"""
type C() =
class
member x.P = 1
end
member _.Run() = 1
"""
config
|> prepend newline
|> should
equal
"""
type C() =
class
member x.P = 1
end
member _.Run() = 1
"""

[<Test>]
let ``static member with get unit should be formatted the same as without, 1913`` () =
formatSourceString
Expand Down
48 changes: 45 additions & 3 deletions src/Fantomas.Core.Tests/CommentTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2080,8 +2080,8 @@ type CreateFSharpManifestResourceName public () =
(
fileName: string,
linkFileName: string,
rootNamespace: string, // may be null
dependentUponFileName: string, // may be null
rootNamespace: string, // may be null
dependentUponFileName: string, // may be null
binaryStream: Stream // may be null
) : string =
()
Expand Down Expand Up @@ -2570,7 +2570,7 @@ type MyType2 =
type MyType =
member _.MyMethod
(
[<MyAttribute>] inputA: string, // my comment 1
[<MyAttribute>] inputA: string, // my comment 1
[<MyAttribute>] inputB: string // my comment 2
) =
inputA
Expand Down Expand Up @@ -2612,3 +2612,45 @@ let (* this comment disappears after formatting *) a = []
"""
let (* this comment disappears after formatting *) a = []
"""

[<Test>]
let ``trivia after infix operator is not restored correctly, 2887`` () =
formatSourceString
false
"""
let EnableHeapTerminationOnCorruption() =
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version.Major >= 6 && // If OS is Vista or higher
Environment.Version.Major < 3) then // and CLR not 3.0 or higher
let HeapEnableTerminationOnCorruption = 1u : uint32
if not (HeapSetInformation(GetProcessHeap(), HeapEnableTerminationOnCorruption, UIntPtr.Zero, UIntPtr.Zero)) then
raise (System.Security.SecurityException(
"Unable to enable unmanaged process execution option TerminationOnCorruption. " +
"HeapSetInformation() returned FALSE; LastError = 0x" +
GetLastError().ToString("X").PadLeft(8, '0') + "."))
"""
config
|> prepend newline
|> should
equal
"""
let EnableHeapTerminationOnCorruption () =
if
(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
&& Environment.OSVersion.Version.Major >= 6
&& // If OS is Vista or higher
Environment.Version.Major < 3)
then // and CLR not 3.0 or higher
let HeapEnableTerminationOnCorruption = 1u: uint32

if
not (HeapSetInformation(GetProcessHeap(), HeapEnableTerminationOnCorruption, UIntPtr.Zero, UIntPtr.Zero))
then
raise (
System.Security.SecurityException(
"Unable to enable unmanaged process execution option TerminationOnCorruption. "
+ "HeapSetInformation() returned FALSE; LastError = 0x"
+ GetLastError().ToString("X").PadLeft(8, '0')
+ "."
)
)
"""
Loading

0 comments on commit eeb8f27

Please sign in to comment.