diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index e8ed1b0..3941cf5 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -17,14 +17,17 @@ env: jobs: build-cli: name: Build CLI (${{ matrix.rid }}) - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - rid: win-x64 + os: windows-latest - rid: linux-x64 + os: ubuntu-latest - rid: osx-x64 + os: macos-latest steps: - uses: actions/checkout@v3 - name: Setup .NET Core @@ -35,4 +38,17 @@ jobs: run: dotnet test --configuration release src/BicepDocs.sln - name: Build binary run: dotnet publish --configuration release --self-contained true -p:PublishTrimmed=true -p:PublishSingleFile=true -p:TrimmerDefaultAction=copyused -p:SuppressTrimAnalysisWarnings=true -r ${{ matrix.rid }} ./src/BicepDocs.Cli/BicepDocs.Cli.csproj - + - name: Test samples + if: matrix.rid != 'win-x64' + run: | + mv ./src/BicepDocs.Cli/bin/release/net6.0/${{ matrix.rid }}/publish/bicepdocs . + ./bicepdocs generate filesystem \ + --folderPath docs/formatters/examples/inputs \ + --out ./docs/formatters/examples/generated-output/markdown \ + --config docs/example-config.yml \ + --formatter markdown + - name: Test samples (win) + if: matrix.rid == 'win-x64' + run: | + mv .\src\BicepDocs.Cli\bin\release\net6.0\${{ matrix.rid }}\publish\bicepdocs.exe . + .\bicepdocs.exe generate filesystem --folderPath docs\formatters\examples\inputs --out .\docs\formatters\examples\generated-output\markdown --config docs\example-config.yml --formatter markdown \ No newline at end of file diff --git a/src/BicepDocs.Core.UnitTests/BicepFileTestBase.cs b/src/BicepDocs.Core.UnitTests/BicepFileTestBase.cs index c97d9f0..efab399 100644 --- a/src/BicepDocs.Core.UnitTests/BicepFileTestBase.cs +++ b/src/BicepDocs.Core.UnitTests/BicepFileTestBase.cs @@ -1,6 +1,7 @@ using System.IO.Abstractions; using Bicep.Core; using Bicep.Core.Semantics; +using LandingZones.Tools.BicepDocs.Core.Extensions; using Microsoft.Extensions.DependencyInjection; namespace LandingZones.Tools.BicepDocs.Core.UnitTests; @@ -27,11 +28,11 @@ protected async Task GetModelFromPath(string filePath) protected async Task GetModel(string fileContent, string fileName = "deploy.bicep") { - var vPath = Path.Join("/modules", fileName); - FileSystem.Directory.CreateDirectory("/modules"); + var vPath = Path.Join("/modules", fileName).ToPlatformPath(); + FileSystem.Directory.CreateDirectory("/modules".ToPlatformPath()); await FileSystem.File.WriteAllTextAsync(vPath, fileContent); var compiler = ServiceProvider.GetRequiredService(); - var compilation = await compiler.CreateCompilation(new Uri(vPath)); + var compilation = await compiler.CreateCompilation(PathResolver.FilePathToUri(vPath)); return compilation.GetEntrypointSemanticModel(); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core.UnitTests/Models/GenerationFileTests.cs b/src/BicepDocs.Core.UnitTests/Models/GenerationFileTests.cs index f404ffa..1c07002 100644 --- a/src/BicepDocs.Core.UnitTests/Models/GenerationFileTests.cs +++ b/src/BicepDocs.Core.UnitTests/Models/GenerationFileTests.cs @@ -1,3 +1,4 @@ +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; namespace LandingZones.Tools.BicepDocs.Core.UnitTests.Models; @@ -8,19 +9,20 @@ public class GenerationFileTests [TestMethod] public void GenerationFile_ValidPath_ReturnsFolder() { - var ctx = new TextGenerationFile("/some/path/here/deploy.bicep", ""); - Assert.AreEqual("/some/path/here", ctx.FolderPath); + var ctx = new TextGenerationFile("/some/path/here/deploy.bicep".ToPlatformPath(), ""); + Assert.AreEqual("/some/path/here".ToPlatformPath(), ctx.FolderPath); } [TestMethod] public void GenerationFile_VersionString_SetsProperties() { - var ctx = new DemoGenFile("/some/path/here/deploy.bicep", "/some/path/here/version/deploy.bicep"); - Assert.AreEqual("/some/path/here", ctx.FolderPath); - Assert.AreEqual("/some/path/here/deploy.bicep", ctx.FilePath); + var ctx = new DemoGenFile("/some/path/here/deploy.bicep".ToPlatformPath(), "/some/path/here/version/deploy.bicep" + .ToPlatformPath()); + Assert.AreEqual("/some/path/here".ToPlatformPath(), ctx.FolderPath); + Assert.AreEqual("/some/path/here/deploy.bicep".ToPlatformPath(), ctx.FilePath); - Assert.AreEqual("/some/path/here/version", ctx.VersionFolderPath); - Assert.AreEqual("/some/path/here/version/deploy.bicep", ctx.VersionFilePath); + Assert.AreEqual("/some/path/here/version".ToPlatformPath(), ctx.VersionFolderPath); + Assert.AreEqual("/some/path/here/version/deploy.bicep".ToPlatformPath(), ctx.VersionFilePath); } class DemoGenFile : GenerationFile @@ -29,4 +31,4 @@ public DemoGenFile(string filePath, string? versionFilePath = null) : base(fileP { } } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core.UnitTests/PathResolverTests.cs b/src/BicepDocs.Core.UnitTests/PathResolverTests.cs index 5fcb18d..08acff7 100644 --- a/src/BicepDocs.Core.UnitTests/PathResolverTests.cs +++ b/src/BicepDocs.Core.UnitTests/PathResolverTests.cs @@ -1,29 +1,29 @@ +using LandingZones.Tools.BicepDocs.Core.Extensions; + namespace LandingZones.Tools.BicepDocs.Core.UnitTests; [TestClass] public class PathResolverTests { - [DataTestMethod] - [DataRow("./docs/somefolder","/root","/root/docs/somefolder")] - [DataRow("/root/docs/somefolder","/root","/root/docs/somefolder")] - [DataRow("../docs/somefolder","/root/mypath","/root/docs/somefolder")] + [DataRow("./docs/somefolder", "/root", "/root/docs/somefolder")] + [DataRow("/root/docs/somefolder", "/root", "/root/docs/somefolder")] + [DataRow("../docs/somefolder", "/root/mypath", "/root/docs/somefolder")] public void ResolvePath_Input_Resolves(string input, string baseDirectory, string expected) { - var resolved = PathResolver.ResolvePath(input, baseDirectory); - - Assert.AreEqual(expected, resolved); + var resolved = PathResolver.ResolvePath(input.ToPlatformPath(), baseDirectory.ToPlatformPath()); + Assert.AreEqual(Path.Combine(Path.GetPathRoot(resolved)!, expected.TrimStart('/').ToPlatformPath()), resolved); } - + [TestMethod] public void PathResolver_ResolveModulePaths_Resolves() { - var inputFolder = "/input/folder/modules"; - var outputBaseFolder = "/output-folder/some-dir/docs"; - var outputFolder = "/output-folder/some-dir/docs/vaults"; - var inputFile = "/input/folder/modules/vaults/vault.bicep"; - var relativeInputPath = "/vaults/vault.bicep"; - var outputPath = "/output-folder/some-dir/docs/vaults/vault.md"; + var inputFolder = "/input/folder/modules".ToPlatformPath(); + var outputBaseFolder = "/output-folder/some-dir/docs".ToPlatformPath(); + var outputFolder = "/output-folder/some-dir/docs/vaults".ToPlatformPath(); + var inputFile = "/input/folder/modules/vaults/vault.bicep".ToPlatformPath(); + var relativeInputPath = "/vaults/vault.bicep".ToPlatformPath(); + var outputPath = "/output-folder/some-dir/docs/vaults/vault.md".ToPlatformPath(); var resolved = PathResolver.ResolveModulePaths( bicepFilePath: inputFile, baseInputFolder: inputFolder, @@ -36,17 +36,17 @@ public void PathResolver_ResolveModulePaths_Resolves() Assert.AreEqual(outputFolder, resolved.OutputFolder); Assert.AreEqual(outputBaseFolder, resolved.OutputBaseFolder); Assert.AreEqual(relativeInputPath, resolved.RelativeInputPath); - Assert.AreEqual("/modules/vaults/vault.bicep", resolved.VirtualPath); - Assert.AreEqual("/modules/vaults", resolved.VirtualFolder); + Assert.AreEqual("/modules/vaults/vault.bicep".ToPlatformPath(), resolved.VirtualPath); + Assert.AreEqual("/modules/vaults".ToPlatformPath(), resolved.VirtualFolder); Assert.AreEqual(outputPath, resolved.OutputPath); } [TestMethod] public void PathResolver_ResolveVersionPath_Resolves() { - var inputFolder = "/input/folder/modules"; - var outputBaseFolder = "/output-folder/some-dir/docs"; - var inputFile = "/input/folder/modules/vaults/role-assignments/vault-rbac.bicep"; + var inputFolder = "/input/folder/modules".ToPlatformPath(); + var outputBaseFolder = "/output-folder/some-dir/docs".ToPlatformPath(); + var inputFile = "/input/folder/modules/vaults/role-assignments/vault-rbac.bicep".ToPlatformPath(); var modulePaths = PathResolver.ResolveModulePaths( bicepFilePath: inputFile, baseInputFolder: inputFolder, @@ -54,7 +54,7 @@ public void PathResolver_ResolveVersionPath_Resolves() var filePaths = PathResolver.ResolveVersionPath(modulePaths, "2022-12-18"); - Assert.AreEqual("/output-folder/some-dir/docs/vaults/versions/2022-12-18/role-assignments/vault-rbac.md", filePaths.OutputPath); - Assert.AreEqual("/output-folder/some-dir/docs/vaults/versions/2022-12-18/role-assignments", filePaths.OutputFolder); + Assert.AreEqual("/output-folder/some-dir/docs/vaults/versions/2022-12-18/role-assignments/vault-rbac.md".ToPlatformPath(), filePaths.OutputPath); + Assert.AreEqual("/output-folder/some-dir/docs/vaults/versions/2022-12-18/role-assignments".ToPlatformPath(), filePaths.OutputFolder); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core.UnitTests/Services/BicepFileServiceTests.cs b/src/BicepDocs.Core.UnitTests/Services/BicepFileServiceTests.cs index 77b8020..7291025 100644 --- a/src/BicepDocs.Core.UnitTests/Services/BicepFileServiceTests.cs +++ b/src/BicepDocs.Core.UnitTests/Services/BicepFileServiceTests.cs @@ -27,4 +27,4 @@ param resourceGroupName string Assert.IsNotNull(res); Assert.AreEqual(1, res.AllResources.Length); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core.UnitTests/TestExtensions.cs b/src/BicepDocs.Core.UnitTests/TestExtensions.cs new file mode 100644 index 0000000..8f19b99 --- /dev/null +++ b/src/BicepDocs.Core.UnitTests/TestExtensions.cs @@ -0,0 +1,14 @@ +using LandingZones.Tools.BicepDocs.Core.Extensions; + +namespace LandingZones.Tools.BicepDocs.Core.UnitTests +{ + public static class TestExtensions + { + public static string ToPlatformLineEndings(this string text) + { + return text.Contains("\r\n") ? text.Replace("\r\n", "\n") : text.Replace("\n", Environment.NewLine).Replace("\r", Environment.NewLine); + } + + public static string WithPlatformRootPath(this string text) => Path.Combine(Path.GetPathRoot(Environment.CurrentDirectory)!, text.TrimStart('/').TrimStart('\\').ToPlatformPath()); + } +} diff --git a/src/BicepDocs.Core/Extensions/StringExtensions.cs b/src/BicepDocs.Core/Extensions/StringExtensions.cs index 432de60..51a9f4a 100644 --- a/src/BicepDocs.Core/Extensions/StringExtensions.cs +++ b/src/BicepDocs.Core/Extensions/StringExtensions.cs @@ -7,6 +7,11 @@ public static string Repeat(this string text, int count) return string.Concat(Enumerable.Repeat(text, count)); } + public static string ToPlatformPath(this string path) + { + return path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar); + } + public static string FirstCharToUpper(this string? input) => input switch { @@ -14,4 +19,4 @@ public static string FirstCharToUpper(this string? input) => "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)), _ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1)) }; -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core/Models/Formatting/GenerationFile.cs b/src/BicepDocs.Core/Models/Formatting/GenerationFile.cs index 16d1821..17a7d0e 100644 --- a/src/BicepDocs.Core/Models/Formatting/GenerationFile.cs +++ b/src/BicepDocs.Core/Models/Formatting/GenerationFile.cs @@ -1,10 +1,12 @@ +using LandingZones.Tools.BicepDocs.Core.Extensions; + namespace LandingZones.Tools.BicepDocs.Core.Models.Formatting; public abstract class GenerationFile { protected GenerationFile(string filePath, string? versionFilePath = null) { - FilePath = filePath; + FilePath = filePath.ToPlatformPath(); FolderPath = Path.GetDirectoryName(filePath) ?? throw new ArgumentException("Failed to resolve folder path"); if (!string.IsNullOrEmpty(versionFilePath)) @@ -35,4 +37,4 @@ protected GenerationFile(string filePath, string? versionFilePath = null) /// Base folder of /// public string? VersionFolderPath { get; } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Core/PathResolver.cs b/src/BicepDocs.Core/PathResolver.cs index a277995..70889e2 100644 --- a/src/BicepDocs.Core/PathResolver.cs +++ b/src/BicepDocs.Core/PathResolver.cs @@ -1,10 +1,11 @@ +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; namespace LandingZones.Tools.BicepDocs.Core; public static class PathResolver { - private const string VirtualBasePath = "/modules"; + private const string VirtualBasePath = "modules"; private const string VersionsBasePath = "versions"; public static string ResolvePath(string path, string? baseDirectory = null) @@ -22,7 +23,7 @@ public static ModuleVersionPaths ResolveVersionPath(ModulePaths modulePaths, str { var relativeOutput = Path.GetRelativePath(modulePaths.OutputBaseFolder, modulePaths.OutputFolder); var root = relativeOutput.Split(Path.DirectorySeparatorChar); - var newPath = Path.Join(root.First(), VersionsBasePath, version, + var newPath = Path.Join(root.First(), Path.DirectorySeparatorChar.ToString(), VersionsBasePath, version, string.Join(Path.DirectorySeparatorChar, root.Skip(1))); return new ModuleVersionPaths(OutputFolder: Path.Join(modulePaths.OutputBaseFolder, newPath), @@ -37,8 +38,8 @@ public static ModulePaths ResolveModulePaths(string bicepFilePath, string baseIn var outputPathMd = Path.ChangeExtension(outputPath, "md"); return new ModulePaths( RelativeInputPath: modulePath, - VirtualPath: Path.Join(VirtualBasePath, modulePath), - VirtualFolder: Path.Join(VirtualBasePath, Path.GetDirectoryName(modulePath)), + VirtualPath: Path.Join(Path.DirectorySeparatorChar.ToString(),VirtualBasePath, modulePath), + VirtualFolder: Path.Join(Path.DirectorySeparatorChar.ToString(),VirtualBasePath, Path.GetDirectoryName(modulePath)), BaseFileName: Path.GetFileNameWithoutExtension(bicepFilePath), InputFolder: baseInputFolder, OutputBaseFolder: outputFolder, @@ -49,4 +50,11 @@ public static ModulePaths ResolveModulePaths(string bicepFilePath, string baseIn OutputPath: outputPathMd ); } -} \ No newline at end of file + + public static Uri FilePathToUri(string path) => new UriBuilder + { + Scheme = "file", + Host = null, + Path = path.ToPlatformPath(), + }.Uri; +} diff --git a/src/BicepDocs.Core/Services/BicepFileService.cs b/src/BicepDocs.Core/Services/BicepFileService.cs index 8866a0b..13db540 100644 --- a/src/BicepDocs.Core/Services/BicepFileService.cs +++ b/src/BicepDocs.Core/Services/BicepFileService.cs @@ -20,8 +20,8 @@ public async Task GetSemanticModelFromContent(string folder, stri { _fileSystem.Directory.CreateDirectory(folder); await _fileSystem.File.WriteAllTextAsync(path, content); - var compilation = await _compiler.CreateCompilation(new Uri(path)); + var compilation = await _compiler.CreateCompilation(PathResolver.FilePathToUri(path)); var sourceFile = compilation.GetEntrypointSemanticModel(); return sourceFile; } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Destination.FileSystem.UnitTests/FileSystemDestinationTests.cs b/src/BicepDocs.Destination.FileSystem.UnitTests/FileSystemDestinationTests.cs index 00e2ca4..56e5cc0 100644 --- a/src/BicepDocs.Destination.FileSystem.UnitTests/FileSystemDestinationTests.cs +++ b/src/BicepDocs.Destination.FileSystem.UnitTests/FileSystemDestinationTests.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using System.IO.Abstractions; using LandingZones.Tools.BicepDocs.Core.Abstractions; +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -23,7 +24,7 @@ public void Write_InvalidGenerationFileType_Throws() var sut = new FileSystemDestination(new NullLogger(), _fileSystemMock.Object); var files = new List() { - new DummyGenFile("/somewhere/folder/deploy.md") + new DummyGenFile("/somewhere/folder/deploy.md".ToPlatformPath()) }.ToImmutableList(); Assert.ThrowsExceptionAsync(() => sut.Write(files)); @@ -32,15 +33,15 @@ public void Write_InvalidGenerationFileType_Throws() [TestMethod] public async Task Write_NoVersion_WritesSingleFile() { - _fileSystemMock.Setup(x => x.Directory.Exists("/somewhere/folder")).Returns(true); + _fileSystemMock.Setup(x => x.Directory.Exists("/somewhere/folder".ToPlatformPath())).Returns(true); _fileSystemMock - .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md", It.IsAny(), + .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md".ToPlatformPath(), It.IsAny(), It.IsAny())).Returns(Task.CompletedTask); var sut = new FileSystemDestination(new NullLogger(), _fileSystemMock.Object); var files = new List() { - new TextGenerationFile("/somewhere/folder/deploy.md", "hello-there") + new TextGenerationFile("/somewhere/folder/deploy.md".ToPlatformPath(), "hello-there") }.ToImmutableList(); await sut.Write(files); @@ -55,16 +56,16 @@ public async Task Write_WithVersion_WritesMultipleFiles() { _fileSystemMock.Setup(x => x.Directory.Exists(It.IsAny())).Returns(true); _fileSystemMock - .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md", It.IsAny(), + .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md".ToPlatformPath(), It.IsAny(), It.IsAny())).Returns(Task.CompletedTask); _fileSystemMock - .Setup(x => x.File.WriteAllTextAsync("/somewhere/v1/folder/deploy.md", It.IsAny(), + .Setup(x => x.File.WriteAllTextAsync("/somewhere/v1/folder/deploy.md".ToPlatformPath(), It.IsAny(), It.IsAny())).Returns(Task.CompletedTask); var sut = new FileSystemDestination(new NullLogger(), _fileSystemMock.Object); var files = new List() { - new TextGenerationFile("/somewhere/folder/deploy.md", "hello-there", "/somewhere/v1/folder/deploy.md") + new TextGenerationFile("/somewhere/folder/deploy.md".ToPlatformPath(), "hello-there", "/somewhere/v1/folder/deploy.md".ToPlatformPath()) }.ToImmutableList(); await sut.Write(files); @@ -77,16 +78,16 @@ public async Task Write_WithVersion_WritesMultipleFiles() [TestMethod] public async Task Write_OutDirectoryDoesNotExist_CreatesDirectory() { - _fileSystemMock.Setup(x => x.Directory.Exists("/somewhere/folder")).Returns(false); - _fileSystemMock.Setup(x => x.Directory.CreateDirectory("/somewhere/folder")).Returns((IDirectoryInfo)null!); + _fileSystemMock.Setup(x => x.Directory.Exists("/somewhere/folder".ToPlatformPath())).Returns(false); + _fileSystemMock.Setup(x => x.Directory.CreateDirectory("/somewhere/folder".ToPlatformPath())).Returns((IDirectoryInfo)null!); _fileSystemMock - .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md", It.IsAny(), + .Setup(x => x.File.WriteAllTextAsync("/somewhere/folder/deploy.md".ToPlatformPath(), It.IsAny(), It.IsAny())).Returns(Task.CompletedTask); var sut = new FileSystemDestination(new NullLogger(), _fileSystemMock.Object); var files = new List() { - new TextGenerationFile("/somewhere/folder/deploy.md", "hello-there") + new TextGenerationFile("/somewhere/folder/deploy.md".ToPlatformPath(), "hello-there") }.ToImmutableList(); await sut.Write(files); @@ -102,4 +103,4 @@ public DummyGenFile(string filePath, string? versionFilePath = null) : base(file { } } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Formatter.Docusaurus.UnitTests/DocusaurusDocsFormatterTests.cs b/src/BicepDocs.Formatter.Docusaurus.UnitTests/DocusaurusDocsFormatterTests.cs index 36e448d..fb0d672 100644 --- a/src/BicepDocs.Formatter.Docusaurus.UnitTests/DocusaurusDocsFormatterTests.cs +++ b/src/BicepDocs.Formatter.Docusaurus.UnitTests/DocusaurusDocsFormatterTests.cs @@ -1,5 +1,6 @@ using LandingZones.Tools.BicepDocs.Core; using LandingZones.Tools.BicepDocs.Core.Abstractions; +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using LandingZones.Tools.BicepDocs.Core.UnitTests; using LandingZones.Tools.BicepDocs.Formatter.Docusaurus.Models.Markdown; @@ -49,7 +50,7 @@ param resourceGroupName string var files = await sut.GenerateModuleDocs(ctx); Assert.AreEqual(2, files.Count); var otp = files[0]; - Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md", otp.FilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md".ToPlatformPath(), otp.FilePath); Assert.IsNull(otp.VersionFilePath); Assert.IsNull(otp.VersionFolderPath); @@ -62,7 +63,7 @@ param resourceGroupName string Assert.IsInstanceOfType(meta, typeof(TextGenerationFile)); Assert.AreEqual(@"{ ""label"": ""Resources"" -}", (meta as TextGenerationFile)?.Content); +}".ReplaceLineEndings(), (meta as TextGenerationFile)?.Content); } [TestMethod] @@ -101,7 +102,7 @@ param resourceGroupName string var files = await sut.GenerateModuleDocs(ctx); Assert.AreEqual(2, files.Count); var otp = files[0]; - Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md", otp.FilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md".ToPlatformPath(), otp.FilePath); var mdFile = otp as MarkdownGenerationFile; Assert.IsNotNull(mdFile); var firstElement = mdFile.Document[0]; @@ -110,12 +111,12 @@ param resourceGroupName string private ModulePaths GetPaths() { - var inputFolder = "/input/folder/modules"; - var outputBaseFolder = "/output-folder/some-dir/docs"; - var inputFile = "/input/folder/modules/resources/resourceGroups.bicep"; + var inputFolder = "/input/folder/modules".ToPlatformPath(); + var outputBaseFolder = "/output-folder/some-dir/docs".ToPlatformPath(); + var inputFile = "/input/folder/modules/resources/resourceGroups.bicep".ToPlatformPath(); return PathResolver.ResolveModulePaths( bicepFilePath: inputFile, baseInputFolder: inputFolder, outputFolder: outputBaseFolder); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/OutputGeneratorTests.cs b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/OutputGeneratorTests.cs index c34e168..c21d517 100644 --- a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/OutputGeneratorTests.cs +++ b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/OutputGeneratorTests.cs @@ -14,11 +14,11 @@ public class OutputGeneratorTests : BicepFileTestBase [TestMethod] public void BuildOutputs_Input_BuildsCorrectly() { - const string expected = @"## Outputs + var expected = @"## Outputs | Name | Type | Description | | --- | --- | --- | -| `resourceId` | string | The resource id of the resource |"; +| `resourceId` | string | The resource id of the resource |".ToPlatformLineEndings(); var outputs = new List { new("resourceId", "string", "The resource id of the resource") @@ -37,13 +37,14 @@ public void BuildOutputs_Input_BuildsCorrectly() [TestMethod] public async Task BuildOutputs_DisabledInOptions_DoesNotGenerate() { - const string template = @"resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' = { + var template = @"resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' = { name: resourceGroupName location: resourceGroupLocation tags: tags } -output resourceId string = resourceGroup.id"; +output resourceId string = resourceGroup.id".ToPlatformLineEndings(); + ; var semanticModel = await GetModel(template); var document = new MarkdownDocument(); var ctx = new FormatterContext(semanticModel, TestConstants.GetMockModulePaths(), new FormatterOptions @@ -58,11 +59,11 @@ public async Task BuildOutputs_DisabledInOptions_DoesNotGenerate() [TestMethod] public async Task BuildOutputs_TemplateInput_Generates() { - const string expected = @"## Outputs + var expected = @"## Outputs | Name | Type | Description | | --- | --- | --- | -| `resourceId` | string | The resource id of the resource |"; +| `resourceId` | string | The resource id of the resource |".ToPlatformLineEndings();; const string template = @"resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' = { name: resourceGroupName location: resourceGroupLocation diff --git a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ParameterGeneratorTests.cs b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ParameterGeneratorTests.cs index 1c9f41d..ab89a62 100644 --- a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ParameterGeneratorTests.cs +++ b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ParameterGeneratorTests.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using LandingZones.Tools.BicepDocs.Core.Models.Parsing; +using LandingZones.Tools.BicepDocs.Core.UnitTests; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Elements; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Generators; @@ -57,7 +58,7 @@ public void BuildParameters_DecoratorSet_BuildsCorrectly(int? minValue, int? max | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | string {expectedDesc} | |"; +| `location` | The location of the resource | string {expectedDesc} | |".ToPlatformLineEndings();; var parameters = new List { @@ -85,11 +86,11 @@ public void BuildParameters_DecoratorSet_BuildsCorrectly(int? minValue, int? max [TestMethod] public void BuildParameters_SimpleParameterType_BuildsCorrectly() { - const string expected = @"## Parameters + var expected = @"## Parameters | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | string | |"; +| `location` | The location of the resource | string | |".ToPlatformLineEndings();; var parameters = new List { @@ -112,11 +113,11 @@ public void BuildParameters_SimpleParameterType_BuildsCorrectly() [TestMethod] public void BuildParameters_SimpleParameterTypeWithDefault_BuildsCorrectly() { - const string expected = @"## Parameters + var expected = @"## Parameters | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | string | northeurope |"; +| `location` | The location of the resource | string | northeurope |".ToPlatformLineEndings();; var parameters = new List { @@ -140,11 +141,11 @@ public void BuildParameters_SimpleParameterTypeWithDefault_BuildsCorrectly() [TestMethod] public void BuildParameters_Interpolated_BuildsCorrectly() { - const string expected = @"## Parameters + var expected = @"## Parameters | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | string | `resourceGroup().location` |"; +| `location` | The location of the resource | string | `resourceGroup().location` |".ToPlatformLineEndings();; var parameters = new List { @@ -169,11 +170,11 @@ public void BuildParameters_Interpolated_BuildsCorrectly() [TestMethod] public void BuildParameters_ComplexParameterType_BuildsCorrectly() { - const string expected = @"## Parameters + var expected = @"## Parameters | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | [locationAllow](#locationallow) | |"; +| `location` | The location of the resource | [locationAllow](#locationallow) | |".ToPlatformLineEndings();; var parameters = new List { @@ -197,11 +198,11 @@ public void BuildParameters_ComplexParameterType_BuildsCorrectly() [TestMethod] public void BuildParameters_ComplexParameterTypeWithDefault_BuildsCorrectly() { - const string expected = @"## Parameters + var expected = @"## Parameters | Parameter | Description | Type | Default | | --- | --- | --- | --- | -| `location` | The location of the resource | [locationAllow](#locationallow) | one |"; +| `location` | The location of the resource | [locationAllow](#locationallow) | one |".ToPlatformLineEndings();; var parameters = new List { @@ -268,7 +269,7 @@ public void BuildParameterReferences_NoComplexOrAllow_DoesNotGenerate() [TestMethod] public void BuildParameterReferences_ComplexDefaultValue_BuildsCorrectly() { - const string expected = @"## References + var expected = @"## References ### locationValue @@ -276,7 +277,7 @@ public void BuildParameterReferences_ComplexDefaultValue_BuildsCorrectly() { one: 'something' } -```"; +```".ToPlatformLineEndings();; var parameters = new List { @@ -303,14 +304,14 @@ public void BuildParameterReferences_ComplexDefaultValue_BuildsCorrectly() [TestMethod] public void BuildParameterReferences_ComplexParameterType_BuildsCorrectly() { - const string expected = @"## References + var expected = @"## References ### locationAllow - one - two - three -- four"; +- four".ToPlatformLineEndings();; var parameters = new List { @@ -340,4 +341,4 @@ public void BuildParameterReferences_ComplexParameterType_BuildsCorrectly() } #endregion -} \ No newline at end of file +} diff --git a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ResourceGeneratorTests.cs b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ResourceGeneratorTests.cs index 283bf93..21bc569 100644 --- a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ResourceGeneratorTests.cs +++ b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/ResourceGeneratorTests.cs @@ -17,9 +17,9 @@ public class ResourceGeneratorTests : BicepFileTestBase [TestMethod] public void BuildResources_Input_BuildsCorrectly() { - const string expected = @"## Resources + var expected = @"## Resources -- [Microsoft.Web/sites/2022-12-18](https://learn.microsoft.com/en-us/azure/templates/microsoft.web/2022-12-18/sites)"; +- [Microsoft.Web/sites/2022-12-18](https://learn.microsoft.com/en-us/azure/templates/microsoft.web/2022-12-18/sites)".ToPlatformLineEndings();; var resources = new List { new("Microsoft.Web/sites/2022-12-18", "Microsoft.Web", "sites") @@ -45,9 +45,9 @@ public void BuildResources_Input_BuildsCorrectly() [TestMethod] public void BuildResources_MultipleOfSame_BuildsSingle() { - const string expected = @"## Resources + var expected = @"## Resources -- [Microsoft.Web/sites/2022-12-18](https://learn.microsoft.com/en-us/azure/templates/microsoft.web/2022-12-18/sites)"; +- [Microsoft.Web/sites/2022-12-18](https://learn.microsoft.com/en-us/azure/templates/microsoft.web/2022-12-18/sites)".ToPlatformLineEndings();; var resources = new List { new("Microsoft.Web/sites/2022-12-18", "Microsoft.Web", "sites") @@ -81,9 +81,9 @@ public void BuildResources_MultipleOfSame_BuildsSingle() [TestMethod] public async Task BuildResources_InputTemplate_BuildsSingle() { - const string expected = @"## Resources + var expected = @"## Resources -- [Microsoft.Resources/resourceGroups@2021-01-01](https://learn.microsoft.com/en-us/azure/templates/microsoft.resources/2021-01-01/resourcegroups)"; +- [Microsoft.Resources/resourceGroups@2021-01-01](https://learn.microsoft.com/en-us/azure/templates/microsoft.resources/2021-01-01/resourcegroups)".ToPlatformLineEndings();; const string template = @"resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' = { name: resourceGroupName @@ -148,11 +148,11 @@ public async Task BuildResources_NoResources_DoesNotGenerate() [TestMethod] public void BuildReferencedResources_Input_BuildsCorrectly() { - const string expected = @"## Referenced Resources + var expected = @"## Referenced Resources | Provider | Name | Scope | | --- | --- | --- | -| Microsoft.Web/sites/2022-12-18 | `siteOne` | `subscription()` |"; +| Microsoft.Web/sites/2022-12-18 | `siteOne` | `subscription()` |".ToPlatformLineEndings();; var resources = new List { new("Microsoft.Web/sites/2022-12-18", "Microsoft.Web", "sites") @@ -181,12 +181,12 @@ public void BuildReferencedResources_Input_BuildsCorrectly() [TestMethod] public void BuildReferencedResources_MultipleOfSame_BuildsAll() { - const string expected = @"## Referenced Resources + var expected = @"## Referenced Resources | Provider | Name | Scope | | --- | --- | --- | | Microsoft.Web/sites/2022-12-18 | `siteOne` | `subscription()` | -| Microsoft.Web/sites/2022-12-18 | `siteTwo` | `subscription()` |"; +| Microsoft.Web/sites/2022-12-18 | `siteTwo` | `subscription()` |".ToPlatformLineEndings();; var resources = new List { new("Microsoft.Web/sites/2022-12-18", "Microsoft.Web", "sites") @@ -226,11 +226,11 @@ public void BuildReferencedResources_MultipleOfSame_BuildsAll() [TestMethod] public async Task BuildReferencedResources_InputTemplate_BuildsSingle() { - const string expected = @"## Referenced Resources + var expected = @"## Referenced Resources | Provider | Name | Scope | | --- | --- | --- | -| Microsoft.Resources/resourceGroups@2021-01-01 | `resourceGroupName` | - |"; +| Microsoft.Resources/resourceGroups@2021-01-01 | `resourceGroupName` | - |".ToPlatformLineEndings();; const string template = @"resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' existing = { name: resourceGroupName diff --git a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/UsageGeneratorTests.cs b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/UsageGeneratorTests.cs index 695e990..5beb5bd 100644 --- a/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/UsageGeneratorTests.cs +++ b/src/BicepDocs.Formatter.Markdown.UnitTests/Generators/UsageGeneratorTests.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using LandingZones.Tools.BicepDocs.Core.Models.Parsing; +using LandingZones.Tools.BicepDocs.Core.UnitTests; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Elements; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Generators; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Models; @@ -19,7 +20,7 @@ public void BuildUsage_Input_BuildsCorrectly() ModuleType = ModuleUsageType.Registry }; const string modulePath = "workloads/web/function-app"; - const string expected = @"## Usage + var expected = @"## Usage ```bicep module exampleInstance 'br/MyRegistry:workloads/web/function-app:2022-10-29' = { @@ -28,7 +29,7 @@ public void BuildUsage_Input_BuildsCorrectly() location: 'location' } } -```"; +```".ToPlatformLineEndings();; var parameters = new List { @@ -57,7 +58,7 @@ public void BuildUsage_WithDefaults_BuildsCorrectly() ModuleType = ModuleUsageType.Registry }; const string modulePath = "workloads/web/function-app"; - const string expected = @"## Usage + var expected = @"## Usage ```bicep module exampleInstance 'br/MyRegistry:workloads/web/function-app:2022-10-29' = { @@ -67,7 +68,7 @@ public void BuildUsage_WithDefaults_BuildsCorrectly() count: 10 } } -```"; +```".ToPlatformLineEndings();; var parameters = new List { @@ -115,4 +116,4 @@ public void BuildResources_DisabledInOptions_DoesNotGenerate() Assert.AreEqual(0, document.Count); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Formatter.Markdown.UnitTests/MarkdownDocsFormatterTests.cs b/src/BicepDocs.Formatter.Markdown.UnitTests/MarkdownDocsFormatterTests.cs index c5d1e3b..f929bc3 100644 --- a/src/BicepDocs.Formatter.Markdown.UnitTests/MarkdownDocsFormatterTests.cs +++ b/src/BicepDocs.Formatter.Markdown.UnitTests/MarkdownDocsFormatterTests.cs @@ -1,5 +1,6 @@ using LandingZones.Tools.BicepDocs.Core; using LandingZones.Tools.BicepDocs.Core.Abstractions; +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using LandingZones.Tools.BicepDocs.Core.UnitTests; using LandingZones.Tools.BicepDocs.Formatter.Markdown.Models; @@ -44,7 +45,7 @@ param resourceGroupName string var files = await sut.GenerateModuleDocs(ctx); Assert.AreEqual(1, files.Count); var otp = files[0]; - Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md", otp.FilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md".ToPlatformPath(), otp.FilePath); Assert.IsInstanceOfType(otp, typeof(MarkdownGenerationFile)); Assert.IsNull(otp.VersionFilePath); Assert.IsNull(otp.VersionFolderPath); @@ -77,20 +78,20 @@ param resourceGroupName string var files = await sut.GenerateModuleDocs(ctx); Assert.AreEqual(1, files.Count); var otp = files[0]; - Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md", otp.FilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md".ToPlatformPath(), otp.FilePath); Assert.IsInstanceOfType(otp, typeof(MarkdownGenerationFile)); - Assert.AreEqual("/output-folder/some-dir/docs/resources/versions/2022-12-26/resourceGroups.md", otp.VersionFilePath); - Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md", otp.FilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/versions/2022-12-26/resourceGroups.md".ToPlatformPath(), otp.VersionFilePath); + Assert.AreEqual("/output-folder/some-dir/docs/resources/resourceGroups.md".ToPlatformPath(), otp.FilePath); } private ModulePaths GetPaths() { - var inputFolder = "/input/folder/modules"; - var outputBaseFolder = "/output-folder/some-dir/docs"; - var inputFile = "/input/folder/modules/resources/resourceGroups.bicep"; + var inputFolder = "/input/folder/modules".ToPlatformPath(); + var outputBaseFolder = "/output-folder/some-dir/docs".ToPlatformPath(); + var inputFile = "/input/folder/modules/resources/resourceGroups.bicep".ToPlatformPath(); return PathResolver.ResolveModulePaths( bicepFilePath: inputFile, baseInputFolder: inputFolder, outputFolder: outputBaseFolder); } -} \ No newline at end of file +} diff --git a/src/BicepDocs.Source.FileSystem.UnitTests/Commands/FileSystemCommandHandlerTests.cs b/src/BicepDocs.Source.FileSystem.UnitTests/Commands/FileSystemCommandHandlerTests.cs index e466295..56ebc11 100644 --- a/src/BicepDocs.Source.FileSystem.UnitTests/Commands/FileSystemCommandHandlerTests.cs +++ b/src/BicepDocs.Source.FileSystem.UnitTests/Commands/FileSystemCommandHandlerTests.cs @@ -2,6 +2,7 @@ using System.IO.Abstractions; using LandingZones.Tools.BicepDocs.Core; using LandingZones.Tools.BicepDocs.Core.Abstractions; +using LandingZones.Tools.BicepDocs.Core.Extensions; using LandingZones.Tools.BicepDocs.Core.Models.Formatting; using LandingZones.Tools.BicepDocs.Core.UnitTests; using LandingZones.Tools.BicepDocs.Destination.FileSystem; @@ -51,7 +52,7 @@ public async Task Invoke_GetResultsInFullPath_Null_Returns() _matcher.Setup(x => x.AddIncludePatterns(It.IsAny>())); - _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath)).Returns((List)null!); + _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath.WithPlatformRootPath())).Returns((List)null!); var result = await sut.InvokeAsync(new InvocationContext(null!)); Assert.AreEqual(-1, result); @@ -76,7 +77,7 @@ public async Task Invoke_GetResultsInFullPath_Empty_Returns() _matcher.Setup(x => x.AddIncludePatterns(It.IsAny>())); - _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath)).Returns(new List()); + _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath.WithPlatformRootPath())).Returns(new List()); var result = await sut.InvokeAsync(new InvocationContext(null!)); Assert.AreEqual(-1, result); @@ -106,34 +107,32 @@ public async Task Invoke_Defaults_GeneratesAndWrites() tags: tags }"; - const string modulePath = "/input/modules/rg/resourceGroup.bicep"; - const string moduleOut = "/output/modules/rg"; - const string moduleOutFile = "/output/modules/rg/resourceGroup.md"; + string modulePath = "/input/modules/rg/resourceGroup.bicep".ToPlatformPath(); _matcher.Setup(x => x.AddIncludePatterns(It.IsAny>())); - _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath)).Returns( + _matcher.Setup(x => x.GetResultsInFullPath(sut.FolderPath.WithPlatformRootPath())).Returns( new List { modulePath }); // Loading - _staticFileSystem.Setup(x => x.Directory.Exists(sut.Out)).Returns(false); - _staticFileSystem.Setup(x => x.Directory.CreateDirectory(sut.Out)).Returns((IDirectoryInfo)null!); + _staticFileSystem.Setup(x => x.Directory.Exists(sut.Out.WithPlatformRootPath())).Returns(false); + _staticFileSystem.Setup(x => x.Directory.CreateDirectory(sut.Out.WithPlatformRootPath())).Returns((IDirectoryInfo)null!); _staticFileSystem.Setup(x => x.File.ReadAllTextAsync(modulePath, It.IsAny())) .ReturnsAsync(template); //Writing - _staticFileSystem.Setup(x => x.Directory.Exists(moduleOut)).Returns(false); - _staticFileSystem.Setup(x => x.Directory.CreateDirectory(moduleOut)).Returns((IDirectoryInfo)null!); + _staticFileSystem.Setup(x => x.Directory.Exists(It.IsAny())).Returns(false); + _staticFileSystem.Setup(x => x.Directory.CreateDirectory(It.IsAny())).Returns((IDirectoryInfo)null!); _staticFileSystem - .Setup(x => x.File.WriteAllTextAsync(moduleOutFile, It.IsAny(), It.IsAny())) + .Setup(x => x.File.WriteAllTextAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var result = await sut.InvokeAsync(new InvocationContext(null!)); - Assert.AreEqual(1, result); + Assert.AreEqual(0, result); } @@ -151,8 +150,8 @@ private FileSystemCommandHandler GetSut( _bicepFileService ) { - FolderPath = "/input/modules", - Out = "/output/modules", + FolderPath = "/input/modules".ToPlatformPath(), + Out = "/output/modules".ToPlatformPath(), Formatter = DocFormatter.Markdown }; @@ -164,4 +163,4 @@ private FileSystemSource GetFileSystemSource() => private FileSystemDestination GetFileSystemDestination() => new(NullLogger.Instance, _staticFileSystem.Object); -} \ No newline at end of file +} diff --git a/src/BicepDocs.Source.FileSystem/Commands/FileSystemCommandHandler.cs b/src/BicepDocs.Source.FileSystem/Commands/FileSystemCommandHandler.cs index 40d9dd1..5102da4 100644 --- a/src/BicepDocs.Source.FileSystem/Commands/FileSystemCommandHandler.cs +++ b/src/BicepDocs.Source.FileSystem/Commands/FileSystemCommandHandler.cs @@ -113,6 +113,6 @@ await _bicepFileService.GetSemanticModelFromContent(paths.VirtualFolder, paths.V await destinationProvider.Write(convertedFiles); } - return 1; + return 0; } } \ No newline at end of file