Skip to content

Commit 5dcf8f4

Browse files
authored
Remove dependency on System.IO.Abstractions (#116)
1 parent 479a92a commit 5dcf8f4

File tree

8 files changed

+94
-57
lines changed

8 files changed

+94
-57
lines changed

ApiSurface/ApiSurface.fs

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
namespace ApiSurface
22

33
open System
4-
open System.IO.Abstractions
4+
open System.IO
55
open System.Text.RegularExpressions
66
open System.Runtime.CompilerServices
77
open System.Runtime.InteropServices
88
open System.Reflection
9-
open System.IO
109

1110
type ApiSurface = internal | ApiSurface of string list
1211

@@ -176,37 +175,33 @@ module ApiSurface =
176175

177176
assembly |> ofAssembly |> toString |> writer.Write
178177

179-
let private readCurrentVersion (version : IFileInfo) =
180-
use stream = version.OpenRead ()
181-
use reader = new StreamReader (stream)
178+
let private readCurrentVersion (version : Stream) =
179+
use reader = new StreamReader (version)
182180
let versionFile = VersionFile.read reader
183181

184182
let versionParts = versionFile.Version.Split '.'
185183

186-
try
187-
{
188-
Major = int versionParts.[0]
189-
Minor = int versionParts.[1]
190-
}
191-
with _ ->
192-
// GitVersioning will verify the json file during build, before the test runs, so it's not expected that anyone will see this error.
193-
failwithf
194-
"Version in the version.json file must be of the form 'x.x' when x represents a whole number; it was %s."
195-
versionFile.Version
196-
197-
198-
let private writeUpdatedVersion (version : Version) (versionFile : IFileInfo) =
184+
let parsedVersion =
185+
try
186+
{
187+
Major = int versionParts.[0]
188+
Minor = int versionParts.[1]
189+
}
190+
with _ ->
191+
// GitVersioning will verify the json file during build, before the test runs, so it's not expected that anyone will see this error.
192+
failwithf
193+
"Version in the version.json file must be of the form 'x.x' when x represents a whole number; it was %s."
194+
versionFile.Version
195+
196+
versionFile, parsedVersion
197+
198+
let private writeUpdatedVersion (oldVersionFile : VersionFile) (newVersion : Version) (versionFile : Stream) =
199199
let updatedFile =
200-
use stream = versionFile.OpenRead ()
201-
use reader = new StreamReader (stream)
202-
let versionFile = VersionFile.read reader
203-
204-
{ versionFile with
205-
Version = sprintf "%d.%d" version.Major version.Minor
200+
{ oldVersionFile with
201+
Version = sprintf "%d.%d" newVersion.Major newVersion.Minor
206202
}
207203

208-
use writer = versionFile.Open FileMode.Create
209-
use writer = new StreamWriter (writer)
204+
use writer = new StreamWriter (versionFile)
210205
updatedFile |> VersionFile.write writer
211206

212207
let internal findNewVersion currentVersion (ApiSurface baseline) (ApiSurface target) =
@@ -228,8 +223,17 @@ module ApiSurface =
228223
// If the api was not changed, then GitVersioning will handle the patch version
229224
| _ -> currentVersion
230225

231-
let updateVersionJson (baseline : ApiSurface) (assembly : Assembly) (versionFile : IFileInfo) : unit =
232-
let currentVersion = readCurrentVersion versionFile
226+
let updateVersionJson<'fileInfo>
227+
(baseline : ApiSurface)
228+
(assembly : Assembly)
229+
(versionFile : 'fileInfo)
230+
(openVersionFile : 'fileInfo -> FileMode * FileAccess -> Stream)
231+
: unit
232+
=
233+
let oldVersionFile, currentVersion =
234+
use versionFile = openVersionFile versionFile (FileMode.Open, FileAccess.Read)
235+
readCurrentVersion versionFile
236+
233237
printfn "Current version %d.%d" currentVersion.Major currentVersion.Minor
234238

235239
let updatedVersion = findNewVersion currentVersion baseline (ofAssembly assembly)
@@ -239,12 +243,14 @@ module ApiSurface =
239243
else
240244
printfn "Updated version to %d.%d" updatedVersion.Major updatedVersion.Minor
241245

242-
writeUpdatedVersion updatedVersion versionFile
246+
do
247+
use versionFile = openVersionFile versionFile (FileMode.Truncate, FileAccess.Write)
248+
writeUpdatedVersion oldVersionFile updatedVersion versionFile
243249

244250
let writeAssembly
245251
(baseline : ApiSurface)
246252
(possibleBaselineResources : string list)
247-
(versionFiles : IFileInfo list)
253+
(versionFiles : FileInfo list)
248254
(assembly : Assembly)
249255
: unit
250256
=
@@ -275,7 +281,7 @@ module ApiSurface =
275281
match versionFile with
276282
| Some versionFile ->
277283
printfn "Updating version.json file: %s" versionFile.FullName
278-
updateVersionJson baseline assembly versionFile
284+
updateVersionJson baseline assembly versionFile (fun f (mode, access) -> f.Open (mode, access))
279285
| None -> ()
280286

281287
printfn "Updating baseline file: %s" baselinePath
@@ -285,13 +291,12 @@ module ApiSurface =
285291
let writeAssemblyBaselineWithDirectory (dir : string) (assembly : Assembly) : unit =
286292
let possibleBaselineResources = findBaselineResourcesWithDirectory dir assembly
287293

288-
let versionFiles =
289-
VersionFile.findVersionFilesWithDirectory (FileSystem ()) dir assembly
294+
let versionFiles = VersionFile.findVersionFilesWithDirectory FileInfo dir assembly
290295

291296
writeAssembly (ofAssemblyBaseline assembly) possibleBaselineResources versionFiles assembly
292297

293298
[<CompiledName "WriteAssemblyBaseline">]
294299
let writeAssemblyBaseline (assembly : Assembly) : unit =
295300
let possibleBaselineResources = findBaselineResources assembly
296-
let versionFiles = VersionFile.findVersionFiles (FileSystem ()) assembly
301+
let versionFiles = VersionFile.findVersionFiles FileInfo assembly
297302
writeAssembly (ofAssemblyBaseline assembly) possibleBaselineResources versionFiles assembly

ApiSurface/ApiSurface.fsi

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace ApiSurface
22

3+
open System.IO
34
open System.Reflection
45

56
/// Represents the public API surface of an assembly.
@@ -46,18 +47,26 @@ module ApiSurface =
4647
[<CompiledName "AssertIdentical">]
4748
val assertIdentical : Assembly -> unit
4849

49-
/// Updates an assembly's SurfaceBaseline.txt file on the disk.
50-
/// Expects to find '../<AssemblyName>/SurfaceBaseline.txt' somewhere in
50+
/// <summary>Updates an assembly's SurfaceBaseline.txt file on the disk.</summary>
51+
/// <remarks>
52+
/// Expects to find '../&lt;AssemblyName&gt;/SurfaceBaseline.txt' somewhere in
5153
/// the directory ancestry tree.
54+
/// </remarks>
5255
[<CompiledName "WriteAssemblyBaseline">]
5356
val writeAssemblyBaseline : Assembly -> unit
5457

55-
/// Updates an assembly's SurfaceBaseline.txt file on the disk.
56-
/// Expects to find '../<supplied directory>/SurfaceBaseline.txt' somewhere in the directory tree.
58+
/// <summary>Updates an assembly's SurfaceBaseline.txt file on the disk.</summary>
59+
/// <remarks>
60+
/// Expects to find <c>../&lt;supplied directory&gt;/SurfaceBaseline.txt</c> somewhere in the directory tree.
61+
/// </remarks>
5762
[<CompiledName "WriteAssemblyBaselineWithDirectory">]
5863
val writeAssemblyBaselineWithDirectory : string -> Assembly -> unit
5964

6065
val internal findNewVersion : Version -> baseline : ApiSurface -> target : ApiSurface -> Version
6166

62-
val internal updateVersionJson :
63-
baseline : ApiSurface -> Assembly -> versionFile : System.IO.Abstractions.IFileInfo -> unit
67+
val internal updateVersionJson<'fileInfo> :
68+
baseline : ApiSurface ->
69+
Assembly ->
70+
versionFile : 'fileInfo ->
71+
openVersionFile : ('fileInfo -> FileMode * FileAccess -> Stream) ->
72+
unit

ApiSurface/ApiSurface.fsproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,5 @@
4444
<PackageReference Include="System.Text.Json" Version="8.0.5" NoWarn="%(NoWarn);NU1903" />
4545
<PackageReference Include="NuGet.Packaging" Version="6.14.0" />
4646
<PackageReference Include="NuGet.Protocol" Version="6.14.0" />
47-
<PackageReference Include="System.IO.Abstractions" Version="4.2.13" />
4847
</ItemGroup>
4948
</Project>

ApiSurface/Assembly.fs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ open System
44
open System.IO
55
open System.Reflection
66

7+
/// Helper functions for dealing with the Assembly type.
78
[<RequireQualifiedAccess>]
8-
module internal Assembly =
9+
module Assembly =
910

1011
/// Attempt to retrieve an embedded resource from an assembly.
11-
let tryReadEmbeddedResource (assembly : Assembly) (resourcePath : string) : Stream option =
12+
let internal tryReadEmbeddedResource (assembly : Assembly) (resourcePath : string) : Stream option =
1213
let resourcePath = resourcePath.Replace ("/", ".")
1314
let assemblyResourceName ns = sprintf "%s.%s" ns resourcePath
1415

@@ -26,6 +27,8 @@ module internal Assembly =
2627
|> Set.add resourcePath
2728
|> Seq.tryPick (assembly.GetManifestResourceStream >> Option.ofObj)
2829

30+
/// You are not expected to use this function directly.
31+
///
2932
/// Finds all 'fileNames' in ancestor directories of the assembly's location, where
3033
/// we specifically look for the given parentDir.
3134
let findProjectFilesWithDirectory (parentDir : string) fileNames (assembly : Assembly) =
@@ -56,6 +59,8 @@ module internal Assembly =
5659
fileNames assembly
5760
|> List.map (fun f -> Path.Combine (findParentDir parentDir (FileInfo assembly.Location).Directory, f))
5861

59-
/// Finds all 'fileNames' in ancestor directories of 'assembly'
60-
let findProjectFiles fileNames (assembly : Assembly) =
62+
/// You are not expected to use this function directly.
63+
///
64+
/// Finds all 'fileNames' in ancestor directories of 'assembly'.
65+
let findProjectFiles (fileNames : Assembly -> string list) (assembly : Assembly) =
6166
findProjectFilesWithDirectory (assembly.GetName().Name) fileNames assembly

ApiSurface/SurfaceBaseline.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ ApiSurface.ApiSurfaceModule.FromAssemblyCustomPrint [static method]: (ApiSurface
2424
ApiSurface.ApiSurfaceModule.ToString [static method]: ApiSurface.ApiSurface -> string
2525
ApiSurface.ApiSurfaceModule.WriteAssemblyBaseline [static method]: System.Reflection.Assembly -> unit
2626
ApiSurface.ApiSurfaceModule.WriteAssemblyBaselineWithDirectory [static method]: string -> System.Reflection.Assembly -> unit
27+
ApiSurface.Assembly inherit obj
28+
ApiSurface.Assembly.findProjectFiles [static method]: (System.Reflection.Assembly -> string list) -> System.Reflection.Assembly -> string list
29+
ApiSurface.Assembly.findProjectFilesWithDirectory [static method]: string -> (System.Reflection.Assembly -> string list) -> System.Reflection.Assembly -> string list
2730
ApiSurface.DocCoverage inherit obj, implements ApiSurface.DocCoverage System.IEquatable, System.Collections.IStructuralEquatable, ApiSurface.DocCoverage System.IComparable, System.IComparable, System.Collections.IStructuralComparable
2831
ApiSurface.DocCoverageModule inherit obj
2932
ApiSurface.DocCoverageModule.AssertFullyDocumented [static method]: System.Reflection.Assembly -> unit
@@ -111,7 +114,7 @@ ApiSurface.VersionFile.PathFilters [property]: [read-only] string list option
111114
ApiSurface.VersionFile.PublicReleaseRefSpec [property]: [read-only] string list
112115
ApiSurface.VersionFile.Version [property]: [read-only] string
113116
ApiSurface.VersionFileModule inherit obj
114-
ApiSurface.VersionFileModule.findVersionFiles [static method]: System.IO.Abstractions.IFileSystem -> System.Reflection.Assembly -> System.IO.Abstractions.IFileInfo list
115-
ApiSurface.VersionFileModule.findVersionFilesWithDirectory [static method]: System.IO.Abstractions.IFileSystem -> string -> System.Reflection.Assembly -> System.IO.Abstractions.IFileInfo list
117+
ApiSurface.VersionFileModule.findVersionFiles [static method]: (string -> 'fileInfo) -> System.Reflection.Assembly -> 'fileInfo list
118+
ApiSurface.VersionFileModule.findVersionFilesWithDirectory [static method]: (string -> 'fileInfo) -> string -> System.Reflection.Assembly -> 'fileInfo list
116119
ApiSurface.VersionFileModule.read [static method]: System.IO.StreamReader -> ApiSurface.VersionFile
117-
ApiSurface.VersionFileModule.write [static method]: System.IO.StreamWriter -> ApiSurface.VersionFile -> unit
120+
ApiSurface.VersionFileModule.write [static method]: System.IO.StreamWriter -> ApiSurface.VersionFile -> unit

ApiSurface/Test/TestVersionFile.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ module TestVersionFile =
159159
|> fun s -> fs.File.WriteAllText (location.FullName, s)
160160

161161
let baseline = ApiSurface [ "something" ; "something else" ]
162-
ApiSurface.updateVersionJson baseline typeof<ApiSurface>.Assembly location
162+
ApiSurface.updateVersionJson baseline typeof<ApiSurface>.Assembly location _.Open
163163

164164
let output = fs.File.ReadAllText location.FullName
165165

ApiSurface/VersionFile.fs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
namespace ApiSurface
22

33
open System.IO
4-
open System.IO.Abstractions
54
open System.Text.Json
65
open System.Reflection
7-
open System.Text.Json.Serialization
86

97
/// A record representing the layout of a version.json file, e.g. as consumed by NerdBank.GitVersioning.
108
type VersionFile =
@@ -40,15 +38,33 @@ module VersionFile =
4038
JsonSerializer.Serialize (versionFile, writeOptions) |> writer.Write
4139

4240
/// Find version.json files referenced within this assembly.
43-
let findVersionFiles (fs : IFileSystem) (assembly : Assembly) : IFileInfo list =
41+
/// Pass e.g. `fs.FileInfo.FromFileName` (from System.IO.Abstractions) or `FileInfo` (from System.IO)
42+
/// as the `fromFileName` argument.
43+
let inline findVersionFiles< ^fileInfo when ^fileInfo : (member Exists : bool)>
44+
(fromFileName : string -> 'fileInfo)
45+
(assembly : Assembly)
46+
: 'fileInfo list
47+
=
4448
let filenames = assembly |> Assembly.findProjectFiles (fun _ -> [ "version.json" ])
45-
filenames |> List.filter File.Exists |> List.map fs.FileInfo.FromFileName
49+
50+
filenames
51+
|> List.map fromFileName
52+
|> List.filter (fun f -> (^fileInfo : (member Exists : bool) f))
4653

4754
/// Find version.json files above this assembly, but stopping when we hit a directory with
4855
/// the given name.
49-
let findVersionFilesWithDirectory (fs : IFileSystem) (dir : string) (assembly : Assembly) : IFileInfo list =
56+
/// Pass e.g. `fs.FileInfo.FromFileName` (from System.IO.Abstractions) or `FileInfo` (from System.IO)
57+
/// as the `fromFileName` argument.
58+
let inline findVersionFilesWithDirectory<'fileInfo when ^fileInfo : (member Exists : bool)>
59+
(fromFileName : string -> 'fileInfo)
60+
(dir : string)
61+
(assembly : Assembly)
62+
: 'fileInfo list
63+
=
5064
let filenames =
5165
assembly
5266
|> Assembly.findProjectFilesWithDirectory dir (fun _ -> [ "version.json" ])
5367

54-
filenames |> List.filter File.Exists |> List.map fs.FileInfo.FromFileName
68+
filenames
69+
|> List.map fromFileName
70+
|> List.filter (fun f -> (^fileInfo : (member Exists : bool) f))

ApiSurface/version.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "4.1",
2+
"version": "5.0",
33
"publicReleaseRefSpec": [
44
"^refs/heads/main$"
55
],
@@ -17,4 +17,4 @@
1717
":^/.git-blame-ignore-revs",
1818
":^/.gitignore"
1919
]
20-
}
20+
}

0 commit comments

Comments
 (0)