Skip to content

Commit c5f723d

Browse files
committed
adjust solution structure
1 parent f963e8f commit c5f723d

File tree

294 files changed

+786
-111
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

294 files changed

+786
-111
lines changed

NetArchTest.eNhancedEdition.sln

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,46 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
44
VisualStudioVersion = 17.3.32819.101
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest", "src\NetArchTest.Rules\NetArchTest.csproj", "{2FDD6DBD-F203-4EC9-9F9B-6771713CC353}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest", "sources\NetArchTest\NetArchTest.csproj", "{2FDD6DBD-F203-4EC9-9F9B-6771713CC353}"
77
EndProject
8-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{660FEA1B-C886-4B72-AD70-1D7DD248CD76}"
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{660FEA1B-C886-4B72-AD70-1D7DD248CD76}"
99
EndProject
10-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.UnitTests", "test\NetArchTest.Rules.UnitTests\NetArchTest.UnitTests.csproj", "{D56F6954-7CCA-41D6-BA81-850F0C81FE3A}"
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.UnitTests", "tests\NetArchTest.Rules.UnitTests\NetArchTest.UnitTests.csproj", "{D56F6954-7CCA-41D6-BA81-850F0C81FE3A}"
1111
EndProject
12-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.TestStructure", "test\NetArchTest.TestStructure\NetArchTest.TestStructure.csproj", "{D91C182D-DC97-4F9B-AFFE-8C7A62501DA6}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.TestStructure", "tests\NetArchTest.TestStructure\NetArchTest.TestStructure.csproj", "{D91C182D-DC97-4F9B-AFFE-8C7A62501DA6}"
1313
EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{460F2EC0-8774-4A26-835C-2FFFCAEEE1FA}"
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.SampleRules", "samples\NetArchTest.SampleRules\NetArchTest.SampleRules.csproj", "{4C5B170E-CAA1-421E-9FA5-9C2D6BEDB27C}"
1717
EndProject
1818
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.SampleLibrary", "samples\NetArchTest.SampleLibrary\NetArchTest.SampleLibrary.csproj", "{7123A8AE-678D-4D14-82E5-EB5607ABDC4A}"
1919
EndProject
20-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.CrossAssemblyTest.A", "test\NetArchTest.CrossAssemblyTest.A\NetArchTest.CrossAssemblyTest.A.csproj", "{70B787F2-8B79-4AA5-8C73-26682A605B6B}"
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.CrossAssemblyTest.A", "tests\NetArchTest.CrossAssemblyTest.A\NetArchTest.CrossAssemblyTest.A.csproj", "{70B787F2-8B79-4AA5-8C73-26682A605B6B}"
2121
EndProject
22-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.CrossAssemblyTest.B", "test\NetArchTest.CrossAssemblyTest.B\NetArchTest.CrossAssemblyTest.B.csproj", "{28692D43-3E08-43E4-BCBB-5940B9F741C6}"
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.CrossAssemblyTest.B", "tests\NetArchTest.CrossAssemblyTest.B\NetArchTest.CrossAssemblyTest.B.csproj", "{28692D43-3E08-43E4-BCBB-5940B9F741C6}"
2323
EndProject
2424
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documentation", "documentation", "{AD4F8A0F-6F5B-45A6-AC8B-822999097CA3}"
2525
ProjectSection(SolutionItems) = preProject
2626
documentation\api.md = documentation\api.md
27-
api.nt = api.nt
27+
documentation\api.nt = documentation\api.nt
2828
readme.md = readme.md
29+
documentation\readme.nt = documentation\readme.nt
2930
EndProjectSection
3031
EndProject
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetArchTest.SampleTests", "samples\NetArchTest.SampleTests\NetArchTest.SampleTests.csproj", "{C86E2D57-4566-4713-88DF-0AA265B0EDAC}"
33+
EndProject
34+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.BuildingBlocks", "samples\SampleApp.BuildingBlocks\SampleApp.BuildingBlocks.csproj", "{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2}"
35+
EndProject
36+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleApp", "SampleApp", "{FD532FD5-BB0C-4731-87A5-747FE1A32FBD}"
37+
EndProject
38+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.API", "samples\SampleApp.API\SampleApp.API.csproj", "{F54503C5-B053-45EF-967C-B625B876ED88}"
39+
EndProject
40+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.ModuleAlpha", "samples\SampleApp.ModuleAlpha\SampleApp.ModuleAlpha.csproj", "{D46D6289-81C2-41D1-B252-0B88BF825660}"
41+
EndProject
42+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.ModuleOmega", "samples\SampleApp.ModuleOmega\SampleApp.ModuleOmega.csproj", "{22600143-A90D-42B5-8FA0-9FEC0E962BCC}"
43+
EndProject
44+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.SharedKernel", "samples\SampleApp.SharedKernel\SampleApp.SharedKernel.csproj", "{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D}"
45+
EndProject
3146
Global
3247
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3348
Debug|Any CPU = Debug|Any CPU
@@ -62,6 +77,30 @@ Global
6277
{28692D43-3E08-43E4-BCBB-5940B9F741C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
6378
{28692D43-3E08-43E4-BCBB-5940B9F741C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
6479
{28692D43-3E08-43E4-BCBB-5940B9F741C6}.Release|Any CPU.Build.0 = Release|Any CPU
80+
{C86E2D57-4566-4713-88DF-0AA265B0EDAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
81+
{C86E2D57-4566-4713-88DF-0AA265B0EDAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
82+
{C86E2D57-4566-4713-88DF-0AA265B0EDAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
83+
{C86E2D57-4566-4713-88DF-0AA265B0EDAC}.Release|Any CPU.Build.0 = Release|Any CPU
84+
{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
85+
{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
86+
{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
87+
{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2}.Release|Any CPU.Build.0 = Release|Any CPU
88+
{F54503C5-B053-45EF-967C-B625B876ED88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
89+
{F54503C5-B053-45EF-967C-B625B876ED88}.Debug|Any CPU.Build.0 = Debug|Any CPU
90+
{F54503C5-B053-45EF-967C-B625B876ED88}.Release|Any CPU.ActiveCfg = Release|Any CPU
91+
{F54503C5-B053-45EF-967C-B625B876ED88}.Release|Any CPU.Build.0 = Release|Any CPU
92+
{D46D6289-81C2-41D1-B252-0B88BF825660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
93+
{D46D6289-81C2-41D1-B252-0B88BF825660}.Debug|Any CPU.Build.0 = Debug|Any CPU
94+
{D46D6289-81C2-41D1-B252-0B88BF825660}.Release|Any CPU.ActiveCfg = Release|Any CPU
95+
{D46D6289-81C2-41D1-B252-0B88BF825660}.Release|Any CPU.Build.0 = Release|Any CPU
96+
{22600143-A90D-42B5-8FA0-9FEC0E962BCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
97+
{22600143-A90D-42B5-8FA0-9FEC0E962BCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
98+
{22600143-A90D-42B5-8FA0-9FEC0E962BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
99+
{22600143-A90D-42B5-8FA0-9FEC0E962BCC}.Release|Any CPU.Build.0 = Release|Any CPU
100+
{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
101+
{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
102+
{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
103+
{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D}.Release|Any CPU.Build.0 = Release|Any CPU
65104
EndGlobalSection
66105
GlobalSection(SolutionProperties) = preSolution
67106
HideSolutionNode = FALSE
@@ -73,6 +112,13 @@ Global
73112
{7123A8AE-678D-4D14-82E5-EB5607ABDC4A} = {460F2EC0-8774-4A26-835C-2FFFCAEEE1FA}
74113
{70B787F2-8B79-4AA5-8C73-26682A605B6B} = {660FEA1B-C886-4B72-AD70-1D7DD248CD76}
75114
{28692D43-3E08-43E4-BCBB-5940B9F741C6} = {660FEA1B-C886-4B72-AD70-1D7DD248CD76}
115+
{C86E2D57-4566-4713-88DF-0AA265B0EDAC} = {460F2EC0-8774-4A26-835C-2FFFCAEEE1FA}
116+
{4E5A47CB-2F0B-4F7B-B898-D8BD2B8797C2} = {FD532FD5-BB0C-4731-87A5-747FE1A32FBD}
117+
{FD532FD5-BB0C-4731-87A5-747FE1A32FBD} = {460F2EC0-8774-4A26-835C-2FFFCAEEE1FA}
118+
{F54503C5-B053-45EF-967C-B625B876ED88} = {FD532FD5-BB0C-4731-87A5-747FE1A32FBD}
119+
{D46D6289-81C2-41D1-B252-0B88BF825660} = {FD532FD5-BB0C-4731-87A5-747FE1A32FBD}
120+
{22600143-A90D-42B5-8FA0-9FEC0E962BCC} = {FD532FD5-BB0C-4731-87A5-747FE1A32FBD}
121+
{674DBCB9-5F7E-45A1-9862-1CDA64C83B3D} = {FD532FD5-BB0C-4731-87A5-747FE1A32FBD}
76122
EndGlobalSection
77123
GlobalSection(ExtensibilityGlobals) = postSolution
78124
SolutionGuid = {4388262D-A716-4918-A629-6072E4F8B668}

README.md

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![net-workflow](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/actions/workflows/net-workflow.yml/badge.svg?branch=main)](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/actions/workflows/net-workflow.yml)
1+
[![net-workflow](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/actions/workflows/net-workflow.yml/badge.svg?branch=main)](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/actions/workflows/net-workflow.yml)
22
[![Nuget](https://img.shields.io/nuget/v/NetArchTest.eNhancedEdition?color=%23004880&label=NetArchTest.eNhancedEdition%20nuget)](https://www.nuget.org/packages/NetArchTest.eNhancedEdition)
33

44
# NetArchTest.eNhancedEdition
@@ -43,14 +43,14 @@ What **eNhancedEdition** has to offer, that is not available in the NetArchTest
4343
* [Options](#options)
4444
* [Limitations](#limitations)
4545
* API
46-
* [Types](documentation/api.md#types)
47-
* [Predicate](documentation/api.md#predicate)
48-
* [PredicateList](documentation/api.md#predicateList)
49-
* [Condition](documentation/api.md#condition)
50-
* [ConditionList](documentation/api.md#conditionList)
51-
* [TestResult](documentation/api.md#testResult)
52-
* [IType](documentation/api.md#itype)
53-
* [Options](documentation/api.md#options)
46+
* [Types](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#types)
47+
* [Predicate](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#predicate)
48+
* [PredicateList](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#predicateList)
49+
* [Condition](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#condition)
50+
* [ConditionList](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#conditionList)
51+
* [TestResult](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#testResult)
52+
* [IType](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#itype)
53+
* [Options](https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/main/documentation/api.md#options)
5454

5555

5656

@@ -61,37 +61,39 @@ The library is available as a package on NuGet: [NetArchTest.eNhancedEdition](ht
6161
### Examples
6262

6363
```csharp
64-
static readonly Assembly TestCreationAssembly = typeof(Foo).Assembly;
65-
66-
[TestMethod]
67-
public void DomainIsNotAccessibleFromOutsideOfModule()
64+
[TestClass]
65+
public class SampleApp_ModuleAlpha_Tests
6866
{
69-
var result = Types.InAssembly(AssemblyUnderTest)
70-
.That()
71-
.ResideInNamespace("MyApp.Domain")
72-
.And()
73-
.DoNotHaveNameEndingWith("Const")
74-
.Should()
75-
.NotBePublic()
76-
.GetResult();
77-
Assert.IsTrue(result.IsSuccessful);
78-
}
79-
80-
[TestMethod]
81-
public void DomainIsIndependent()
82-
{
83-
var result = Types.InAssembly(AssemblyUnderTest)
84-
.That()
85-
.ResideInNamespace("MyApp.Domain")
86-
.ShouldNot()
87-
.HaveDependencyOtherThan(
88-
"System",
89-
"MyApp.SharedKernel.Domain",
90-
"MyApp.BuildingBlocks.Domain"
91-
)
92-
.GetResult();
93-
94-
Assert.IsTrue(result.IsSuccessful, "Domain has lost its independence!");
67+
static readonly Assembly AssemblyUnderTest = typeof(SampleApp.ModuleAlpha.TestUtils).Assembly;
68+
[TestMethod]
69+
public void PersistenceIsNotAccessibleFromOutsideOfModuleExceptOfDbContext()
70+
{
71+
var result = Types.InAssembly(AssemblyUnderTest)
72+
.That()
73+
.ResideInNamespace("SampleApp.ModuleAlpha.Persistence")
74+
.And()
75+
.DoNotHaveNameEndingWith("DbContext")
76+
.Should()
77+
.NotBePublic()
78+
.GetResult();
79+
Assert.IsTrue(result.IsSuccessful);
80+
}
81+
[TestMethod]
82+
public void DomainIsIndependent()
83+
{
84+
var result = Types.InAssembly(AssemblyUnderTest)
85+
.That()
86+
.ResideInNamespace("SampleApp.ModuleAlpha.Domain")
87+
.ShouldNot()
88+
.HaveDependencyOtherThan(
89+
"System",
90+
"SampleApp.ModuleAlpha.Domain",
91+
"SampleApp.SharedKernel.Domain",
92+
"SampleApp.BuildingBlocks.Domain"
93+
)
94+
.GetResult();
95+
Assert.IsTrue(result.IsSuccessful, "Domain has lost its independence!");
96+
}
9597
}
9698
```
9799

@@ -108,15 +110,15 @@ var types = Types.InAssembly(typeof(MyClass).Assembly);
108110
```
109111
Once you have selected the types you can filter them using one or more predicates. These can be chained together using `And()` or `Or()` conjunctions:
110112
```csharp
111-
types.That().ResideInNamespace(MyProject.Data);
113+
types.That().ResideInNamespace("MyProject.Data");
112114
```
113115
Once the set of classes have been filtered you can apply a set of conditions using the `Should()` or `ShouldNot()` methods, e.g.
114116
```csharp
115-
types.That().ResideInNamespace(MyProject.Data).Should().BeSealed();
117+
types.That().ResideInNamespace("MyProject.Data").Should().BeSealed();
116118
```
117119
Finally, you obtain a result from the rule by using an executor, i.e. use `GetTypes()` to return the types that match the rule or `GetResult()` to determine whether the rule has been met. Note that the result will also return a list of types that failed to meet the conditions.
118120
```csharp
119-
var result = types.That().ResideInNamespace(MyProject.Data).Should().BeSealed().GetResult();
121+
var result = types.That().ResideInNamespace("MyProject.Data").Should().BeSealed().GetResult();
120122
var isValid = result.IsSuccessful;
121123
var types = result.FailingTypes;
122124
```
@@ -170,13 +172,13 @@ There is only one way, at least for now, to divide types into slices `ByNamespac
170172
`namespacePrefix.(sliceName).restOfNamespace`
171173
3) Types with the same `sliceName` part will be placed in the same slice. If `sliceName` is empty for a given type, the type will be also ignored (`BaseFeature` class from folowing image)
172174

173-
![Slices](documentation/slices/slices.png)
175+
![Slices](https://raw.githubusercontent.com/NeVeSpl/NetArchTest.eNhancedEdition/main/documentation/slices/slices.png)
174176

175177
When we already have our types divided into slices, we can apply condition: `NotHaveDependenciesBetweenSlices()`. As the name suggest it detects if any dependency exists between slices. Dependency from slice to type that is not part of any other slice is allowed.
176178

177179
passing | failing
178180
--|---
179-
![Slices](documentation/slices/slices.ok.png)|![Slices](documentation/slices/slices.not.png)
181+
![Slices](https://raw.githubusercontent.com/NeVeSpl/NetArchTest.eNhancedEdition/main/documentation/slices/slices.ok.png)|![Slices](https://raw.githubusercontent.com/NeVeSpl/NetArchTest.eNhancedEdition/main/documentation/slices/slices.not.png)
180182

181183

182184
## Custom rules
@@ -220,3 +222,4 @@ Available options:
220222

221223
NetArchTest is build on top of [jbevain/cecil](https://github.com/jbevain/cecil) thus it works on CLI level. Unfortunately not every feature of C# language is represented in CLI, thus some things will never be available in NetArchTest, e.g.:
222224
- BenMorris/NetArchTest#81 - NetArchTest ignores a nameof expression
225+

api.nt

Lines changed: 0 additions & 57 deletions
This file was deleted.

documentation/api.nt

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,57 @@
1-

1+
{{- config.AddGeneratedFilesToVSProject = false
2+
capture output
3+
types_type = data.Classes | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^Types$"
4+
predicate_type = data.Classes | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^Predicate"
5+
condition_type = data.Classes | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^Condition"
6+
testresult_type = data.Classes | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^TestResult"
7+
itype_type = data.Interfaces | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^IType"
8+
options_type = data.Classes | Symbols.WhereNamespaceStartsWith "NetArchTest.Rules" | Symbols.WhereNameMatches "^Options"
9+
10+
all_types = types_type | Array.Concat predicate_type | Array.Concat condition_type | Array.Concat testresult_type | Array.Concat itype_type | Array.Concat options_type
11+
}}
12+
13+
14+
{{- for type in all_types }}
15+
## {{ type.Name }}
16+
17+
{{- for method in type.Methods | Symbols.ThatArePublic | Symbols.ThatAreStatic | Array.Sort "Name" }}
18+
- [{{method.Name}}](#{{type.BareName}}{{method.BareName}})
19+
{{- end }}
20+
{{~ for method in type.Methods | Symbols.ThatArePublic | Symbols.ThatAreNotStatic | Array.Sort "Name" }}
21+
* [{{method.Name}}](#{{type.BareName}}{{method.BareName}})
22+
{{- end }}
23+
{{- for prop in type.Properties | Symbols.ThatArePublic | Symbols.ThatAreNotStatic | Array.Sort "Name" }}
24+
* [{{prop.Name}}](#{{type.BareName}}{{prop.BareName}})
25+
{{- end }}
26+
{{ end}}
27+
28+
29+
30+
{{- for type in all_types }}
31+
## {{ type.Name }}
32+
33+
{{- for method in type.Methods | Symbols.ThatArePublic | Array.Sort "Name" }}
34+
### {{type.BareName}}.{{method.Name}}
35+
```csharp
36+
{{method.FullName}}
37+
```
38+
{{ method.DocComment.Summary | String.StripNewlines }}
39+
{{- end }}
40+
41+
{{- for prop in type.Properties | Symbols.ThatArePublic | Symbols.ThatAreNotStatic | Array.Sort "Name" }}
42+
### {{type.BareName}}.{{prop.Name}}
43+
```csharp
44+
{{prop.FullName}}
45+
```
46+
{{~ prop.DocComment.Summary | String.StripNewlines }}
47+
{{- end }}
48+
{{ end}}
49+
50+
51+
52+
53+
54+
{{
55+
end
56+
Save output "api.md"
57+
-}}

0 commit comments

Comments
 (0)