diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..0baa52b --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "0.38.5", + "commands": [ + "dotnet-cake" + ] + }, + "minver-cli": { + "version": "2.3.1", + "commands": [ + "minver" + ] + } + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e34807c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +end_of_line = unset +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +[*.{xml,config,nuspec,csproj,props,targets,ps1}] +indent_size = 2 + +[*.{sh}] +end_of_line = lf + +[*.{dotsettings}] +end_of_line = lf diff --git a/.github/workflows/dependabot-cake.yml b/.github/workflows/dependabot-cake.yml new file mode 100644 index 0000000..ebf78d6 --- /dev/null +++ b/.github/workflows/dependabot-cake.yml @@ -0,0 +1,13 @@ +on: + schedule: + # every Sunday at 6am + - cron: '0 6 * * SUN' + + workflow_dispatch: + +jobs: + dependabot-cake: + runs-on: ubuntu-latest + steps: + - name: check/update cake dependencies + uses: augustoproiete-actions/nils-org--dependabot-cake-action@v1 diff --git a/Cake.ExcelDnaPack.sln b/Cake.ExcelDnaPack.sln new file mode 100644 index 0000000..2b56199 --- /dev/null +++ b/Cake.ExcelDnaPack.sln @@ -0,0 +1,56 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A9A83466-9CAD-4375-95F1-D9076C84F91F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cake.ExcelDnaPack", "src\Cake.ExcelDnaPack\Cake.ExcelDnaPack.csproj", "{AF41A4CC-4C49-462F-8093-DDE0728ED080}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{5335FA0D-89D3-4929-91FD-9E034B446C6F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cake.ExcelDnaPack.Tests", "test\Cake.ExcelDnaPack.Tests\Cake.ExcelDnaPack.Tests.csproj", "{CB06C244-620D-49F8-8D25-FC09B5A2D634}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "asset", "asset", "{93529E0B-F492-407B-9410-F4872FA21CF1}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .gitattributes = .gitattributes + .gitignore = .gitignore + build.cake = build.cake + build.cmd = build.cmd + build.ps1 = build.ps1 + build.sh = build.sh + cake.config = cake.config + CHANGES.md = CHANGES.md + CODEOWNERS = CODEOWNERS + Directory.Build.props = Directory.Build.props + global.json = global.json + LICENSE = LICENSE + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AF41A4CC-4C49-462F-8093-DDE0728ED080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF41A4CC-4C49-462F-8093-DDE0728ED080}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF41A4CC-4C49-462F-8093-DDE0728ED080}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF41A4CC-4C49-462F-8093-DDE0728ED080}.Release|Any CPU.Build.0 = Release|Any CPU + {CB06C244-620D-49F8-8D25-FC09B5A2D634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB06C244-620D-49F8-8D25-FC09B5A2D634}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB06C244-620D-49F8-8D25-FC09B5A2D634}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB06C244-620D-49F8-8D25-FC09B5A2D634}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {AF41A4CC-4C49-462F-8093-DDE0728ED080} = {A9A83466-9CAD-4375-95F1-D9076C84F91F} + {CB06C244-620D-49F8-8D25-FC09B5A2D634} = {5335FA0D-89D3-4929-91FD-9E034B446C6F} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4A94F7B1-5AA4-40C5-AA9C-22A3F47318A7} + EndGlobalSection +EndGlobal diff --git a/Cake.ExcelDnaPack.sln.DotSettings b/Cake.ExcelDnaPack.sln.DotSettings new file mode 100644 index 0000000..f563613 --- /dev/null +++ b/Cake.ExcelDnaPack.sln.DotSettings @@ -0,0 +1,14 @@ + + 1000 + 3000 + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..2c3ecd9 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,11 @@ + + + + latest + + + + + + + diff --git a/asset/cake-exceldnapack-nuget.png b/asset/cake-exceldnapack-nuget.png new file mode 100644 index 0000000..9881edc Binary files /dev/null and b/asset/cake-exceldnapack-nuget.png differ diff --git a/build.cake b/build.cake new file mode 100644 index 0000000..cb31183 --- /dev/null +++ b/build.cake @@ -0,0 +1,121 @@ +#addin "nuget:?package=Cake.MinVer&version=0.2.0" + +var target = Argument("target", "pack"); +var buildVersion = MinVer(s => s.WithTagPrefix("v").WithDefaultPreReleasePhase("preview")); + +Task("clean") + .Does(() => +{ + CleanDirectory("./build/artifacts"); + CleanDirectories("./src/**/bin"); + CleanDirectories("./src/**/obj"); + CleanDirectories("./test/**/bin"); + CleanDirectories("./test/**/obj"); +}); + +Task("restore") + .IsDependentOn("clean") + .Does(() => +{ + DotNetCoreRestore("./Cake.ExcelDnaPack.sln", new DotNetCoreRestoreSettings + { + LockedMode = true, + }); +}); + +Task("build") + .IsDependentOn("restore") + .Does(() => +{ + DotNetCoreBuild("./Cake.ExcelDnaPack.sln", new DotNetCoreBuildSettings + { + Configuration = "Debug", + NoRestore = true, + NoIncremental = false, + ArgumentCustomization = args => + args.AppendQuoted($"-p:Version={buildVersion.Version}") + .AppendQuoted($"-p:AssemblyVersion={buildVersion.FileVersion}") + .AppendQuoted($"-p:FileVersion={buildVersion.FileVersion}") + .AppendQuoted($"-p:ContinuousIntegrationBuild=true") + }); + + DotNetCoreBuild("./Cake.ExcelDnaPack.sln", new DotNetCoreBuildSettings + { + Configuration = "Release", + NoRestore = true, + NoIncremental = false, + ArgumentCustomization = args => + args.AppendQuoted($"-p:Version={buildVersion.Version}") + .AppendQuoted($"-p:AssemblyVersion={buildVersion.FileVersion}") + .AppendQuoted($"-p:FileVersion={buildVersion.FileVersion}") + .AppendQuoted($"-p:ContinuousIntegrationBuild=true") + }); +}); + +Task("test") + .IsDependentOn("build") + .Does(() => +{ + var settings = new DotNetCoreTestSettings + { + Configuration = "Release", + NoRestore = true, + NoBuild = true, + }; + + var projectFiles = GetFiles("./test/**/*.csproj"); + foreach (var file in projectFiles) + { + DotNetCoreTest(file.FullPath, settings); + } +}); + +Task("pack") + .IsDependentOn("test") + .Does(() => +{ + var releaseNotes = $"https://github.com/augustoproiete/Cake.ExcelDnaPack/releases/tag/v{buildVersion.Version}"; + + DotNetCorePack("./src/Cake.ExcelDnaPack/Cake.ExcelDnaPack.csproj", new DotNetCorePackSettings + { + Configuration = "Release", + NoRestore = true, + NoBuild = true, + OutputDirectory = "./build/artifacts", + ArgumentCustomization = args => + args.AppendQuoted($"-p:Version={buildVersion.Version}") + .AppendQuoted($"-p:PackageReleaseNotes={releaseNotes}") + }); +}); + +Task("publish") + .IsDependentOn("pack") + .Does(context => +{ + var url = context.EnvironmentVariable("NUGET_URL"); + if (string.IsNullOrWhiteSpace(url)) + { + context.Information("No NuGet URL specified. Skipping publishing of NuGet packages"); + return; + } + + var apiKey = context.EnvironmentVariable("NUGET_API_KEY"); + if (string.IsNullOrWhiteSpace(apiKey)) + { + context.Information("No NuGet API key specified. Skipping publishing of NuGet packages"); + return; + } + + var nugetPushSettings = new DotNetCoreNuGetPushSettings + { + Source = url, + ApiKey = apiKey, + }; + + foreach (var nugetPackageFile in GetFiles("./build/artifacts/*.nupkg")) + { + DotNetCoreNuGetPush(nugetPackageFile.FullPath, nugetPushSettings); + } +}); + +RunTarget(target); diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..d060b75 --- /dev/null +++ b/build.cmd @@ -0,0 +1,11 @@ +@echo on +@cd %~dp0 + +set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +set DOTNET_CLI_TELEMETRY_OPTOUT=1 +set DOTNET_NOLOGO=1 + +dotnet tool restore +@if %ERRORLEVEL% neq 0 goto :eof + +dotnet cake %* diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..21821d2 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,13 @@ +$ErrorActionPreference = 'Stop' + +Set-Location -LiteralPath $PSScriptRoot + +$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1' +$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1' +$env:DOTNET_NOLOGO = '1' + +dotnet tool restore +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + +dotnet cake @args +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..31be886 --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euox pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")" + +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_NOLOGO=1 + +dotnet tool restore + +dotnet cake "$@" diff --git a/cake.config b/cake.config new file mode 100644 index 0000000..513b1e8 --- /dev/null +++ b/cake.config @@ -0,0 +1,12 @@ +[Nuget] +Source=https://api.nuget.org/v3/index.json +UseInProcessClient=true +LoadDependencies=false + +[Paths] +Tools=./.cake +Addins=./.cake/addins +Modules=./.cake/modules + +[Settings] +SkipVerification=false diff --git a/global.json b/global.json new file mode 100644 index 0000000..5f35d39 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "allowPrerelease": false, + "version": "5.0.100", + "rollForward": "latestFeature" + } +} diff --git a/src/Cake.ExcelDnaPack/AddInInformation.cs b/src/Cake.ExcelDnaPack/AddInInformation.cs new file mode 100644 index 0000000..73145a9 --- /dev/null +++ b/src/Cake.ExcelDnaPack/AddInInformation.cs @@ -0,0 +1,39 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Reflection; +using Cake.Core.Diagnostics; + +namespace Cake.ExcelDnaPack +{ + internal static class AddInInformation + { + private static readonly Assembly _thisAssembly = typeof(AddInInformation).GetTypeInfo().Assembly; + + private static readonly string _informationalVersion = _thisAssembly + .GetCustomAttribute()?.InformationalVersion; + + private static readonly string _assemblyVersion = _thisAssembly + .GetName().Version?.ToString(3); + + private static readonly string _assemblyName = _thisAssembly + .GetName().Name; + + public static void LogVersionInformation(ICakeLog log) + { + log.Verbose(entry => + entry("Using add-in: {0} v{1} ({2})", _assemblyName, _assemblyVersion, _informationalVersion)); + } + } +} diff --git a/src/Cake.ExcelDnaPack/Cake.ExcelDnaPack.csproj b/src/Cake.ExcelDnaPack/Cake.ExcelDnaPack.csproj new file mode 100644 index 0000000..242d221 --- /dev/null +++ b/src/Cake.ExcelDnaPack/Cake.ExcelDnaPack.csproj @@ -0,0 +1,54 @@ + + + + net5.0;netstandard2.0;net461 + Cake.ExcelDnaPack + + Cake.ExcelDnaPack + 0.0.1.0 + true + true + true + + true + portable + true + true + snupkg + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + $(NoWarn);NU5048 + true + + + + + 4.0.0 + Cake.ExcelDnaPack + 0.0.1-local + C. Augusto Proiete & Contributors + augustoproiete.net + Cake add-in that makes ExcelDnaPack available as a tool in Cake. + Copyright 2021 C. Augusto Proiete & Contributors - Provided under the MIT License + cake;exceldnapack;exceldna;addin;cake-addin;cake-build;augustoproiete + MIT + images\icon.png + https://raw.githubusercontent.com/augustoproiete/Cake.ExcelDnaPack/master/assets/cake-exceldnapack-nuget.png + https://github.com/augustoproiete/Cake.ExcelDnaPack + https://github.com/augustoproiete/Cake.ExcelDnaPack/releases + git + https://github.com/augustoproiete/Cake.ExcelDnaPack.git + + + + + + + + + + + + + + diff --git a/src/Cake.ExcelDnaPack/ExcelDnaPackAliases.cs b/src/Cake.ExcelDnaPack/ExcelDnaPackAliases.cs new file mode 100644 index 0000000..3460778 --- /dev/null +++ b/src/Cake.ExcelDnaPack/ExcelDnaPackAliases.cs @@ -0,0 +1,285 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Cake.Core; +using Cake.Core.Annotations; +using Cake.Core.IO; + +namespace Cake.ExcelDnaPack +{ + /// + /// ExcelDnaPack aliases + /// + [CakeAliasCategory("ExcelDnaPack")] + [CakeNamespaceImport("Cake.ExcelDnaPack")] + public static class ExcelDnaPackAliases + { + /// + /// Run the ExcelDnaPack tool with default settings. + /// + /// The context. + /// The path to the primary .dna file for the Excel-DNA add-in. + /// + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("ExcelDnaPack")] + public static void ExcelDnaPack(this ICakeContext context, FilePath dnaFilePath) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (dnaFilePath is null) + { + throw new ArgumentNullException(nameof(dnaFilePath)); + } + + var settings = new ExcelDnaPackSettings + { + DnaFilePath = dnaFilePath, + }; + + context.ExcelDnaPack(settings); + } + + /// + /// Run the ExcelDnaPack tool using the settings returned by a configurator. + /// + /// The context. + /// The path to the primary .dna file for the Excel-DNA add-in. + /// The settings configurator. + /// + /// Enable interactive prompt to overwrite the output .xll file, if it already exists + /// + /// settings + /// .PromptBeforeOverwrite() + /// ); + /// // ... + /// ]]> + /// + /// Disable compression (LZMA) of resources (e.g. `/NoCompression`) + /// + /// settings + /// .NoCompression() + /// ); + /// // ... + /// ]]> + /// + /// Disable multi-threading to ensure deterministic order of packing (e.g. `/NoMultiThreading`) + /// + /// settings + /// .NoMultiThreading() + /// ); + /// // ... + /// ]]> + /// + /// The output path for the packed .xll file (e.g. `/O MyAddin-x86-packed.xll`) + /// + /// settings + /// .SetOutputXllFilePath("MyAddin-x86-packed.xll") + /// ); + /// // ... + /// ]]> + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("ExcelDnaPack")] + public static void ExcelDnaPack(this ICakeContext context, FilePath dnaFilePath, Action configurator) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (dnaFilePath is null) + { + throw new ArgumentNullException(nameof(dnaFilePath)); + } + + if (configurator is null) + { + throw new ArgumentNullException(nameof(configurator)); + } + + var settings = new ExcelDnaPackSettings + { + DnaFilePath = dnaFilePath, + }; + + configurator(settings); + + context.ExcelDnaPack(settings); + } + + /// + /// Run the ExcelDnaPack tool using the settings returned by a configurator. + /// + /// The context. + /// The settings configurator. + /// + /// Enable interactive prompt to overwrite the output .xll file, if it already exists + /// + /// settings + /// .SetDnaFilePath("MyAddin.dna") + /// .PromptBeforeOverwrite() + /// ); + /// // ... + /// ]]> + /// + /// Disable compression (LZMA) of resources (e.g. `/NoCompression`) + /// + /// settings + /// .SetDnaFilePath("MyAddin.dna") + /// .NoCompression() + /// ); + /// // ... + /// ]]> + /// + /// Disable multi-threading to ensure deterministic order of packing (e.g. `/NoMultiThreading`) + /// + /// settings + /// .SetDnaFilePath("MyAddin.dna") + /// .NoMultiThreading() + /// ); + /// // ... + /// ]]> + /// + /// The output path for the packed .xll file (e.g. `/O MyAddin-x86-packed.xll`) + /// + /// settings + /// .SetDnaFilePath("MyAddin.dna") + /// .SetOutputXllFilePath("MyAddin-x86-packed.xll") + /// ); + /// // ... + /// ]]> + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("ExcelDnaPack")] + public static void ExcelDnaPack(this ICakeContext context, Action configurator) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (configurator is null) + { + throw new ArgumentNullException(nameof(configurator)); + } + + var settings = new ExcelDnaPackSettings(); + configurator(settings); + + context.ExcelDnaPack(settings); + } + + /// + /// Run the ExcelDnaPack tool using the specified settings. + /// + /// The context. + /// The settings. + /// + /// Enable interactive prompt to overwrite the output .xll file, if it already exists + /// + /// + /// + /// Disable compression (LZMA) of resources (e.g. `/NoCompression`) + /// + /// + /// + /// Disable multi-threading to ensure deterministic order of packing (e.g. `/NoMultiThreading`) + /// + /// + /// + /// The output path for the packed .xll file (e.g. `/O MyAddin-x86-packed.xll`) + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory("ExcelDnaPack")] + public static void ExcelDnaPack(this ICakeContext context, ExcelDnaPackSettings settings) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + AddInInformation.LogVersionInformation(context.Log); + + var excelDnaPack = new ExcelDnaPackTool(context.FileSystem, context.Environment, context.ProcessRunner, + context.Tools, context.Log); + + excelDnaPack.Run(settings); + } + } +} diff --git a/src/Cake.ExcelDnaPack/ExcelDnaPackSettings.cs b/src/Cake.ExcelDnaPack/ExcelDnaPackSettings.cs new file mode 100644 index 0000000..7af4704 --- /dev/null +++ b/src/Cake.ExcelDnaPack/ExcelDnaPackSettings.cs @@ -0,0 +1,51 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Cake.Core.IO; +using Cake.Core.Tooling; + +namespace Cake.ExcelDnaPack +{ + /// + /// Contains settings used by . + /// + public class ExcelDnaPackSettings : ToolSettings + { + /// + /// The path to the primary .dna file for the Excel-DNA add-in. + /// + public FilePath DnaFilePath { get; set; } + + /// + /// Enable interactive prompt to overwrite the output .xll file, if it already exists. + /// Defaults to if . + /// + public bool? PromptBeforeOverwrite { get; set; } + + /// + /// Disable compression (LZMA) of resources. + /// + public bool? NoCompression { get; set; } + + /// + /// Disable multi-threading to ensure deterministic order of packing. + /// + public bool? NoMultiThreading { get; set; } + + /// + /// The output path for the packed .xll file. Default is -packed.xll. + /// + public FilePath OutputXllFilePath { get; set; } + } +} diff --git a/src/Cake.ExcelDnaPack/ExcelDnaPackSettingsExtensions.cs b/src/Cake.ExcelDnaPack/ExcelDnaPackSettingsExtensions.cs new file mode 100644 index 0000000..5bdf4b9 --- /dev/null +++ b/src/Cake.ExcelDnaPack/ExcelDnaPackSettingsExtensions.cs @@ -0,0 +1,112 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Cake.Core.IO; + +namespace Cake.ExcelDnaPack +{ + /// + /// Extensions for . + /// + public static class ExcelDnaPackSettingsExtensions + { + /// + /// Set the path to the primary .dna file for the Excel-DNA add-in + /// + /// The settings. + /// The path to the primary .dna file for the Excel-DNA add-in + /// The instance with set to . + public static ExcelDnaPackSettings SetDnaFilePath(this ExcelDnaPackSettings settings, FilePath dnaFilePath) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + settings.DnaFilePath = dnaFilePath; + + return settings; + } + + /// + /// Enable interactive prompt to overwrite the output .xll file, if it already exists. + /// + /// The settings. + /// The instance with set to . + public static ExcelDnaPackSettings PromptBeforeOverwrite(this ExcelDnaPackSettings settings) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + settings.PromptBeforeOverwrite = true; + + return settings; + } + + /// + /// Disable compression (LZMA) of resources + /// + /// The settings. + /// The instance with set to . + public static ExcelDnaPackSettings NoCompression(this ExcelDnaPackSettings settings) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + settings.NoCompression = true; + + return settings; + } + + /// + /// Disable multi-threading to ensure deterministic order of packing + /// + /// The settings. + /// The instance with set to . + public static ExcelDnaPackSettings NoMultiThreading(this ExcelDnaPackSettings settings) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + settings.NoMultiThreading = true; + + return settings; + } + + /// + /// Set the output path for the packed .xll file. Default is -packed.xll. + /// + /// The settings. + /// The output path for the packed .xll file. + /// The instance with set to . + public static ExcelDnaPackSettings SetOutputXllFilePath(this ExcelDnaPackSettings settings, FilePath outputXllFilePath) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + settings.OutputXllFilePath = outputXllFilePath; + + return settings; + } + } +} diff --git a/src/Cake.ExcelDnaPack/ExcelDnaPackTool.cs b/src/Cake.ExcelDnaPack/ExcelDnaPackTool.cs new file mode 100644 index 0000000..61750e6 --- /dev/null +++ b/src/Cake.ExcelDnaPack/ExcelDnaPackTool.cs @@ -0,0 +1,157 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; +using Cake.Core; +using Cake.Core.Diagnostics; +using Cake.Core.IO; +using Cake.Core.Tooling; + +namespace Cake.ExcelDnaPack +{ + /// + /// ExcelDnaPack tool. + /// + public class ExcelDnaPackTool : Tool + { + /// + /// Initializes a new instance of the class. + /// + /// The file system. + /// The environment. + /// The process runner. + /// The tool locator. + /// Cake log instance. + public ExcelDnaPackTool(IFileSystem fileSystem, ICakeEnvironment environment, IProcessRunner processRunner, + IToolLocator tools, ICakeLog log) + : base(fileSystem, environment, processRunner, tools) + { + CakeLog = log ?? throw new ArgumentNullException(nameof(log)); + } + + /// + /// Cake log instance. + /// + public ICakeLog CakeLog { get; } + + /// + /// Run the ExcelDnaPack tool using the specified settings. + /// + /// The settings. + public void Run(ExcelDnaPackSettings settings) + { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + CakeLog.Verbose("Executing {0} tool", GetToolName()); + + EnsureSettingsAreValid(settings); + + var args = GetArguments(settings); + var processSettings = new ProcessSettings(); + + Run(settings, args, processSettings, postAction: null); + } + + /// + protected override string GetToolName() + { + return "ExcelDnaPack"; + } + + /// + protected override IEnumerable GetToolExecutableNames() + { + return new [] { "ExcelDnaPack.exe" }; + } + + private static void EnsureSettingsAreValid(ExcelDnaPackSettings settings) + { + if (settings.DnaFilePath is null) + { + throw new CakeException($"{nameof(settings.DnaFilePath)} setting is required"); + } + } + + private ProcessArgumentBuilder GetArguments(ExcelDnaPackSettings settings) + { + var args = new ProcessArgumentBuilder(); + + AppendDnaFilePath(args, settings); + AppendDisablePromptBeforeOverwrite(args, settings); + AppendNoCompression(args, settings); + AppendNoMultiThreading(args, settings); + AppendOutputXllFilePath(args, settings); + + CakeLog.Verbose("{0} arguments: [{1}]", GetToolName(), args.RenderSafe()); + + return args; + } + + private static void AppendDnaFilePath(ProcessArgumentBuilder args, ExcelDnaPackSettings settings) + { + if (settings.DnaFilePath is null) + { + return; + } + + args.AppendQuoted(settings.DnaFilePath.FullPath); + } + + private static void AppendDisablePromptBeforeOverwrite(ProcessArgumentBuilder args, ExcelDnaPackSettings settings) + { + // We inverted ExcelDnaPack's default here which is to always display the interactive prompt unless /Y is specified + if (settings.PromptBeforeOverwrite.GetValueOrDefault(false)) + { + return; + } + + args.Append("/Y"); + } + + private static void AppendNoCompression(ProcessArgumentBuilder args, ExcelDnaPackSettings settings) + { + if (!settings.NoCompression.GetValueOrDefault(false)) + { + return; + } + + args.Append("/NoCompression"); + } + + private static void AppendNoMultiThreading(ProcessArgumentBuilder args, ExcelDnaPackSettings settings) + { + if (!settings.NoMultiThreading.GetValueOrDefault(false)) + { + return; + } + + args.Append("/NoMultiThreading"); + } + + private static void AppendOutputXllFilePath(ProcessArgumentBuilder args, ExcelDnaPackSettings settings) + { + if (settings.OutputXllFilePath is null) + { + return; + } + + args.Append("/O"); + args.AppendQuoted(settings.OutputXllFilePath.FullPath); + } + } +} diff --git a/src/Cake.ExcelDnaPack/Namespaces.cs b/src/Cake.ExcelDnaPack/Namespaces.cs new file mode 100644 index 0000000..38bd001 --- /dev/null +++ b/src/Cake.ExcelDnaPack/Namespaces.cs @@ -0,0 +1,26 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Runtime.CompilerServices; + +namespace Cake.ExcelDnaPack +{ + /// + /// This namespace contain types used for operations using the ExcelDnaPack tool wrapper. + /// + [CompilerGenerated] + internal class NamespaceDoc + { + } +} diff --git a/test/Cake.ExcelDnaPack.Tests/Cake.ExcelDnaPack.Tests.csproj b/test/Cake.ExcelDnaPack.Tests/Cake.ExcelDnaPack.Tests.csproj new file mode 100644 index 0000000..0bf66c4 --- /dev/null +++ b/test/Cake.ExcelDnaPack.Tests/Cake.ExcelDnaPack.Tests.csproj @@ -0,0 +1,30 @@ + + + + net5.0;netcoreapp3.1;net461 + false + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackSettingsExtensionsTests.cs b/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackSettingsExtensionsTests.cs new file mode 100644 index 0000000..a460660 --- /dev/null +++ b/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackSettingsExtensionsTests.cs @@ -0,0 +1,68 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Cake.Core.IO; +using FluentAssertions; +using Xunit; + +namespace Cake.ExcelDnaPack.Tests +{ + public sealed class ExcelDnaPackSettingsExtensionsTests + { + [Fact] + public void Should_Set_DnaFilePath_via_SetDnaFilePath() + { + var settings = new ExcelDnaPackSettings() + .SetDnaFilePath("MyAddin.dna"); + + settings.DnaFilePath.FullPath.Should().Be(FilePath.FromString("MyAddin.dna").FullPath); + } + + [Fact] + public void Should_Set_PromptBeforeOverwrite_via_PromptBeforeOverwrite() + { + var settings = new ExcelDnaPackSettings() + .PromptBeforeOverwrite(); + + settings.PromptBeforeOverwrite.Should().Be(true); + } + + [Fact] + public void Should_Set_NoCompression_via_NoCompression() + { + var settings = new ExcelDnaPackSettings() + .NoCompression(); + + settings.NoCompression.Should().Be(true); + } + + [Fact] + public void Should_Set_NoMultiThreading_via_NoMultiThreading() + { + var settings = new ExcelDnaPackSettings() + .NoMultiThreading(); + + settings.NoMultiThreading.Should().Be(true); + } + + [Fact] + public void Should_Set_OutputXllFilePath_via_SetOutputXllFilePath() + { + var settings = new ExcelDnaPackSettings() + .SetOutputXllFilePath("MyAddin-packed.xll"); + + settings.OutputXllFilePath.FullPath.Should().Be(FilePath.FromString("MyAddin-packed.xll").FullPath); + } + } +} diff --git a/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackToolTests.cs b/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackToolTests.cs new file mode 100644 index 0000000..b671607 --- /dev/null +++ b/test/Cake.ExcelDnaPack.Tests/ExcelDnaPackToolTests.cs @@ -0,0 +1,152 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Cake.Core; +using Cake.Core.Diagnostics; +using Cake.ExcelDnaPack.Tests.Support; +using FluentAssertions; +using Xunit; +using Xunit.Abstractions; + +namespace Cake.ExcelDnaPack.Tests +{ + public sealed class ExcelDnaPackToolTests + { + private readonly ICakeLog _log; + + public ExcelDnaPackToolTests(ITestOutputHelper testOutputHelper) + { + _log = new XUnitLogger(testOutputHelper); + } + + [Fact] + public void Should_Throw_If_Settings_Are_Null() + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = null, + }; + + fixture.Invoking(f => f.Run()) + .Should().ThrowExactly() + .And.ParamName.Should().Be("settings"); + } + + [Fact] + public void Should_Throw_If_DnaFilePath_Is_Null() + { + var fixture = new ExcelDnaPackToolFixture(_log); + + fixture.Invoking(f => f.Run()) + .Should().ThrowExactly() + .And.Message.Should().Be($"{nameof(ExcelDnaPackSettings.DnaFilePath)} setting is required"); + } + + [Fact] + public void Should_Add_Required_DnaFilePath_and_Disable_PromptBeforeOverwrite_By_Default() + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = + { + DnaFilePath = "MyAddin.dna", + }, + }; + + var result = fixture.Run(); + + Assert.Equal(@"""MyAddin.dna"" /Y", result.Args); + } + + [Theory] + [InlineData(true, "")] + [InlineData(false, " /Y")] + [InlineData(null, " /Y")] + public void Should_Add_OverwriteXllIfExists_To_Arguments_If_true(bool? promptBeforeOverwrite, string expected) + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = + { + DnaFilePath = "MyAddin.dna", + PromptBeforeOverwrite = promptBeforeOverwrite, + }, + }; + + var result = fixture.Run(); + + Assert.Equal($@"""MyAddin.dna""{expected}", result.Args); + } + + [Theory] + [InlineData(true, " /NoCompression")] + [InlineData(false, "")] + [InlineData(null, "")] + public void Should_Add_NoCompression_To_Arguments_If_true(bool? noCompression, string expected) + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = + { + DnaFilePath = "MyAddin.dna", + NoCompression = noCompression, + }, + }; + + var result = fixture.Run(); + + Assert.Equal($@"""MyAddin.dna"" /Y{expected}", result.Args); + } + + [Theory] + [InlineData(true, " /NoMultiThreading")] + [InlineData(false, "")] + [InlineData(null, "")] + public void Should_Add_NoMultiThreading_To_Arguments_If_true(bool? noMultiThreading, string expected) + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = + { + DnaFilePath = "MyAddin.dna", + NoMultiThreading = noMultiThreading, + }, + }; + + var result = fixture.Run(); + + Assert.Equal($@"""MyAddin.dna"" /Y{expected}", result.Args); + } + + [Theory] + [InlineData("MyAddin-packed.xll", @" /O ""MyAddin-packed.xll""")] + [InlineData(null, "")] + public void Should_Add_OutputXllFilePath_To_Arguments_If_true(string outputXllFilePath, string expected) + { + var fixture = new ExcelDnaPackToolFixture(_log) + { + Settings = + { + DnaFilePath = "MyAddin.dna", + OutputXllFilePath = outputXllFilePath, + }, + }; + + var result = fixture.Run(); + + Assert.Equal($@"""MyAddin.dna"" /Y{expected}", result.Args); + } + } +} diff --git a/test/Cake.ExcelDnaPack.Tests/Support/ExcelDnaPackToolFixture.cs b/test/Cake.ExcelDnaPack.Tests/Support/ExcelDnaPackToolFixture.cs new file mode 100644 index 0000000..83489c8 --- /dev/null +++ b/test/Cake.ExcelDnaPack.Tests/Support/ExcelDnaPackToolFixture.cs @@ -0,0 +1,37 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Cake.Core.Diagnostics; +using Cake.Testing.Fixtures; + +namespace Cake.ExcelDnaPack.Tests.Support +{ + internal sealed class ExcelDnaPackToolFixture : ToolFixture + { + public ExcelDnaPackToolFixture(ICakeLog log) + : base("ExcelDnaPack.exe") + { + Log = log ?? throw new ArgumentNullException(nameof(log)); + } + + public ICakeLog Log { get; } + + protected override void RunTool() + { + var tool = new ExcelDnaPackTool(FileSystem, Environment, ProcessRunner, Tools, Log); + tool.Run(Settings); + } + } +} diff --git a/test/Cake.ExcelDnaPack.Tests/Support/XUnitLogger.cs b/test/Cake.ExcelDnaPack.Tests/Support/XUnitLogger.cs new file mode 100644 index 0000000..0e41aa9 --- /dev/null +++ b/test/Cake.ExcelDnaPack.Tests/Support/XUnitLogger.cs @@ -0,0 +1,41 @@ +// Copyright 2021 C. Augusto Proiete & Contributors +// +// Licensed under the MIT (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Cake.Core.Diagnostics; +using Xunit.Abstractions; + +namespace Cake.ExcelDnaPack.Tests.Support +{ + internal class XUnitLogger : ICakeLog + { + private readonly ITestOutputHelper _testOutputHelper; + + public XUnitLogger(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper)); + Verbosity = Verbosity.Diagnostic; + } + + public void Write(Verbosity verbosity, LogLevel level, string format, params object[] args) + { + if ((int)verbosity <= (int)Verbosity) + { + _testOutputHelper.WriteLine($"[{level}] {format}", args); + } + } + + public Verbosity Verbosity { get; set; } + } +}