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