diff --git a/Content/Console/.fantomasignore b/Content/Console/.fantomasignore deleted file mode 100644 index d9f2aa7f..00000000 --- a/Content/Console/.fantomasignore +++ /dev/null @@ -1,2 +0,0 @@ -# Ignore AssemblyInfo files -AssemblyInfo.fs diff --git a/Content/Console/Directory.Packages.props b/Content/Console/Directory.Packages.props index 57cd3447..e623a592 100644 --- a/Content/Console/Directory.Packages.props +++ b/Content/Console/Directory.Packages.props @@ -34,7 +34,6 @@ - @@ -47,4 +46,4 @@ - \ No newline at end of file + diff --git a/Content/Console/README.md b/Content/Console/README.md index 5be67f1a..8e0f8188 100644 --- a/Content/Console/README.md +++ b/Content/Console/README.md @@ -78,7 +78,6 @@ $ ./build.sh // on unix - `GenerateCoverageReport` - Code coverage is run during `DotnetTest` and this generates a report via [ReportGenerator](https://github.com/danielpalme/ReportGenerator). - `WatchApp` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) on the application. Useful for rapid feedback loops. - `WatchTests` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) with the test projects. Useful for rapid feedback loops. -- `GenerateAssemblyInfo` - Generates [AssemblyInfo](https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.applicationservices.assemblyinfo?view=netframework-4.8) for libraries. - `CreatePackages` - Runs the packaging task from [dotnet-packaging](https://github.com/qmfrederik/dotnet-packaging). This creates applications for `win-x64`, `osx-x64` and `linux-x64` - [Runtime Identifiers](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog). - Bundles the `win-x64` application in a .zip file. - Bundles the `osx-x64` application in a .tar.gz file. diff --git a/Content/Console/build/build.fs b/Content/Console/build/build.fs index 31b29aad..4169c6f1 100644 --- a/Content/Console/build/build.fs +++ b/Content/Console/build/build.fs @@ -182,6 +182,28 @@ let failOnBadExitAndPrint (p: ProcessResult) = failwithf "failed with exitcode %d" p.ExitCode +let assemblyInfoMsBuildArgs () = + let releaseChannel = + match latestEntry.SemVer.PreRelease with + | Some pr -> pr.Name + | _ -> "release" + + let gitHash = + try + Git.Information.getCurrentSHA1 (null) + with _ -> + "" + + [ + sprintf "/p:Version=%s" latestEntry.AssemblyVersion + sprintf "/p:AssemblyVersion=%s" latestEntry.AssemblyVersion + sprintf "/p:FileVersion=%s" latestEntry.AssemblyVersion + sprintf "/p:InformationalVersion=%s" latestEntry.AssemblyVersion + sprintf "/p:AssemblyMetadataReleaseDate=%s" (latestEntry.Date.Value.ToString("o")) + sprintf "/p:AssemblyMetadataReleaseChannel=%s" releaseChannel + sprintf "/p:AssemblyMetadataGitHash=%s" gitHash + ] + let rec retryIfInCI times fn = if isCI.Value then if times > 1 then @@ -423,63 +445,6 @@ let watchTests _ = cancelEvent.Cancel <- true -let generateAssemblyInfo _ = - - let (|Fsproj|Csproj|Vbproj|) (projFileName: string) = - match projFileName with - | f when f.EndsWith("fsproj") -> Fsproj - | f when f.EndsWith("csproj") -> Csproj - | f when f.EndsWith("vbproj") -> Vbproj - | _ -> - failwith (sprintf "Project file %s not supported. Unknown project type." projFileName) - - let releaseChannel = - match latestEntry.SemVer.PreRelease with - | Some pr -> pr.Name - | _ -> "release" - - let getAssemblyInfoAttributes projectName = [ - AssemblyInfo.Title(projectName) - AssemblyInfo.Product productName - AssemblyInfo.Version latestEntry.AssemblyVersion - AssemblyInfo.Metadata("ReleaseDate", latestEntry.Date.Value.ToString("o")) - AssemblyInfo.FileVersion latestEntry.AssemblyVersion - AssemblyInfo.InformationalVersion latestEntry.AssemblyVersion - AssemblyInfo.Metadata("ReleaseChannel", releaseChannel) - AssemblyInfo.Metadata("GitHash", Git.Information.getCurrentSHA1 (null)) - ] - - let getProjectDetails (projectPath: string) = - let projectName = IO.Path.GetFileNameWithoutExtension(projectPath) - - (projectPath, - projectName, - IO.Path.GetDirectoryName(projectPath), - (getAssemblyInfoAttributes projectName)) - - !!srcGlob - |> Seq.map getProjectDetails - |> Seq.iter (fun (projFileName, _, folderName, attributes) -> - match projFileName with - | Fsproj -> - AssemblyInfoFile.createFSharp - (folderName - @@ "AssemblyInfo.fs") - attributes - | Csproj -> - AssemblyInfoFile.createCSharp - ((folderName - @@ "Properties") - @@ "AssemblyInfo.cs") - attributes - | Vbproj -> - AssemblyInfoFile.createVisualBasic - ((folderName - @@ "My Project") - @@ "AssemblyInfo.vb") - attributes - ) - let createPackages _ = runtimes |> Seq.iter (fun (runtime, packageType) -> @@ -491,6 +456,7 @@ let createPackages _ = sprintf "/p:RuntimeIdentifier=%s" runtime sprintf "/p:Configuration=%s" "Release" sprintf "/p:PackageVersion=%s" latestEntry.NuGetVersion + yield! assemblyInfoMsBuildArgs () sprintf "/p:PackagePath=\"%s\"" (distDir @@ -510,12 +476,6 @@ let gitRelease _ = Git.Staging.stageFile "" "CHANGELOG.md" |> ignore - !!"src/**/AssemblyInfo.fs" - |> Seq.iter ( - Git.Staging.stageFile "" - >> ignore - ) - Git.Commit.exec "" (sprintf "Bump version to %s\n\n%s" latestEntry.NuGetVersion releaseNotesGitCommitFormat) @@ -606,7 +566,6 @@ let initTargets () = Target.create "GenerateCoverageReport" generateCoverageReport Target.create "WatchApp" watchApp Target.create "WatchTests" watchTests - Target.create "AssemblyInfo" generateAssemblyInfo Target.create "CreatePackages" createPackages Target.create "GitRelease" gitRelease Target.create "GitHubRelease" githubRelease @@ -626,25 +585,11 @@ let initTargets () = "Clean" ==>! "CreatePackages" - // Only call AssemblyInfo if there is a release target in the call chain - // Ensure AssemblyInfo is called after DotnetRestore and before DotnetBuild - "DotnetRestore" - ?=>! "AssemblyInfo" - - "AssemblyInfo" - ?=>! "DotnetBuild" - - "AssemblyInfo" - ==>! "GitRelease" - // Only call UpdateChangelog if there is a release target in the call chain - // Ensure UpdateChangelog is called after DotnetRestore and before AssemblyInfo + // Ensure UpdateChangelog is called after DotnetRestore "DotnetRestore" ?=>! "UpdateChangelog" - "UpdateChangelog" - ?=>! "AssemblyInfo" - "UpdateChangelog" ==>! "GitRelease" diff --git a/Content/Console/build/build.fsproj b/Content/Console/build/build.fsproj index 8a404997..267795e7 100644 --- a/Content/Console/build/build.fsproj +++ b/Content/Console/build/build.fsproj @@ -18,7 +18,6 @@ - diff --git a/Content/Console/src/Directory.Build.props b/Content/Console/src/Directory.Build.props index e67ecfec..b55c8189 100644 --- a/Content/Console/src/Directory.Build.props +++ b/Content/Console/src/Directory.Build.props @@ -9,6 +9,8 @@ Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" /> + true + $(MSBuildProjectName) false diff --git a/Content/Console/src/Directory.Build.targets b/Content/Console/src/Directory.Build.targets index cde61a89..388db2ad 100644 --- a/Content/Console/src/Directory.Build.targets +++ b/Content/Console/src/Directory.Build.targets @@ -1,7 +1,22 @@ - + true --analyzers-path "$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs" $(FSharpAnalyzersOtherFlags) --analyzers-path "$(PkgIonide_Analyzers)/analyzers/dotnet/fs" - \ No newline at end of file + + + + <_Parameter1>ReleaseDate + <_Parameter2>$(AssemblyMetadataReleaseDate) + + + <_Parameter1>ReleaseChannel + <_Parameter2>$(AssemblyMetadataReleaseChannel) + + + <_Parameter1>GitHash + <_Parameter2>$(AssemblyMetadataGitHash) + + + diff --git a/Content/Console/src/MyLib.1/AssemblyInfo.fs b/Content/Console/src/MyLib.1/AssemblyInfo.fs deleted file mode 100644 index d1613d7d..00000000 --- a/Content/Console/src/MyLib.1/AssemblyInfo.fs +++ /dev/null @@ -1,23 +0,0 @@ -// Auto-Generated by FAKE; do not edit -namespace System -open System.Reflection - -[] -[] -[] -[] -[] -[] -[] -[] -do () - -module internal AssemblyVersionInformation = - let [] AssemblyTitle = "MyLib.1" - let [] AssemblyProduct = "MyLib.1" - let [] AssemblyVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000" - let [] AssemblyFileVersion = "0.1.0" - let [] AssemblyInformationalVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseChannel = "release" - let [] AssemblyMetadata_GitHash = "b385af579477bb585016a6b5204121de4a485dac" diff --git a/Content/Console/src/MyLib.1/MyLib.1.fsproj b/Content/Console/src/MyLib.1/MyLib.1.fsproj index f177d838..bf3394f3 100755 --- a/Content/Console/src/MyLib.1/MyLib.1.fsproj +++ b/Content/Console/src/MyLib.1/MyLib.1.fsproj @@ -19,7 +19,6 @@ - diff --git a/Content/Library/README.md b/Content/Library/README.md index 14a85166..4887fcf8 100644 --- a/Content/Library/README.md +++ b/Content/Library/README.md @@ -98,7 +98,6 @@ src/MyLib.1/bin/ - `GenerateCoverageReport` - Code coverage is run during `DotnetTest` and this generates a report via [ReportGenerator](https://github.com/danielpalme/ReportGenerator). - `ShowCoverageReport` - Shows the report generated in `GenerateCoverageReport`. - `WatchTests` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) with the test projects. Useful for rapid feedback loops. -- `GenerateAssemblyInfo` - Generates [AssemblyInfo](https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.applicationservices.assemblyinfo?view=netframework-4.8) for libraries. - `DotnetPack` - Runs [dotnet pack](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-pack). This includes running [Source Link](https://github.com/dotnet/sourcelink). - `SourceLinkTest` - Runs a Source Link test tool to verify Source Links were properly generated. - `PublishToNuGet` - Publishes the NuGet packages generated in `DotnetPack` to NuGet via [nuget push](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push). Runs only from `Github Actions`. diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs index cdd665e2..a0028174 100644 --- a/Content/Library/build/build.fs +++ b/Content/Library/build/build.fs @@ -364,6 +364,30 @@ let deleteChangelogBackupFile _ = if String.isNotNullOrEmpty Changelog.changelogBackupFilename then Shell.rm Changelog.changelogBackupFilename +let assemblyInfoMsBuildArgs () = + let releaseChannel = + match latestEntry.SemVer.PreRelease with + | Some pr -> pr.Name + | _ -> "release" + + let releaseDate = latestEntry.Date.Value.ToString("o") + + let gitHash = + try + Git.Information.getCurrentSHA1 (null) + with _ -> + "" + + [ + $"/p:Version={latestEntry.AssemblyVersion}" + $"/p:AssemblyVersion={latestEntry.AssemblyVersion}" + $"/p:FileVersion={latestEntry.AssemblyVersion}" + $"/p:InformationalVersion={latestEntry.AssemblyVersion}" + $"/p:AssemblyMetadataReleaseDate={releaseDate}" + $"/p:AssemblyMetadataReleaseChannel={releaseChannel}" + $"/p:AssemblyMetadataGitHash={gitHash}" + ] + let dotnetBuild ctx = let args = [ @@ -509,69 +533,13 @@ let watchTests _ = cancelEvent.Cancel <- true -let generateAssemblyInfo _ = - - let (|Fsproj|Csproj|Vbproj|) (projFileName: string) = - match projFileName with - | f when f.EndsWith("fsproj") -> Fsproj - | f when f.EndsWith("csproj") -> Csproj - | f when f.EndsWith("vbproj") -> Vbproj - | _ -> - failwith (sprintf "Project file %s not supported. Unknown project type." projFileName) - - let releaseChannel = - match latestEntry.SemVer.PreRelease with - | Some pr -> pr.Name - | _ -> "release" - - let getAssemblyInfoAttributes projectName = [ - AssemblyInfo.Title(projectName) - AssemblyInfo.Product productName - AssemblyInfo.Version latestEntry.AssemblyVersion - AssemblyInfo.Metadata("ReleaseDate", latestEntry.Date.Value.ToString("o")) - AssemblyInfo.FileVersion latestEntry.AssemblyVersion - AssemblyInfo.InformationalVersion latestEntry.AssemblyVersion - AssemblyInfo.Metadata("ReleaseChannel", releaseChannel) - AssemblyInfo.Metadata("GitHash", Git.Information.getCurrentSHA1 (null)) - ] - - let getProjectDetails (projectPath: string) = - let projectName = IO.Path.GetFileNameWithoutExtension(projectPath) - - (projectPath, - projectName, - IO.Path.GetDirectoryName(projectPath), - (getAssemblyInfoAttributes projectName)) - - !!srcGlob - |> Seq.map getProjectDetails - |> Seq.iter (fun (projFileName, _, folderName, attributes) -> - match projFileName with - | Fsproj -> - AssemblyInfoFile.createFSharp - (folderName - "AssemblyInfo.fs") - attributes - | Csproj -> - AssemblyInfoFile.createCSharp - ((folderName - "Properties") - "AssemblyInfo.cs") - attributes - | Vbproj -> - AssemblyInfoFile.createVisualBasic - ((folderName - "My Project") - "AssemblyInfo.vb") - attributes - ) - let dotnetPack ctx = // Get release notes with properly-linked version number let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl let args = [ $"/p:PackageVersion={latestEntry.NuGetVersion}" + yield! assemblyInfoMsBuildArgs () $"/p:PackageReleaseNotes=\"{releaseNotes}\"" ] @@ -620,15 +588,6 @@ let gitRelease _ = Git.Staging.stageFile "" "CHANGELOG.md" |> ignore - !!(rootDirectory - "src/**/AssemblyInfo.fs") - ++ (rootDirectory - "tests/**/AssemblyInfo.fs") - |> Seq.iter ( - Git.Staging.stageFile "" - >> ignore - ) - let msg = sprintf "Bump version to %s\n\n%s" latestEntry.NuGetVersion releaseNotesGitCommitFormat @@ -731,7 +690,6 @@ let initTargets () = Target.create "GenerateCoverageReport" generateCoverageReport Target.create "ShowCoverageReport" showCoverageReport Target.create "WatchTests" watchTests - Target.create "GenerateAssemblyInfo" generateAssemblyInfo Target.create "DotnetPack" dotnetPack Target.create "SourceLinkTest" sourceLinkTest Target.create "PublishToNuGet" publishToNuget @@ -758,21 +716,10 @@ let initTargets () = "Clean" ==>! "DotnetPack" - // Only call GenerateAssemblyInfo if GitRelease was in the call chain - // Ensure GenerateAssemblyInfo is called after DotnetRestore and before DotnetBuild - "DotnetRestore" - ?=>! "GenerateAssemblyInfo" - - "GenerateAssemblyInfo" - ?=>! "DotnetBuild" - // Ensure UpdateChangelog is called after DotnetRestore "DotnetRestore" ?=>! "UpdateChangelog" - "UpdateChangelog" - ?=>! "GenerateAssemblyInfo" - "CleanDocsCache" ==>! "BuildDocs" @@ -791,7 +738,6 @@ let initTargets () = ==>! "ShowCoverageReport" "UpdateChangelog" - ==> "GenerateAssemblyInfo" ==> "GitRelease" ==>! "Release" diff --git a/Content/Library/src/Directory.Build.props b/Content/Library/src/Directory.Build.props index 133c4195..de83db80 100644 --- a/Content/Library/src/Directory.Build.props +++ b/Content/Library/src/Directory.Build.props @@ -9,6 +9,8 @@ Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" /> + true + $(MSBuildProjectName) true diff --git a/Content/Library/src/Directory.Build.targets b/Content/Library/src/Directory.Build.targets index cde61a89..388db2ad 100644 --- a/Content/Library/src/Directory.Build.targets +++ b/Content/Library/src/Directory.Build.targets @@ -1,7 +1,22 @@ - + true --analyzers-path "$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs" $(FSharpAnalyzersOtherFlags) --analyzers-path "$(PkgIonide_Analyzers)/analyzers/dotnet/fs" - \ No newline at end of file + + + + <_Parameter1>ReleaseDate + <_Parameter2>$(AssemblyMetadataReleaseDate) + + + <_Parameter1>ReleaseChannel + <_Parameter2>$(AssemblyMetadataReleaseChannel) + + + <_Parameter1>GitHash + <_Parameter2>$(AssemblyMetadataGitHash) + + + diff --git a/Content/Library/src/MyLib.1/AssemblyInfo.fs b/Content/Library/src/MyLib.1/AssemblyInfo.fs deleted file mode 100644 index 6f273302..00000000 --- a/Content/Library/src/MyLib.1/AssemblyInfo.fs +++ /dev/null @@ -1,23 +0,0 @@ -// Auto-Generated by FAKE; do not edit -namespace System -open System.Reflection - -[] -[] -[] -[] -[] -[] -[] -[] -do () - -module internal AssemblyVersionInformation = - let [] AssemblyTitle = "MyLib.1" - let [] AssemblyProduct = "MyLib.1" - let [] AssemblyVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000" - let [] AssemblyFileVersion = "0.1.0" - let [] AssemblyInformationalVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseChannel = "release" - let [] AssemblyMetadata_GitHash = "bb8964b54bee133e9af64d316dc2cfee16df7f72" diff --git a/Content/Library/src/MyLib.1/MyLib.1.fsproj b/Content/Library/src/MyLib.1/MyLib.1.fsproj index 66a0952d..bfc1ad6f 100755 --- a/Content/Library/src/MyLib.1/MyLib.1.fsproj +++ b/Content/Library/src/MyLib.1/MyLib.1.fsproj @@ -11,7 +11,6 @@ - diff --git a/Content/ProjConsole/AssemblyInfo.fs b/Content/ProjConsole/AssemblyInfo.fs deleted file mode 100644 index d1613d7d..00000000 --- a/Content/ProjConsole/AssemblyInfo.fs +++ /dev/null @@ -1,23 +0,0 @@ -// Auto-Generated by FAKE; do not edit -namespace System -open System.Reflection - -[] -[] -[] -[] -[] -[] -[] -[] -do () - -module internal AssemblyVersionInformation = - let [] AssemblyTitle = "MyLib.1" - let [] AssemblyProduct = "MyLib.1" - let [] AssemblyVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000" - let [] AssemblyFileVersion = "0.1.0" - let [] AssemblyInformationalVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseChannel = "release" - let [] AssemblyMetadata_GitHash = "b385af579477bb585016a6b5204121de4a485dac" diff --git a/Content/ProjConsole/MyLib.1.fsproj b/Content/ProjConsole/MyLib.1.fsproj index 6c0387e0..2e5e4a7b 100644 --- a/Content/ProjConsole/MyLib.1.fsproj +++ b/Content/ProjConsole/MyLib.1.fsproj @@ -10,7 +10,6 @@ - diff --git a/Content/ProjLib/AssemblyInfo.fs b/Content/ProjLib/AssemblyInfo.fs deleted file mode 100644 index 6f273302..00000000 --- a/Content/ProjLib/AssemblyInfo.fs +++ /dev/null @@ -1,23 +0,0 @@ -// Auto-Generated by FAKE; do not edit -namespace System -open System.Reflection - -[] -[] -[] -[] -[] -[] -[] -[] -do () - -module internal AssemblyVersionInformation = - let [] AssemblyTitle = "MyLib.1" - let [] AssemblyProduct = "MyLib.1" - let [] AssemblyVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000" - let [] AssemblyFileVersion = "0.1.0" - let [] AssemblyInformationalVersion = "0.1.0" - let [] AssemblyMetadata_ReleaseChannel = "release" - let [] AssemblyMetadata_GitHash = "bb8964b54bee133e9af64d316dc2cfee16df7f72" diff --git a/Content/ProjLib/MyLib.1.fsproj b/Content/ProjLib/MyLib.1.fsproj index 35c00fcc..504c1f0d 100644 --- a/Content/ProjLib/MyLib.1.fsproj +++ b/Content/ProjLib/MyLib.1.fsproj @@ -14,7 +14,6 @@ - diff --git a/tests/MiniScaffold.Tests/Asserts.fs b/tests/MiniScaffold.Tests/Asserts.fs index fbf5db30..f7ef6f60 100644 --- a/tests/MiniScaffold.Tests/Asserts.fs +++ b/tests/MiniScaffold.Tests/Asserts.fs @@ -1,6 +1,10 @@ namespace MiniScaffold.Tests open System.IO +open System.IO.Compression +open System.Diagnostics +open System.Reflection +open System.Runtime.Loader open Expecto open Infrastructure open Fake.IO.FileSystemOperators @@ -40,6 +44,9 @@ module Array = newArray module Assert = + let private deleteRetryDelayMs = 100 + let private maxDeleteRetries = 5 + open System let private failIfNoneWithMsg msg opt = @@ -134,6 +141,129 @@ module Assert = let ``File exists`` path = tryFindFile path + let ``File does not exist`` file (d: DirectoryInfo) = + let filepath = Path.Combine(d.FullName, file) + Expect.isFalse (File.Exists filepath) (sprintf "%s should not exist" filepath) + + let ``assembly info values are set after pack`` projectName (d: DirectoryInfo) = + let mutable extractedDllDir: string option = None + + let nupkgPath = Path.Combine(d.FullName, "dist", $"{projectName}.0.1.0.nupkg") + + Expect.isTrue (File.Exists nupkgPath) (sprintf "%s should exist" nupkgPath) + + use archive = ZipFile.OpenRead(nupkgPath) + + let entry = + archive.Entries + |> Seq.tryFind (fun x -> + x.FullName.StartsWith("lib/net8.0/") + && x.FullName.EndsWith($"/{projectName}.dll") + ) + + let dllPath = + match entry with + | Some e -> + let tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")) + + let tempPath = Path.Combine(tempDir, $"{projectName}.dll") + + Directory.CreateDirectory(tempDir) + |> ignore + + e.ExtractToFile(tempPath, true) + extractedDllDir <- Some tempDir + + tempPath + | None -> failtestf "Could not find lib/net8.0/%s.dll in %s" projectName nupkgPath + + let assemblyName = AssemblyName.GetAssemblyName(dllPath) + Expect.equal assemblyName.Version (Version "0.1.0.0") "AssemblyVersion should be 0.1.0.0" + + let fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath) + + Expect.isTrue + (fileVersionInfo.FileVersion = "0.1.0" + || fileVersionInfo.FileVersion = "0.1.0.0") + "FileVersion should be 0.1.0 or 0.1.0.0" + + let assemblyContext = + new AssemblyLoadContext($"metadata-{projectName}-{Guid.NewGuid():N}", true) + + try + use assemblyStream = new MemoryStream(File.ReadAllBytes dllPath) + let assembly = assemblyContext.LoadFromStream(assemblyStream) + + let title = + assembly.GetCustomAttribute() + |> Option.ofObj + |> Option.map _.Title + + Expect.equal title (Some projectName) "AssemblyTitle should match project name" + + let product = + assembly.GetCustomAttribute() + |> Option.ofObj + |> Option.map _.Product + + Expect.equal product (Some projectName) "AssemblyProduct should match project name" + + let informationalVersion = + assembly.GetCustomAttribute() + |> Option.ofObj + |> Option.map _.InformationalVersion + + Expect.equal informationalVersion (Some "0.1.0") "InformationalVersion should be 0.1.0" + + let metadata = + assembly.GetCustomAttributes() + |> Seq.map (fun x -> x.Key, x.Value) + |> Map.ofSeq + + Expect.equal + (metadata + |> Map.tryFind "ReleaseChannel") + (Some "release") + "ReleaseChannel should be release" + + let releaseDate = + metadata + |> Map.tryFind "ReleaseDate" + + Expect.isTrue + (releaseDate + |> Option.exists ( + String.IsNullOrWhiteSpace + >> not + )) + "ReleaseDate should be set" + finally + assemblyContext.Unload() + GC.Collect() + GC.WaitForPendingFinalizers() + GC.Collect() + + extractedDllDir + |> Option.iter (fun path -> + let rec deleteWithRetry attempts = + try + if Directory.Exists path then + Directory.Delete(path, true) + with + | :? IOException + | :? UnauthorizedAccessException when attempts > 0 -> + GC.Collect() + GC.WaitForPendingFinalizers() + System.Threading.Thread.Sleep deleteRetryDelayMs + + deleteWithRetry ( + attempts + - 1 + ) + + deleteWithRetry maxDeleteRetries + ) + module Effect = open System open Fake.IO diff --git a/tests/MiniScaffold.Tests/Infrastructure.fs b/tests/MiniScaffold.Tests/Infrastructure.fs index cf489172..79451799 100644 --- a/tests/MiniScaffold.Tests/Infrastructure.fs +++ b/tests/MiniScaffold.Tests/Infrastructure.fs @@ -4,6 +4,10 @@ namespace Infrastructure module Dotnet = open Fake.Core open Fake.DotNet + open System.Threading + + let private fantomasRetryDelayMs = 250 + let private fantomasMaxRetries = 2 let failOnBadExitAndPrint (p: ProcessResult) = if @@ -16,14 +20,32 @@ module Dotnet = failwithf "failed with exitcode %d" p.ExitCode let fantomas workingDir args = - DotNet.exec - (fun opt -> { - opt with - WorkingDirectory = workingDir - }) - "fantomas" - args - |> failOnBadExitAndPrint + let rec run attempts = + let result = + DotNet.exec + (fun opt -> { + opt with + WorkingDirectory = workingDir + }) + "fantomas" + args + + if + // Exit code 137 can occur when Fantomas is transiently terminated by the OS. + result.ExitCode = 137 + && attempts > 0 + then + Thread.Sleep fantomasRetryDelayMs + + run ( + attempts + - 1 + ) + else + result + |> failOnBadExitAndPrint + + run fantomasMaxRetries module New = let cmd (opt: DotNet.Options -> DotNet.Options) args = diff --git a/tests/MiniScaffold.Tests/Tests.fs b/tests/MiniScaffold.Tests/Tests.fs index 371469f6..4005158a 100755 --- a/tests/MiniScaffold.Tests/Tests.fs +++ b/tests/MiniScaffold.Tests/Tests.fs @@ -129,7 +129,9 @@ module Tests = "-n MyCoolLib --githubUsername CoolPersonNo2", [ yield! projectStructureAsserts + Assert.``File does not exist`` "src/MyCoolLib/AssemblyInfo.fs" Assert.``project can build target`` "DotnetPack" + Assert.``assembly info values are set after pack`` "MyCoolLib" Assert.``project can build target`` "BuildDocs" ] @@ -144,6 +146,7 @@ module Tests = "src" Effect.``dotnet sln add`` "src/MyCoolLib3/MyCoolLib3.fsproj" Assert.``File exists`` "src/MyCoolLib3/MyCoolLib3.fsproj" + Assert.``File does not exist`` "src/MyCoolLib3/AssemblyInfo.fs" Assert.``project can build target`` "DotnetPack" ] @@ -157,6 +160,7 @@ module Tests = "src" Effect.``dotnet sln add`` "src/MyCoolConsole/MyCoolConsole.fsproj" Assert.``File exists`` "src/MyCoolConsole/MyCoolConsole.fsproj" + Assert.``File does not exist`` "src/MyCoolConsole/AssemblyInfo.fs" Assert.``project can build target`` "DotnetPack" Effect.``dotnet run`` "" "src/MyCoolConsole/" ] @@ -179,6 +183,7 @@ module Tests = "../../src/MyCoolLib3/MyCoolLib3.fsproj" "tests/MyCoolLib3.Tests/" Assert.``File exists`` "tests/MyCoolLib3.Tests/MyCoolLib3.Tests.fsproj" + Assert.``File does not exist`` "tests/MyCoolLib3.Tests/AssemblyInfo.fs" Assert.``project can build target`` "DotnetPack" ] @@ -202,7 +207,7 @@ module Tests = "-n AssemblyInfoFail --githubUsername TestAccount", [ Effect.``setup for release tests`` - Effect.``make build function fail`` "let generateAssemblyInfo" + Effect.``make build function fail`` "let updateChangelog" Assert.``CHANGELOG contains Unreleased section`` Assert.``build target with failure expected`` "Release" Assert.``CHANGELOG contains Unreleased section`` @@ -305,7 +310,7 @@ module Tests = "-n AssemblyInfoFail --githubUsername TestAccount --outputType Console", [ Effect.``setup for release tests`` - Effect.``make build function fail`` "let generateAssemblyInfo" + Effect.``make build function fail`` "let updateChangelog" Assert.``CHANGELOG contains Unreleased section`` Assert.``build target with failure expected`` "Release" Assert.``CHANGELOG contains Unreleased section``