Simplify target path discovery

This commit is contained in:
Sven van Heugten 2026-04-27 23:15:16 +02:00
parent 28ae18b480
commit 678deb8fd9
No known key found for this signature in database
GPG key ID: D612F88666F4F660

View file

@ -2,7 +2,6 @@ open System
open System.IO
open System.Reflection
open System.Diagnostics
open System.Xml.Linq
type MutationCase =
{ Id: string
@ -31,10 +30,7 @@ type Options =
type ProjectInfo =
{ RelativeProjectPath: string
AbsoluteProjectPath: string
ProjectDirectory: string
AssemblyName: string
TargetFramework: string }
AbsoluteProjectPath: string }
let fail message =
eprintfn "%s" message
@ -80,9 +76,6 @@ let repoRoot =
if exitCode <> 0 then fail stderr
stdout.Trim()
let makeRelativePath (path: string) =
if Path.IsPathRooted path then Path.GetRelativePath(repoRoot, path) else path
let parseArgs (args: string list) =
let rec loop configuration projectPath noBuild remaining =
match remaining with
@ -114,47 +107,24 @@ let loadProjectInfo (projectPath: string) =
fail $"Project file not found: {absoluteProjectPath}"
let relativeProjectPath = ensureWithinRepo absoluteProjectPath
let projectDirectory = Path.GetDirectoryName relativeProjectPath
let document = XDocument.Load absoluteProjectPath
let tryGetProperty name =
document.Descendants()
|> Seq.tryPick (fun element ->
if element.Name.LocalName = name then
let value = element.Value.Trim()
if String.IsNullOrWhiteSpace value then None else Some value
else
None)
let targetFramework =
match tryGetProperty "TargetFramework" with
| Some value -> value
| None ->
match tryGetProperty "TargetFrameworks" with
| Some value ->
value.Split(';', StringSplitOptions.RemoveEmptyEntries)
|> Array.tryHead
|> Option.map _.Trim()
|> Option.defaultWith (fun () -> fail $"Could not determine TargetFramework from {relativeProjectPath}")
| None -> fail $"Could not determine TargetFramework from {relativeProjectPath}"
let assemblyName =
tryGetProperty "AssemblyName"
|> Option.defaultValue (Path.GetFileNameWithoutExtension absoluteProjectPath)
{ RelativeProjectPath = relativeProjectPath
AbsoluteProjectPath = absoluteProjectPath
ProjectDirectory = projectDirectory
AssemblyName = assemblyName
TargetFramework = targetFramework }
AbsoluteProjectPath = absoluteProjectPath }
let project =
match options.ProjectPath with
| Some projectPath -> loadProjectInfo projectPath
| None -> fail "Missing required --project <path/to/project.fsproj>."
let assemblyPath =
Path.Combine(repoRoot, project.ProjectDirectory, "bin", options.Configuration, project.TargetFramework, project.AssemblyName + ".dll")
let targetPathForProject (workingDirectory: string) (projectPath: string) =
let exitCode, stdout, stderr =
captureProcess workingDirectory "dotnet" [ "msbuild"; projectPath; "--getProperty:TargetPath"; $"-property:Configuration={options.Configuration}" ]
if exitCode <> 0 then fail stderr
let targetPath = stdout.Trim()
if String.IsNullOrWhiteSpace targetPath then
fail $"MSBuild did not return a TargetPath for {projectPath}."
targetPath
let assemblyPath = targetPathForProject repoRoot project.AbsoluteProjectPath
let ensureBuilt () =
if not options.NoBuild then