Skip to content

Commit db135cf

Browse files
author
Durdsoft
committed
efcore#43 PoC - Add new migrations to project
1 parent b9e9511 commit db135cf

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

src/EFCore.FSharp/Migrations/Design/FSharpMigrationsScaffolder.fs

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
namespace EntityFrameworkCore.FSharp.Migrations.Design
22

3+
open System
4+
open System.IO
5+
open System.Text
36
open Microsoft.EntityFrameworkCore.Migrations.Design
47
open Microsoft.EntityFrameworkCore.Internal
58
open EntityFrameworkCore.FSharp.IndentedStringBuilderUtilities
6-
open System.Text
7-
open System.IO
9+
open System
10+
open System
11+
open Microsoft.EntityFrameworkCore
12+
813

914
type FSharpMigrationsScaffolder(dependencies) =
1015
inherit MigrationsScaffolder(dependencies)
@@ -46,8 +51,86 @@ type FSharpMigrationsScaffolder(dependencies) =
4651
Directory.CreateDirectory(modelSnapshotDirectory) |> ignore
4752
File.WriteAllText(modelSnapshotFile, migration.SnapshotCode, Encoding.UTF8)
4853

54+
let projectFiles =
55+
Directory.GetFiles(projectDir)
56+
|> Seq.filter (fun f -> f.EndsWith ".fsproj")
57+
|> Seq.toList
58+
59+
match projectFiles with
60+
| [] -> dependencies.OperationReporter.WriteVerbose(sprintf "Unable to find .fsproj file in %s" projectDir)
61+
62+
| [ projectFile ] ->
63+
let projectDirectory = Path.GetDirectoryName projectFile
64+
let projectContents = File.ReadAllLines projectFile
65+
66+
let allDbContextTypes =
67+
dependencies.MigrationsAssembly.Assembly.GetTypes()
68+
|> Seq.filter (fun t -> typeof<DbContext>.IsAssignableFrom t)
69+
|> Seq.map (fun t -> sprintf "type %s" t.Name)
70+
71+
let declaringFiles =
72+
projectContents
73+
|> Seq.filter (fun l -> l.Contains("<Compile Include=\""))
74+
|> Seq.map (fun l -> l.Replace("<Compile Include=\"", "").Replace("/>", "").TrimStart().TrimEnd().TrimEnd('"'))
75+
|> Seq.map (fun l -> (l, File.ReadAllText l))
76+
|> Seq.filter (fun (_, c) -> allDbContextTypes |> Seq.exists (fun t -> c.Contains t))
77+
|> Seq.map fst
78+
|> Seq.toList
79+
80+
let rec calculateInsertPoint (compileIncludesToFind: string list) (searchLines: (int * string) seq) (acc: int) =
81+
match compileIncludesToFind with
82+
| [ ] -> acc + 1
83+
| _ ->
84+
let line = compileIncludesToFind.Head
85+
let location =
86+
searchLines
87+
|> Seq.skipWhile (fun (_, l) -> l.Contains(sprintf "\"%s\"" line) |> not)
88+
|> Seq.map fst
89+
|> Seq.head
90+
91+
let newLocation = if location > acc then location else acc
92+
calculateInsertPoint (compileIncludesToFind.Tail) searchLines newLocation
93+
94+
let indexedProjectContents =
95+
projectContents
96+
|> Seq.mapi (fun i l -> (i, l))
97+
98+
let insertionPoint =
99+
calculateInsertPoint declaringFiles indexedProjectContents 0
100+
101+
let indentation =
102+
(projectContents
103+
|> Seq.toArray).[insertionPoint + 1]
104+
|> Seq.takeWhile (fun c -> c = ' ')
105+
|> String.Concat
106+
107+
let compileIncludes =
108+
[ migrationFile; modelSnapshotFile; if migration.MigrationCode <> "// intentionally empty" then migrationMetadataFile; ]
109+
|> Seq.filter (isNull >> not)
110+
|> Seq.map (fun s -> s.Replace(projectDirectory, "").TrimStart('\\'))
111+
|> Seq.map (fun s -> sprintf "%s<Compile Include=\"%s\" />" indentation s)
112+
|> Seq.toList
113+
114+
let startProjectFile =
115+
projectContents
116+
|> Seq.take insertionPoint
117+
|> Seq.toList
118+
119+
let endProjectFile =
120+
projectContents
121+
|> Seq.skip insertionPoint
122+
|> Seq.toList
123+
124+
let newProjectContents =
125+
[ startProjectFile; compileIncludes; endProjectFile ]
126+
|> List.concat
127+
128+
File.WriteAllLines(projectFile, newProjectContents)
129+
130+
| _ -> dependencies.OperationReporter.WriteVerbose(sprintf "Ambiguous .fsproj file in %s. Please manually add the generated files." projectDir)
131+
49132
MigrationFiles (
50133
MigrationFile = migrationFile,
51134
MetadataFile = migrationMetadataFile,
52135
SnapshotFile = modelSnapshotFile
53-
)
136+
)

0 commit comments

Comments
 (0)