From c93f87d2823ee795bc9a755c093949bf64790f77 Mon Sep 17 00:00:00 2001 From: Sven van Heugten Date: Tue, 12 May 2026 08:32:11 +0200 Subject: [PATCH] Apply the mutations --- Mutannot/Program.fs | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Mutannot/Program.fs b/Mutannot/Program.fs index 5c3f6be..d3d9f06 100644 --- a/Mutannot/Program.fs +++ b/Mutannot/Program.fs @@ -19,6 +19,25 @@ let ensureCleanWorkingDirectory () = eprintfn "Uncommitted changes. Refusing to run." exit 2 +let applyPatch patch = + cli { + Exec "git" + Arguments [ "apply"; "-" ] + Input patch + } + |> Command.execute + |> Output.throwIfErrored + |> ignore + +let restore () = + cli { + Exec "git" + Arguments [ "restore"; "--staged"; "--worktree"; "." ] + } + |> Command.execute + |> Output.throwIfErrored + |> ignore + let ensureBuilt projectPath = cli { Exec "dotnet" @@ -51,6 +70,19 @@ let getMetadataLoadContext (assemblyPath: string) = new MetadataLoadContext(pathAssemblyResolver, typeof.Assembly.GetName().Name) +let unindented (s: string) = + let lines = s.Split([| "\r\n"; "\n" |], StringSplitOptions.None) + + let indexOfFirstNonEmptyLine = + lines |> Array.findIndex (not << String.IsNullOrWhiteSpace) + + let identantionOfFirstNonEmptyLine = + lines[indexOfFirstNonEmptyLine] |> Seq.takeWhile Char.IsWhiteSpace |> Seq.length + + lines[indexOfFirstNonEmptyLine..] + |> Seq.map (fun line -> line.Substring(min identantionOfFirstNonEmptyLine line.Length)) + |> String.concat Environment.NewLine + let getMutationCases projectPath = ensureBuilt projectPath @@ -73,7 +105,7 @@ let getMutationCases projectPath = | "Mutannot.MutationCaseAttribute" -> Some { TestName = $"{m.DeclaringType.FullName}.{m.Name}" - Patch = attr.ConstructorArguments[0].Value :?> string } + Patch = attr.ConstructorArguments[0].Value :?> string |> unindented } | _ -> None)) |> Seq.toList @@ -85,9 +117,13 @@ let main argv = ensureCleanWorkingDirectory () + AppDomain.CurrentDomain.ProcessExit.Add(fun _ -> restore ()) + let projectPath = argv[0] for mutationCase in getMutationCases projectPath do - printfn "%s" <| mutationCase.ToString() + printfn "MUTATION\n\n%s" <| mutationCase.Patch + applyPatch mutationCase.Patch + restore () 0