diff --git a/nuspec/nuget/Cake.DocFx.nuspec b/nuspec/nuget/Cake.DocFx.nuspec index c163dc5..d41c05f 100644 --- a/nuspec/nuget/Cake.DocFx.nuspec +++ b/nuspec/nuget/Cake.DocFx.nuspec @@ -14,7 +14,7 @@ false Copyright (c) Cake Contributions 2016 - Present Cake Script DocFx - https://github.com/cake-contrib/Cake.DocFx/releases/tag/0.7.0 + https://github.com/cake-contrib/Cake.DocFx/releases/tag/0.8.0 diff --git a/src/Cake.DocFx.Tests/Build/DocFxBuildRunnerTests.cs b/src/Cake.DocFx.Tests/Build/DocFxBuildRunnerTests.cs index 6a610a1..1683407 100644 --- a/src/Cake.DocFx.Tests/Build/DocFxBuildRunnerTests.cs +++ b/src/Cake.DocFx.Tests/Build/DocFxBuildRunnerTests.cs @@ -103,6 +103,22 @@ public void Should_Add_Serve_To_Arguments_If_True() // Then Assert.Equal("build --serve", result.Args); } + + [Fact] + public void Should_Add_Force_To_Arguments_If_True() + { + // Given + var fixture = new DocFxBuildRunnerFixture + { + Settings = {Force = true} + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("build --force", result.Args); + } } } } diff --git a/src/Cake.DocFx.Tests/Metadata/DocFxMetadataRunnerTests.cs b/src/Cake.DocFx.Tests/Metadata/DocFxMetadataRunnerTests.cs index f285a8b..fe70048 100644 --- a/src/Cake.DocFx.Tests/Metadata/DocFxMetadataRunnerTests.cs +++ b/src/Cake.DocFx.Tests/Metadata/DocFxMetadataRunnerTests.cs @@ -73,6 +73,22 @@ public void Should_Not_Add_LogLevel_To_Arguments_If_Default() // Then Assert.Equal("metadata", result.Args); } + + [Fact] + public void Should_Add_Force_To_Arguments_If_True() + { + // Given + var fixture = new DocFxMetadataRunnerFixture + { + Settings = {Force = true} + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("metadata --force", result.Args); + } } } } diff --git a/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerFixture.cs b/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerFixture.cs new file mode 100644 index 0000000..adadb76 --- /dev/null +++ b/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerFixture.cs @@ -0,0 +1,20 @@ +using Cake.Core.IO; +using Cake.DocFx.Pdf; + +namespace Cake.DocFx.Tests.Pdf +{ + internal sealed class DocFxPdfRunnerFixture : DocFxFixture + { + public DocFxPdfRunnerFixture() + { + } + + public FilePath ConfigFilePath { get; set; } + + protected override void RunTool() + { + var tool = new DocFxPdfRunner(FileSystem, Environment, ProcessRunner, Tools); + tool.Run(ConfigFilePath, Settings); + } + } +} diff --git a/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerTests.cs b/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerTests.cs new file mode 100644 index 0000000..ad0ad01 --- /dev/null +++ b/src/Cake.DocFx.Tests/Pdf/DocFxPdfRunnerTests.cs @@ -0,0 +1,123 @@ +using Xunit; + +namespace Cake.DocFx.Tests.Pdf +{ + public class DocFxPdfRunnerTests + { + public sealed class TheRunMethod + { + [Fact] + public void Should_Throw_If_Settings_Are_Null() + { + // Given + var fixture = new DocFxPdfRunnerFixture + { + Settings = null + }; + + // When + var result = Record.Exception(() => fixture.Run()); + + // Then + result.IsArgumentNullException("settings"); + } + + + [Fact] + public void Should_Be_Pdf_Command() + { + // Given + var fixture = new DocFxPdfRunnerFixture + { + Settings = {} + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf", result.Args); + } + + [Fact] + public void Should_Add_LogPath_To_Arguments_If_Set() + { + // Given + var fixture = new DocFxPdfRunnerFixture + { + Settings = { LogPath = @"c:\temp\docfx.log" } + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf -l \"c:/temp/docfx.log\"", result.Args); + } + + [Theory] + [InlineData(DocFxLogLevel.Error, "Error")] + [InlineData(DocFxLogLevel.Warning, "Warning")] + [InlineData(DocFxLogLevel.Info, "Info")] + [InlineData(DocFxLogLevel.Verbose, "Verbose")] + public void Should_Add_LogLevel_To_Arguments_If_Set(DocFxLogLevel logLevel, string expectedLevel) + { + // Given + var fixture = new DocFxPdfRunnerFixture + { + Settings = { LogLevel = logLevel } + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf --logLevel \"" + expectedLevel + "\"", result.Args); + } + + [Fact] + public void Should_Not_Add_LogLevel_To_Arguments_If_Default() + { + // Given + var fixture = new DocFxPdfRunnerFixture + { + Settings = { LogLevel = DocFxLogLevel.Default } + }; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf", result.Args); + } + + [Fact] + public void Should_Add_GlobalMetadata_To_Arguments_If_Not_Empty() + { + // Given + var fixture = new DocFxPdfRunnerFixture(); + fixture.Settings.GlobalMetadata.Add("foo", "bar"); + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf --globalMetadata \"{\\\"foo\\\": \\\"bar\\\"}\"", result.Args); + } + + [Fact] + public void Should_Add_Name_To_Arguments_If_Not_Empty() + { + // Given + var fixture = new DocFxPdfRunnerFixture(); + fixture.Settings.Name = "foo"; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("pdf --name \"foo\"", result.Args); + } + } + } +} diff --git a/src/Cake.DocFx/Build/DocFxBuildRunner.cs b/src/Cake.DocFx/Build/DocFxBuildRunner.cs index 4e80d98..5665058 100644 --- a/src/Cake.DocFx/Build/DocFxBuildRunner.cs +++ b/src/Cake.DocFx/Build/DocFxBuildRunner.cs @@ -43,10 +43,10 @@ private ProcessArgumentBuilder GetArguments(FilePath configFile, DocFxBuildSetti builder.Append("build"); // parameters + #region DupFinder Exclusion if (configFile != null) builder.Append("\"{0}\"", configFile.FullPath); - #region DupFinder Exclusion if (settings.OutputPath != null) builder.Append("-o \"{0}\"", settings.OutputPath.FullPath); @@ -55,7 +55,6 @@ private ProcessArgumentBuilder GetArguments(FilePath configFile, DocFxBuildSetti if (settings.LogLevel != DocFxLogLevel.Default) builder.Append("--logLevel \"{0}\"", settings.LogLevel); - #endregion if (settings.TemplateFolder != null) builder.Append("-t \"{0}\"", settings.TemplateFolder.FullPath); @@ -69,6 +68,12 @@ private ProcessArgumentBuilder GetArguments(FilePath configFile, DocFxBuildSetti { builder.Append("--serve"); } + #endregion + + if (settings.Force) + { + builder.Append("--force"); + } return builder; } diff --git a/src/Cake.DocFx/Build/DocFxBuildSettings.cs b/src/Cake.DocFx/Build/DocFxBuildSettings.cs index dfd5dc7..c8f698b 100644 --- a/src/Cake.DocFx/Build/DocFxBuildSettings.cs +++ b/src/Cake.DocFx/Build/DocFxBuildSettings.cs @@ -45,5 +45,10 @@ public class DocFxBuildSettings : ToolSettings /// in a built in web server. /// public bool Serve { get; set; } + + /// + /// Gets or sets a value indicating whether all the documentation is re-build. + /// + public bool Force { get; set; } } } \ No newline at end of file diff --git a/src/Cake.DocFx/DocFxPdfAliases.cs b/src/Cake.DocFx/DocFxPdfAliases.cs new file mode 100644 index 0000000..a04b1bd --- /dev/null +++ b/src/Cake.DocFx/DocFxPdfAliases.cs @@ -0,0 +1,96 @@ +using Cake.Core; +using Cake.Core.Annotations; +using Cake.Core.IO; +using Cake.DocFx.Helper; +using Cake.DocFx.Pdf; + +namespace Cake.DocFx +{ + /// + /// Contains functionality related to creating PDF files using DocFx. + /// + [CakeAliasCategory("DocFx")] + [CakeNamespaceImport("Cake.DocFx.Pdf")] + public static class DocFxPdfAliases + { + /// + /// Generates a PDF document for the docfx.json file in the current working directory. + /// + /// The Cake context. + /// + /// + /// DocFxPdf(); + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("Pdf")] + public static void DocFxPdf(this ICakeContext context) + => context.DocFxPdf(null, null); + + /// + /// Generates a PDF document for a specific docfx.json file. + /// + /// The Cake context. + /// The optional path to a DocFx config file. + /// If no value is passed the docfx.json file in the current working directory will be used. + /// + /// + /// DocFxPdf("./docs/docfx.json"); + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("Pdf")] + public static void DocFxPdf(this ICakeContext context, FilePath configFile) + => context.DocFxPdf(configFile, null); + + /// + /// Generates a PDF document for the docfx.json file in the current working directory + /// using the specified settings. + /// + /// The Cake context. + /// The optional DocFx settings. + /// If no settings are passed default settings are used. + /// + /// + /// DocFxPdf(new DocFxPdfSettings() + /// { + /// OutputPath = "./artifacts/docs", + /// TemplateFolder = "default" + /// }); + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("Pdf")] + public static void DocFxPdf(this ICakeContext context, DocFxPdfSettings settings) + => context.DocFxPdf(null, settings); + + /// + /// Generates a PDF document for a specific docfx.json file using the specified settings. + /// + /// The Cake context. + /// The optional path to a DocFx config file. + /// If no value is passed the docfx.json file in the current working directory will be used. + /// The optional DocFx settings. + /// If no settings are passed default settings are used. + /// + /// + /// DocFxPdf("./docs/docfx.json", new DocFxPdfSettings() + /// { + /// OutputPath = "./artifacts/docs", + /// TemplateFolder = "default" + /// }); + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("Pdf")] + public static void DocFxPdf(this ICakeContext context, FilePath configFile, DocFxPdfSettings settings) + { + Contract.NotNull(context, nameof(context)); + + settings = settings ?? new DocFxPdfSettings(); + + var runner = new DocFxPdfRunner(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools); + runner.Run(configFile, settings); + } + } +} \ No newline at end of file diff --git a/src/Cake.DocFx/Metadata/DocFxMetadataRunner.cs b/src/Cake.DocFx/Metadata/DocFxMetadataRunner.cs index 61509a5..45a58de 100644 --- a/src/Cake.DocFx/Metadata/DocFxMetadataRunner.cs +++ b/src/Cake.DocFx/Metadata/DocFxMetadataRunner.cs @@ -56,6 +56,11 @@ private ProcessArgumentBuilder GetArguments(DocFxMetadataSettings settings) builder.Append("--logLevel \"{0}\"", settings.LogLevel); #endregion + if (settings.Force) + { + builder.Append("--force"); + } + return builder; } } diff --git a/src/Cake.DocFx/Metadata/DocFxMetadataSettings.cs b/src/Cake.DocFx/Metadata/DocFxMetadataSettings.cs index 8cfcd60..881fb80 100644 --- a/src/Cake.DocFx/Metadata/DocFxMetadataSettings.cs +++ b/src/Cake.DocFx/Metadata/DocFxMetadataSettings.cs @@ -35,5 +35,10 @@ public class DocFxMetadataSettings : ToolSettings /// Gets or sets to which log level will be logged. /// public DocFxLogLevel LogLevel { get; set; } + + /// + /// Gets or sets a value indicating whether all the documentation is re-build. + /// + public bool Force { get; set; } } } \ No newline at end of file diff --git a/src/Cake.DocFx/Pdf/DocFxPdfRunner.cs b/src/Cake.DocFx/Pdf/DocFxPdfRunner.cs new file mode 100644 index 0000000..a17d451 --- /dev/null +++ b/src/Cake.DocFx/Pdf/DocFxPdfRunner.cs @@ -0,0 +1,74 @@ +using System.Linq; +using Cake.Core; +using Cake.Core.IO; +using Cake.Core.Tooling; +using Cake.DocFx.Helper; + +namespace Cake.DocFx.Pdf +{ + /// + /// Command line runner for the docfx pdf command. + /// + internal sealed class DocFxPdfRunner : DocFxTool + { + /// + /// Initializes a new instance of the class. + /// + /// The file system. + /// The environment. + /// The process runner. + /// The tool locator. + public DocFxPdfRunner(IFileSystem fileSystem, ICakeEnvironment environment, IProcessRunner processRunner, IToolLocator tools) + : base(fileSystem, environment, processRunner, tools) + { + } + + /// + /// Runs DocFx generator with the given configuration. + /// + /// The optional path to the docfx.json config file. + /// The settings. + public void Run(FilePath configFile, DocFxPdfSettings settings) + { + Contract.NotNull(settings, nameof(settings)); + + Run(settings, GetArguments(configFile, settings)); + } + + private ProcessArgumentBuilder GetArguments(FilePath configFile, DocFxPdfSettings settings) + { + var builder = new ProcessArgumentBuilder(); + + // command + builder.Append("pdf"); + + // parameters + #region DupFinder Exclusion + if (configFile != null) + builder.Append("\"{0}\"", configFile.FullPath); + + if (settings.OutputPath != null) + builder.Append("-o \"{0}\"", settings.OutputPath.FullPath); + + if (settings.LogPath != null) + builder.Append("-l \"{0}\"", settings.LogPath.FullPath); + + if (settings.LogLevel != DocFxLogLevel.Default) + builder.Append("--logLevel \"{0}\"", settings.LogLevel); + + if (settings.TemplateFolder != null) + builder.Append("-t \"{0}\"", settings.TemplateFolder.FullPath); + + if (settings.GlobalMetadata.Any()) + builder.Append( + "--globalMetadata \"{{{0}}}\"", + string.Join(", ", settings.GlobalMetadata.Select(x => $"\\\"{x.Key}\\\": \\\"{x.Value}\\\""))); + + if (settings.Name != null) + builder.Append("--name \"{0}\"", settings.Name); + #endregion + + return builder; + } + } +} diff --git a/src/Cake.DocFx/Pdf/DocFxPdfSettings.cs b/src/Cake.DocFx/Pdf/DocFxPdfSettings.cs new file mode 100644 index 0000000..bbfd978 --- /dev/null +++ b/src/Cake.DocFx/Pdf/DocFxPdfSettings.cs @@ -0,0 +1,44 @@ +using Cake.Core.IO; +using Cake.Core.Tooling; +using System.Collections.Generic; + +namespace Cake.DocFx.Pdf +{ + /// + /// Contains settings used by . + /// + public class DocFxPdfSettings : ToolSettings + { + /// + /// Gets or sets the output base directory. + /// + public DirectoryPath OutputPath { get; set; } + + /// + /// Gets or sets the path and file name where the log file generated by DocFx will be saved. + /// + public FilePath LogPath { get; set; } + + /// + /// Gets or sets to which log level will be logged. + /// + public DocFxLogLevel LogLevel { get; set; } + + /// + /// Gets or sets the template path to use. + /// + public DirectoryPath TemplateFolder { get; set; } + + /// + /// Gets global metadata. + /// It overrides the globalMetadata settings from the config file. + /// See for constants for metadata keys. + /// + public Dictionary GlobalMetadata { get; } = new Dictionary(); + + /// + /// Gets or sets the name of the generated PDF. + /// + public string Name { get; set; } + } +} \ No newline at end of file