diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 0000000..2e9eb0c --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,156 @@ +name: .NET Core + +# use https://marketplace.visualstudio.com/items?itemName=me-dutour-mathieu.vscode-github-actions to validate yml in vscode +env: + NUGET_PACKAGES_DIRECTORY: '.nupkg' + RESHARPER_CLI_NAME: 'JetBrains.ReSharper.CommandLineTools.Unix' + RESHARPER_CLI_VERSION: "2019.2.3" + DOCKER_DRIVER: overlay + CONTAINER_IMAGE: codeclimate/codeclimate + CONTAINER_TAG: '0.85.2' + rIds: ${{ secrets.rIds }} + dotnetVersion: 5.0.404 + +on: + pull_request: + branches: + - master + push: + branches: + - master + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.dotnetVersion}} + - name: Build with dotnet + run: | + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + cd DotNet.Bundle + dotnet build + dotnet pack + cd .. + dotnet build + + + # dotnet build -c Release + # dotnet pack -c Release + - name: Tests + run: | + dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='./TestResults/' + - name: Coverage Report + run: | + dotnet --version + dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools + ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:TextSummary; + ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:Html; + ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:Badges; + cat ./Reports/Summary.txt + - uses: actions/upload-artifact@v1 + with: + name: CodeCoverage + path: Reports + - name: Resharper Code Quality + run: | + # apt update && apt install -y curl zip unzip + curl -LO "https://download.jetbrains.com/resharper/ReSharperUltimate.$RESHARPER_CLI_VERSION/$RESHARPER_CLI_NAME.$RESHARPER_CLI_VERSION.zip" + unzip -q $RESHARPER_CLI_NAME.$RESHARPER_CLI_VERSION.zip -d "resharper" + mkdir -p CodeQuality + files=(*.sln) + # sh ./resharper/dupfinder.sh "${files[0]}" --output=CodeQuality/dupfinderReport.html --format=Html + # sh ./resharper/inspectcode.sh "${files[0]}" --output=CodeQuality/inspectcodeReport.html --format=Html + - uses: actions/upload-artifact@v1 + with: + name: CodeQuality + path: CodeQuality + # - name: upload release + # uses: actions/upload-artifact@v2 + # if: ${{ env.rIds }} != '' + # with: + # name: Release_unix + # path: Release/post + + build-win: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.dotnetVersion}} + - name: Build with dotnet + run: | + set DOTNET_CLI_TELEMETRY_OPTOUT=1 + cd DotNet.Bundle + dotnet build + dotnet pack + cd .. + dotnet build + + + # dotnet build -c Release + # dotnet pack -c Release + - name: Tests + run: | + dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='.\TestResults\' + # - name: prerelease + # if: ${{ env.rIds }} != '' + # run: | + # echo "build, obfuscate, and release" + # dotnet tool install Obfuscar.GlobalTool --tool-path tools --version 2.2.28 + # .\scripts\extractRelease.cmd + # set rIds=$env:rIds + # .\scripts\pipeline.cmd + # .\scripts\finalRelease.cmd + # - name: upload release + # uses: actions/upload-artifact@v2 + # if: ${{ env.rIds }} != '' + # with: + # name: Release_win + # path: Release\post + + code_docs: + runs-on: windows-latest + name: code documentation + steps: + - uses: actions/checkout@v1 + - name: docfx + run: | + curl -LO "https://github.com/dotnet/docfx/releases/download/v2.48/docfx.zip" + powershell.exe -NoP -NonI -Command "Expand-Archive '.\docfx.zip' '.\docfx\'" + ./docfx/docfx.exe + - uses: actions/upload-artifact@v1 + with: + name: CodeDocs + path: _site + + security: + runs-on: ubuntu-latest + name: Snyk Security Scan + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.dotnetVersion}} + - name: Build with dotnet + run: | + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + cd DotNet.Bundle + dotnet build + dotnet pack + cd .. + dotnet build + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/dotnet@master + with: + args: --file=MyProject.sln + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.gitignore b/.gitignore index 8513608..4b92e93 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,8 @@ msbuild.wrn # Intellij Idea .idea/ + + +TestResults/ +docs/ +docfx*/ \ No newline at end of file diff --git a/DotNet.Bundle/AppBundler.cs b/DotNet.Bundle/AppBundler.cs index 92fd5b3..914bec9 100644 --- a/DotNet.Bundle/AppBundler.cs +++ b/DotNet.Bundle/AppBundler.cs @@ -4,10 +4,10 @@ namespace Dotnet.Bundle { public class AppBundler { - private readonly BundleAppTask _task; + private readonly IBundleAppTask _task; private readonly StructureBuilder _builder; - public AppBundler(BundleAppTask task, StructureBuilder builder) + public AppBundler(IBundleAppTask task, StructureBuilder builder) { _task = task; _builder = builder; @@ -33,8 +33,8 @@ private void CopyFiles(DirectoryInfo source, DirectoryInfo target, DirectoryInfo { var path = Path.Combine(target.FullName, fileInfo.Name); - _task.Log.LogMessage($"Copying file from: {fileInfo.FullName}"); - _task.Log.LogMessage($"Copying to destination: {path}"); + _task.LogMessage($"Copying file from: {fileInfo.FullName}"); + _task.LogMessage($"Copying to destination: {path}"); fileInfo.CopyTo(path, true); } @@ -54,21 +54,21 @@ private void CopyIcon(DirectoryInfo source, DirectoryInfo destination) var iconName = _task.CFBundleIconFile; if (string.IsNullOrWhiteSpace(iconName)) { - _task.Log.LogMessage($"No icon is specified for bundle"); + _task.LogMessage($"No icon is specified for bundle"); return; } var sourcePath = Path.Combine(source.FullName, iconName); - _task.Log.LogMessage($"Icon file source for bundle is: {sourcePath}"); + _task.LogMessage($"Icon file source for bundle is: {sourcePath}"); var targetPath = Path.Combine(destination.FullName, Path.GetFileName(iconName)); - _task.Log.LogMessage($"Icon file destination for bundle is: {targetPath}"); + _task.LogMessage($"Icon file destination for bundle is: {targetPath}"); var sourceFile = new FileInfo(sourcePath); if (sourceFile.Exists) { - _task.Log.LogMessage($"Copying icon file to destination: {targetPath}"); + _task.LogMessage($"Copying icon file to destination: {targetPath}"); sourceFile.CopyTo(targetPath); } } diff --git a/DotNet.Bundle/BundleAppTask.cs b/DotNet.Bundle/BundleAppTask.cs index bd9b697..3149804 100644 --- a/DotNet.Bundle/BundleAppTask.cs +++ b/DotNet.Bundle/BundleAppTask.cs @@ -3,14 +3,51 @@ namespace Dotnet.Bundle { - public class BundleAppTask : Task + public interface IBundleAppTask + { + string OutDir { get; set; } + + string PublishDir { get; set; } + + string CFBundleName { get; set; } + + string CFBundleDisplayName { get; set; } + + string CFBundleIdentifier { get; set; } + + string CFBundleVersion { get; set; } + + string CFBundlePackageType { get; set; } + + string CFBundleSignature { get; set; } + + string CFBundleExecutable { get; set; } + + string CFBundleIconFile { get; set; } + + string CFBundleShortVersionString { get; set; } + + string NSPrincipalClass { get; set; } + + bool NSHighResolutionCapable { get; set; } + + bool NSRequiresAquaSystemAppearance { get; set; } + + bool? NSRequiresAquaSystemAppearanceNullable { get; set; } + + ITaskItem[] CFBundleURLTypes { get; set; } + + bool Execute(); + void LogMessage(string message); + } + public class BundleAppTask : Task, IBundleAppTask { [Required] public string OutDir { get; set; } - + [Required] public string PublishDir { get; set; } - + [Required] public string CFBundleName { get; set; } @@ -36,31 +73,36 @@ public class BundleAppTask : Task public string CFBundleIconFile { get; set; } [Required] - public string CFBundleShortVersionString { get; set; } + public string CFBundleShortVersionString { get; set; } [Required] public string NSPrincipalClass { get; set; } - + [Required] public bool NSHighResolutionCapable { get; set; } - public bool NSRequiresAquaSystemAppearance { + public bool NSRequiresAquaSystemAppearance + { get => NSRequiresAquaSystemAppearanceNullable.Value; set => NSRequiresAquaSystemAppearanceNullable = value; } - internal bool? NSRequiresAquaSystemAppearanceNullable { get; private set; } + public bool? NSRequiresAquaSystemAppearanceNullable { get; set; } public ITaskItem[] CFBundleURLTypes { get; set; } + public void LogMessage(string message) + { + Log.LogMessage(message); + } public override bool Execute() { var builder = new StructureBuilder(this); builder.Build(); - + var bundler = new AppBundler(this, builder); bundler.Bundle(); - + var plistWriter = new PlistWriter(this, builder); plistWriter.Write(); diff --git a/DotNet.Bundle/PlistWriter.cs b/DotNet.Bundle/PlistWriter.cs index ba32461..831b1f4 100644 --- a/DotNet.Bundle/PlistWriter.cs +++ b/DotNet.Bundle/PlistWriter.cs @@ -1,21 +1,21 @@ using System; -using System.Collections; +using System.Collections; using System.IO; -using System.Linq; +using System.Linq; using System.Xml; -using Microsoft.Build.Framework; - +using Microsoft.Build.Framework; + namespace Dotnet.Bundle { public class PlistWriter { - private readonly BundleAppTask _task; - private readonly StructureBuilder _builder; - + private readonly IBundleAppTask _task; + private readonly StructureBuilder _builder; + private static readonly string[] ArrayTypeProperties = { "CFBundleURLSchemes" }; private const char Separator = ';'; - public PlistWriter(BundleAppTask task, StructureBuilder builder) + public PlistWriter(IBundleAppTask task, StructureBuilder builder) { _task = task; _builder = builder; @@ -31,7 +31,7 @@ public void Write() var path = Path.Combine(_builder.ContentsDirectory, "Info.plist"); - _task.Log.LogMessage($"Writing property list file: {path}"); + _task.LogMessage($"Writing property list file: {path}"); using (var xmlWriter = XmlWriter.Create(path, settings)) { xmlWriter.WriteStartDocument(); @@ -58,14 +58,14 @@ public void Write() WriteProperty(xmlWriter, nameof(_task.NSPrincipalClass), _task.NSPrincipalClass); WriteProperty(xmlWriter, nameof(_task.NSHighResolutionCapable), _task.NSHighResolutionCapable); - if (_task.NSRequiresAquaSystemAppearanceNullable.HasValue) - { + if (_task.NSRequiresAquaSystemAppearanceNullable.HasValue) + { WriteProperty(xmlWriter, nameof(_task.NSRequiresAquaSystemAppearance), _task.NSRequiresAquaSystemAppearanceNullable.Value); } - if (_task.CFBundleURLTypes.Length != 0) - { - WriteProperty(xmlWriter, nameof(_task.CFBundleURLTypes), _task.CFBundleURLTypes); + if (_task.CFBundleURLTypes.Length != 0) + { + WriteProperty(xmlWriter, nameof(_task.CFBundleURLTypes), _task.CFBundleURLTypes); } @@ -104,32 +104,32 @@ private void WriteProperty(XmlWriter xmlWriter, string name, bool value) } xmlWriter.WriteEndElement(); - } - + } + private void WriteProperty(XmlWriter xmlWriter, string name, string[] values) { if (values.Length != 0) { xmlWriter.WriteStartElement("key"); xmlWriter.WriteString(name); - xmlWriter.WriteEndElement(); - - xmlWriter.WriteStartElement("array"); - foreach (var value in values) - { - if (!string.IsNullOrEmpty(value)) - { - xmlWriter.WriteStartElement("string"); - xmlWriter.WriteString(value); - xmlWriter.WriteEndElement(); - } + xmlWriter.WriteEndElement(); + + xmlWriter.WriteStartElement("array"); + foreach (var value in values) + { + if (!string.IsNullOrEmpty(value)) + { + xmlWriter.WriteStartElement("string"); + xmlWriter.WriteString(value); + xmlWriter.WriteEndElement(); + } } xmlWriter.WriteEndElement(); } - } - - + } + + private void WriteProperty(XmlWriter xmlWriter, string name, ITaskItem[] values) { xmlWriter.WriteStartElement("key"); @@ -138,29 +138,29 @@ private void WriteProperty(XmlWriter xmlWriter, string name, ITaskItem[] values) xmlWriter.WriteStartElement("array"); - foreach (var value in values) - { - xmlWriter.WriteStartElement("dict"); - var metadataDictionary = value.CloneCustomMetadata(); - - foreach (DictionaryEntry entry in metadataDictionary) - { - var dictValue = entry.Value.ToString(); - var dictKey = entry.Key.ToString(); - - if (dictValue.Contains(Separator.ToString()) || ArrayTypeProperties.Contains(dictKey)) //array - { - WriteProperty(xmlWriter, dictKey, dictValue.Split(Separator)); - } - else - { - WriteProperty(xmlWriter, dictKey, dictValue); - } - } - - xmlWriter.WriteEndElement(); //End dict - } - + foreach (var value in values) + { + xmlWriter.WriteStartElement("dict"); + var metadataDictionary = value.CloneCustomMetadata(); + + foreach (DictionaryEntry entry in metadataDictionary) + { + var dictValue = entry.Value.ToString(); + var dictKey = entry.Key.ToString(); + + if (dictValue.Contains(Separator.ToString()) || ArrayTypeProperties.Contains(dictKey)) //array + { + WriteProperty(xmlWriter, dictKey, dictValue.Split(Separator)); + } + else + { + WriteProperty(xmlWriter, dictKey, dictValue); + } + } + + xmlWriter.WriteEndElement(); //End dict + } + xmlWriter.WriteEndElement(); //End outside array } } diff --git a/DotNet.Bundle/StructureBuilder.cs b/DotNet.Bundle/StructureBuilder.cs index 2737b54..93a697f 100644 --- a/DotNet.Bundle/StructureBuilder.cs +++ b/DotNet.Bundle/StructureBuilder.cs @@ -4,9 +4,9 @@ namespace Dotnet.Bundle { public class StructureBuilder { - private BundleAppTask _task; + private IBundleAppTask _task; - public StructureBuilder(BundleAppTask task) + public StructureBuilder(IBundleAppTask task) { _task = task; } @@ -25,24 +25,24 @@ public StructureBuilder(BundleAppTask task) public void Build() { - _task.Log.LogMessage($"Publish directory is: {PublishDirectory}"); + _task.LogMessage($"Publish directory is: {PublishDirectory}"); if (Directory.Exists(AppDirectory)) { - _task.Log.LogMessage($"Clearing bundle directory"); + _task.LogMessage($"Clearing bundle directory"); Directory.Delete(AppDirectory, true); } - _task.Log.LogMessage($"Creating bundle directory: {AppDirectory}"); + _task.LogMessage($"Creating bundle directory: {AppDirectory}"); Directory.CreateDirectory(AppDirectory); - _task.Log.LogMessage($"Creating contents directory: {ContentsDirectory}"); + _task.LogMessage($"Creating contents directory: {ContentsDirectory}"); Directory.CreateDirectory(ContentsDirectory); - _task.Log.LogMessage($"Creating MacOS directory: {MacosDirectory}"); + _task.LogMessage($"Creating MacOS directory: {MacosDirectory}"); Directory.CreateDirectory(MacosDirectory); - _task.Log.LogMessage($"Creating resources directory: {ResourcesDirectory}"); + _task.LogMessage($"Creating resources directory: {ResourcesDirectory}"); Directory.CreateDirectory(ResourcesDirectory); } } diff --git a/README.md b/README.md index 9f288da..81c83ab 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ Install MSBuild task via NuGet package: `Dotnet.Bundle` ``` +### Development +* `cd TestBundle` +* run `dotnet msbuild -t:BundleApp -p:RuntimeIdentifier=osx-x64` +* verify `Build/Debug/net5.0/osx-x64/publish` contents + ### Using the tool ``` diff --git a/TestBundle/TestBundle.csproj b/TestBundle/TestBundle.csproj index cd4d9c6..1ee1494 100644 --- a/TestBundle/TestBundle.csproj +++ b/TestBundle/TestBundle.csproj @@ -7,7 +7,7 @@ x64 osx-x64 $(RestoreSources);..\\Dotnet.Bundle\\bin\\$(Configuration)\\ - 9.9.999952 + 0.9.14 diff --git a/Tests/Data/PlistWriter/TestWrite.txt b/Tests/Data/PlistWriter/TestWrite.txt new file mode 100644 index 0000000..7d93b72 --- /dev/null +++ b/Tests/Data/PlistWriter/TestWrite.txt @@ -0,0 +1,10 @@ + + + + + CFBundleDisplayName + MyApp + NSHighResolutionCapable + + + \ No newline at end of file diff --git a/Tests/Helper/DataLoader.cs b/Tests/Helper/DataLoader.cs new file mode 100644 index 0000000..a6249af --- /dev/null +++ b/Tests/Helper/DataLoader.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json; + +namespace Tests.Helper +{ + public class DataLoader + { + public static string LoadFileText(string path, string testData = "") + { + var dataDir = Directory.GetCurrentDirectory() + rootPath; + var filePath = dataDir + path + testData + ".txt"; + + if (File.Exists(filePath)) + { + var fileContents = File.ReadAllText(filePath); + return fileContents; + } + else + { + var msg = $"File Data/{path}{testData}.txt doesn't exist"; + Console.WriteLine(msg); + throw new System.Exception(msg); + } + } + public static Dictionary loadJsonDictonary(string path, string testData = "") + { + var dataDir = Directory.GetCurrentDirectory() + rootPath; + if (string.IsNullOrWhiteSpace(testData)) + { + // set equal to t type + testData = typeof(t).Name.ToString(); + } + + if (File.Exists(dataDir + path + testData + ".json")) + { + var fileContents = File.ReadAllText(dataDir + path + testData + ".json"); + var result = JsonConvert.DeserializeObject>(fileContents); + return result; + } + else + { + var msg = "File Data/" + path + testData + ".json doesn't exist"; + Console.WriteLine(msg); + throw new System.Exception(msg); + } + } + /// + /// initialize a json list, helper method to create mock data quickly + /// + /// + public static void initJson(List data = null, string path = "Repository/", string testData = "") where T : class, new() + { + var dataDir = Directory.GetCurrentDirectory() + rootPath; + if (string.IsNullOrWhiteSpace(testData)) + { + // set equal to t type + testData = typeof(T).Name.ToString(); + } + if (data == null) + { + data = new List() { new T() { } }; + } + if (!File.Exists(dataDir + path + testData + ".json")) + { + // should serialize without null + File.WriteAllText(dataDir + path + testData + ".json", + JsonConvert.SerializeObject(data + // ,Newtonsoft.Json.Formatting.None, + // new JsonSerializerSettings + // { + // NullValueHandling = NullValueHandling.Ignore + // } + ) + ); + } + } + + public const string rootPath = "/../../../Data/"; + + /// + /// used for skipped tests + /// + /// + /// + /// + /// + public static string DataExists(string path = "Repository/", string testData = "") + { + var dataDir = Directory.GetCurrentDirectory() + rootPath; + if (string.IsNullOrWhiteSpace(testData)) + { + // set equal to t type + testData = typeof(T).Name.ToString(); + } + + var filePath = dataDir + path + testData + ".json"; + + if (File.Exists(filePath)) + { + return true.ToString(); + } + return filePath; + } + + /// + /// parse through a json array into a c# list + /// + /// + /// + /// + /// + public static List loadJsonArray(string path = "Repository/", string testData = "") where T : class, new() + { + var dataDir = Directory.GetCurrentDirectory() + rootPath; + if (string.IsNullOrWhiteSpace(testData)) + { + // set equal to t type + testData = typeof(T).Name.ToString(); + } + + if (File.Exists(dataDir + path + testData + ".json")) + { + var fileContents = File.ReadAllText(dataDir + path + testData + ".json"); + var result = JsonConvert.DeserializeObject>(fileContents); + return result; + } + else + { + // auto create a default + initJson(path: path, testData: testData); + var msg = "File Data/" + path + testData + ".json doesn't exist"; + Console.WriteLine(msg); + throw new System.Exception(msg); + } + } + } +} \ No newline at end of file diff --git a/Tests/PlistWriterShould.cs b/Tests/PlistWriterShould.cs new file mode 100644 index 0000000..2159649 --- /dev/null +++ b/Tests/PlistWriterShould.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using Dotnet.Bundle; +using Moq; +using Tests.Helper; +using Xunit; + +namespace Tests +{ + + public class PlistWriterShould + { + private StructureBuilder _builder { get; set; } + private IBundleAppTask _task { get; set; } + public PlistWriterShould() + { + var path = Path.Combine(Directory.GetCurrentDirectory()); + + var taskMock = Mock.Of(m => + m.OutDir == path && + m.PublishDir == path && + m.CFBundleDisplayName == "MyApp" + ); + + Mock.Get(taskMock).Setup(s => s.LogMessage(It.IsAny())) + .Callback((string message) => + { + Console.WriteLine(message); + }); + + + // taskMock.Setup(x => x.LogMessage(It.IsAny())) + // .Callback((string message) => + // { + // Console.WriteLine(message); + // }); + // _task = new BundleAppTask(); + + _task = taskMock; + // _task.OutDir = path; + // _task.PublishDir = "test"; + _builder = new StructureBuilder(_task); + _builder.Build(); + } + [Fact] + public void TestWrite() + { + var plistWriter = new PlistWriter(_task, _builder); + plistWriter.Write(); + + var plistPath = Path.Combine(_builder.ContentsDirectory, "Info.plist"); + Assert.True(File.Exists(plistPath), "Info.plist was not written"); + + var result = File.ReadAllText(plistPath); + + var testData = "TestWrite"; + var classPath = $"{typeof(PlistWriter).Name.ToString()}/"; + var expectedResult = DataLoader.LoadFileText(classPath, "TestWrite"); + + if (result != expectedResult) + { + var dataDir = $"{Directory.GetCurrentDirectory()}{DataLoader.rootPath}{classPath}{testData}.txt"; + + File.WriteAllText(dataDir, result); + } + + Assert.Equal(expectedResult, result); + } + } + + +} \ No newline at end of file diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj new file mode 100644 index 0000000..971c9b7 --- /dev/null +++ b/Tests/Tests.csproj @@ -0,0 +1,33 @@ + + + + net5.0 + + false + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/docfx.json b/docfx.json new file mode 100644 index 0000000..cfafbff --- /dev/null +++ b/docfx.json @@ -0,0 +1,69 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "*/**.csproj" + ] + } + ], + "dest": "docs", + "disableGitFeatures": false, + "disableDefaultFilter": false + } + ], + "build": { + "content": [ + { + "files": [ + "docs/**.yml" + ] + }, + { + "files": [ + "articles/**.md", + "articles/**/toc.yml", + "toc.yml", + "*.md" + ] + } + ], + "resource": [ + { + "files": [ + "images/**" + ] + } + ], + "overwrite": [ + { + "files": [ + "apidoc/**.md" + ], + "exclude": [ + "obj/**", + "_site/**", + "bin/**" + ] + } + ], + "dest": "_site", + "globalMetadataFiles": [], + "globalMetaData": { + "_enableSearch": true + }, + "fileMetadataFiles": [], + "template": [ + "statictoc" + ], + "postProcessors": [ + "ExtractSearchIndex" + ], + "markdownEngineName": "markdig", + "noLangKeyword": false, + "keepFileLink": false, + "cleanupCacheHistory": false, + "disableGitFeatures": false + } +} \ No newline at end of file diff --git a/dotnet-bundle.sln b/dotnet-bundle.sln index a65917c..2b9f47d 100644 --- a/dotnet-bundle.sln +++ b/dotnet-bundle.sln @@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet.Bundle", "DotNet.Bun EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBundle", "TestBundle\TestBundle.csproj", "{967D02F2-36B8-4A22-A024-53F81FEA7C1A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{B432AEAE-F3D2-44A6-B0D1-5D64EE07D22C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -19,5 +21,9 @@ Global {967D02F2-36B8-4A22-A024-53F81FEA7C1A}.Debug|Any CPU.Build.0 = Debug|Any CPU {967D02F2-36B8-4A22-A024-53F81FEA7C1A}.Release|Any CPU.ActiveCfg = Release|Any CPU {967D02F2-36B8-4A22-A024-53F81FEA7C1A}.Release|Any CPU.Build.0 = Release|Any CPU + {B432AEAE-F3D2-44A6-B0D1-5D64EE07D22C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B432AEAE-F3D2-44A6-B0D1-5D64EE07D22C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B432AEAE-F3D2-44A6-B0D1-5D64EE07D22C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B432AEAE-F3D2-44A6-B0D1-5D64EE07D22C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal