Scan assembly for mutations
This commit is contained in:
parent
05deb1f089
commit
10ddbef963
1 changed files with 66 additions and 8 deletions
|
|
@ -1,13 +1,77 @@
|
|||
open System
|
||||
open System.IO
|
||||
open System.Reflection
|
||||
open System.Runtime.InteropServices
|
||||
open Fli
|
||||
|
||||
type MutationCase = { TestName: string; Id: string }
|
||||
|
||||
let ensureBuilt projectPath =
|
||||
cli {
|
||||
Exec "dotnet"
|
||||
Arguments [ "build"; projectPath ]
|
||||
Output(new StreamWriter(Console.OpenStandardOutput()))
|
||||
}
|
||||
|> Command.execute
|
||||
|> Output.throwIfErrored
|
||||
|> ignore
|
||||
|
||||
let getAssemblyPath projectPath =
|
||||
cli {
|
||||
Exec "dotnet"
|
||||
Arguments [ "msbuild"; projectPath; "--getProperty:TargetPath" ]
|
||||
}
|
||||
|> Command.execute
|
||||
|> Output.toText
|
||||
|
||||
let getMetadataLoadContext (assemblyPath: string) =
|
||||
// This allows us to inspect assemblies regardless of the platform that they were built for
|
||||
// https://learn.microsoft.com/en-us/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext
|
||||
let assemblyDir = Path.GetDirectoryName assemblyPath
|
||||
|
||||
let pathAssemblyResolver =
|
||||
[ yield assemblyPath
|
||||
yield! Directory.EnumerateFiles(assemblyDir, "*.dll")
|
||||
yield! Directory.EnumerateFiles(assemblyDir, "*.exe")
|
||||
yield! Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll") ]
|
||||
|> PathAssemblyResolver
|
||||
|
||||
new MetadataLoadContext(pathAssemblyResolver, typeof<obj>.Assembly.GetName().Name)
|
||||
|
||||
let getMutationCases projectPath =
|
||||
ensureBuilt projectPath
|
||||
|
||||
let assemblyPath = getAssemblyPath projectPath
|
||||
|
||||
use metadataLoadContext = getMetadataLoadContext assemblyPath
|
||||
|
||||
let assemblyTypes =
|
||||
assemblyPath |> metadataLoadContext.LoadFromAssemblyPath |> _.GetTypes()
|
||||
|
||||
let assemblyMethods =
|
||||
assemblyTypes
|
||||
|> Seq.collect _.GetMethods(BindingFlags.Public ||| BindingFlags.Instance)
|
||||
|
||||
assemblyMethods
|
||||
|> Seq.collect (fun m ->
|
||||
m.GetCustomAttributesData()
|
||||
|> Seq.choose (fun attr ->
|
||||
match attr.AttributeType.FullName with
|
||||
| "Mutannot.MutationCaseAttribute" ->
|
||||
Some
|
||||
{ TestName = $"{m.DeclaringType.FullName}.{m.Name}"
|
||||
Id = attr.ConstructorArguments[0].Value :?> string }
|
||||
| _ -> None))
|
||||
|> Seq.toList
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
if argv.Length <> 1 then
|
||||
eprintfn "Usage: mutannot <path/to/project.csproj|fsproj>"
|
||||
exit 1
|
||||
|
||||
let projectPath = argv[0]
|
||||
|
||||
let gitState =
|
||||
cli {
|
||||
Exec "git"
|
||||
|
|
@ -20,13 +84,7 @@ let main argv =
|
|||
eprintfn "Uncommitted changes. Refusing to run."
|
||||
exit 2
|
||||
|
||||
cli {
|
||||
Exec "dotnet"
|
||||
Arguments [ "build"; argv[0] ]
|
||||
Output(new StreamWriter(Console.OpenStandardOutput()))
|
||||
}
|
||||
|> Command.execute
|
||||
|> Output.throwIfErrored
|
||||
|> ignore
|
||||
for mutationCase in getMutationCases projectPath do
|
||||
printfn "%s" <| mutationCase.ToString()
|
||||
|
||||
0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue