ApiSurface 3.0.10
See the version list below for details.
dotnet add package ApiSurface --version 3.0.10
NuGet\Install-Package ApiSurface -Version 3.0.10
<PackageReference Include="ApiSurface" Version="3.0.10" />
paket add ApiSurface --version 3.0.10
#r "nuget: ApiSurface, 3.0.10"
// Install ApiSurface as a Cake Addin #addin nuget:?package=ApiSurface&version=3.0.10 // Install ApiSurface as a Cake Tool #tool nuget:?package=ApiSurface&version=3.0.10
ApiSurface
This library provides several modules for ensuring the consistency and documentation coverage of an F# assembly's public API.
How to get started
- Create an empty
SurfaceBaseline.txt
file next to your assembly's.fsproj
file. (.csproj
files are not officially supported, but have been observed to work.) - Add an
<EmbeddedResource Include="SurfaceBaseline.txt" />
entry to that.fsproj
file. - Following the example of this repository's
ApiSurface.Test.TestSurface
, create tests as follows:namespace MyLibrary.Test open NUnit.Framework open ApiSurface open MyLibrary [<TestFixture>] module TestSurface = let assembly = typeof<TypeFromMyLibrary>.Assembly [<Test>] let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly [<Test; Explicit>] let ``Update API surface`` () = ApiSurface.writeAssemblyBaseline assembly [<Test>] let ``Ensure public API is fully documented`` () = DocCoverage.assertFullyDocumented assembly [<Test>] let ``Ensure version is monotonic`` () = MonotonicVersion.validate assembly "NuGet.PackageName"
- Run the
Explicit
test calledUpdate API surface
, to populate the emptySurfaceBaseline.txt
file you made earlier. - Similarly, place a
version.json
file next to your project, using the NerdBank.GitVersioning format, and include it as anEmbeddedResource
. - Run the
Ensure version is monotonic
test, to check that yourversion.json
file correctly specifies a version number which is valid with respect to the current release of your NuGet package.
The modules of ApiSurface
ApiSurface
module
The ApiSurface
module enforces that the public API surface does not change.
The public API is serialised in a 'SurfaceBaseline.txt' file that is embedded in the assembly.
Unit tests can then ensure that the API surface of the assembly under test matches that which is encoded in the baseline text file.
You can use ApiSurface.writeAssemblyBaseline
to manually update the SurfaceBaseline.txt
file.
Common practice is to call this function inside a unit test which is marked Explicit
- this ensures that the public API is easy to update with a single click, but that it is not accidentally extended (or reduced) simply by running your normal tests.
DocCoverage
module
The DocCoverage
module provides a function to ensure that the entirety of the public API surface is documented. Note that there are some exceptions to this rule:
- Class constructors never need to be documented. These tend to never be more useful than 'Instantiates the type' anyway.
- All discriminated union case constructors have to be documented.
- Modules which have the same name as a type do not have to be documented. It is self-explanatory that the module simply contains function that construct/act upon the type they are named after.
It is possible to explicitly annotate a type or member as not needing documentation by adding the [<Undocumented>]
attribute.
When applied to a type, all members of that type inherit the [<Undocumented>]
attribute.
This can be overridden with [<Undocumented(MembersInherit=false)>]
.
MonotonicVersion
module
The MonotonicVersion
module provides a function to ensure that the version
field in the version.json
file is always increasing.
This check can fail if a change which increments the major or minor version is reverted.
Semantic Versioning
Along with monitoring a project's public API, this library can be used to encourage semantic versioning.
When running the explicit test (see below) to update a project's SurfaceBaseline file, the test will also look for a version.json
file (in the same location as the SurfaceBaseline file).
If the version.json
file is not found, an error will be raised.
If the version.json
file is found, the version.json
file will be updated with a newer version using the following logic (from https://semver.org/):
- MAJOR version is incremented when backwards incompatible API changes are detected (i.e. API memebers are changed or removed)
- MINOR version is incremented when added backwards-compatible functionality changes are detected (i.e. API members are added only)
If no API changes are detected, the version will not be incremented by the test. If you are using NerdBank.GitVersioning then the PATCH version will be incremented as required for any change, in combination with the above.
Important!
This isn't intended to replace a real human thinking about the version number.
Breaking behaviour changes (without API changes) still require a major version bump, but no tool can make this judgement for you; ApiSurface
only detects the most obvious cases, where the API surface has changed.
There are not any currently known changes you can make to the API surface of your library that "should" be recognisably major version bumps but which do not result in ApiSurface
flagging the change.
Please raise an issue if you find one.
Different API surfaces on different frameworks
ApiSurface
supports the rare situation of APIs which are different between .NET Framework and .NET Core, or between different versions of the .NET runtime.
Instead of giving the default SurfaceBaseline.txt
file, you can override any given framework with one or more specially-named SurfaceBaseline-FRAMEWORKNAME.txt
files; for example, SurfaceBaseline-Net5.txt
or SurfaceBaseline-NetFramework.txt
.
Note that ApiSurface.writeAssemblyBaseline
will only write a SurfaceBaseline.txt
, and it will only do so for the currently-executing framework.
If you wish to make this specific to .NET Framework or .NET Core, you should then manually rename the file.
For the complete list of supported frameworks and file names, see the private frameworkBaselineFile : string
in the ApiSurface
module.
Fully worked end-to-end example
Within the project file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="SurfaceBaseline.txt" />
<EmbeddedResource Include="version.json" />
</ItemGroup>
</Project>
If you are multi-targetting and you wish for different SurfaceBaseline.txt
files for each target, you should generate SurfaceBaseline
files for each target (renaming them to follow the naming schema as described in the summary of this README), and include them all in the project file.
The version.json file
Add a version.json file to the root of the project, following NerdBank.GitVersioning convention.
Within the unit test project
- Add a reference to
ApiSurface
. - Then add the following files to your test project:
TestSurface.fs
namespace MyLibrary.Test
open NUnit.Framework
open ApiSurface
[<TestFixture>]
module TestSurface =
let assembly = typeof<_ MyLibrary.SomeDefinedType>.Assembly
[<Test>]
let ``Ensure API surface has not been modified`` () =
ApiSurface.assertIdentical assembly
[<Test; Explicit>]
let ``Update API surface`` () =
ApiSurface.writeAssemblyBaseline assembly
[<Test>]
let ``Ensure public API is fully documented`` () =
DocCoverage.assertFullyDocumented assembly
[<Test>]
let ``Ensure version is monotonic`` () =
MonotonicVersion.validate assembly "MyCompany.MyLibraryNuGetPackage"
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FSharp.Core (>= 4.3.4)
- Newtonsoft.Json (>= 13.0.1)
- NuGet.Packaging (>= 5.11.2)
- NuGet.Protocol (>= 5.6.0)
- System.IO.Abstractions (>= 4.2.13)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
4.1.9 | 37 | 11/14/2024 |
4.1.8 | 377 | 10/21/2024 |
4.1.7 | 159 | 10/14/2024 |
4.1.6 | 392 | 10/7/2024 |
4.1.5 | 1,408 | 9/2/2024 |
4.1.4 | 74 | 8/28/2024 |
4.1.3 | 66 | 8/28/2024 |
4.1.2 | 245 | 8/21/2024 |
4.1.1 | 78 | 8/20/2024 |
4.0.44 | 387 | 8/13/2024 |
4.0.43 | 1,050 | 7/8/2024 |
4.0.42 | 146 | 7/1/2024 |
4.0.41 | 956 | 6/10/2024 |
4.0.40 | 2,231 | 5/27/2024 |
4.0.39 | 138 | 5/1/2024 |
4.0.38 | 41 | 5/1/2024 |
4.0.37 | 45 | 5/1/2024 |
4.0.36 | 142 | 4/22/2024 |
4.0.35 | 89 | 4/16/2024 |
4.0.34 | 71 | 4/15/2024 |
4.0.33 | 213 | 2/29/2024 |
4.0.32 | 77 | 2/29/2024 |
4.0.31 | 85 | 2/28/2024 |
4.0.30 | 226 | 2/19/2024 |
4.0.29 | 98 | 2/13/2024 |
4.0.28 | 290 | 2/6/2024 |
4.0.27 | 172 | 1/30/2024 |
4.0.26 | 72 | 1/30/2024 |
4.0.25 | 787 | 12/18/2023 |
4.0.24 | 82 | 12/18/2023 |
4.0.23 | 106 | 12/11/2023 |
4.0.22 | 94 | 12/11/2023 |
4.0.21 | 89 | 12/11/2023 |
4.0.20 | 124 | 11/20/2023 |
4.0.19 | 114 | 11/5/2023 |
4.0.18 | 122 | 10/23/2023 |
4.0.16 | 114 | 10/19/2023 |
4.0.15 | 106 | 10/19/2023 |
4.0.14 | 97 | 10/19/2023 |
4.0.13 | 102 | 10/19/2023 |
4.0.12 | 274 | 6/14/2023 |
4.0.11 | 157 | 5/25/2023 |
4.0.10 | 149 | 5/22/2023 |
4.0.9 | 136 | 5/22/2023 |
4.0.8 | 435 | 4/21/2023 |
4.0.7 | 150 | 4/19/2023 |
4.0.6 | 171 | 4/14/2023 |
4.0.5 | 210 | 3/16/2023 |
4.0.4 | 194 | 3/16/2023 |
4.0.3 | 323 | 12/5/2022 |
4.0.2 | 301 | 12/2/2022 |
4.0.1 | 309 | 11/30/2022 |
3.0.15 | 297 | 11/30/2022 |
3.0.14 | 300 | 11/23/2022 |
3.0.13 | 302 | 11/22/2022 |
3.0.12 | 301 | 11/21/2022 |
3.0.11 | 303 | 11/18/2022 |
3.0.10 | 305 | 11/18/2022 |
3.0.9 | 350 | 11/17/2022 |