diff --git a/.build/Build.csproj b/.build/Build.csproj new file mode 100644 index 00000000..7d4f7fe1 --- /dev/null +++ b/.build/Build.csproj @@ -0,0 +1,11 @@ + + + Exe + net7.0 + enable + $(MSBuildProjectDirectory) + + + + + \ No newline at end of file diff --git a/.build/Build.sln b/.build/Build.sln new file mode 100644 index 00000000..5e0a3062 --- /dev/null +++ b/.build/Build.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build", "Build.csproj", "{86E7FFCA-81BE-403B-A2EE-61D4C8526111}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86E7FFCA-81BE-403B-A2EE-61D4C8526111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86E7FFCA-81BE-403B-A2EE-61D4C8526111}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86E7FFCA-81BE-403B-A2EE-61D4C8526111}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86E7FFCA-81BE-403B-A2EE-61D4C8526111}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/.build/BuildContext.cs b/.build/BuildContext.cs new file mode 100644 index 00000000..a5a82d57 --- /dev/null +++ b/.build/BuildContext.cs @@ -0,0 +1,48 @@ +using System.IO; +using Cake.Common; +using Cake.Common.Build; +using Cake.Common.Xml; +using Cake.Core; +using Cake.Frosting; + +namespace BuildScripts; + +public sealed class BuildContext : FrostingContext +{ + public readonly string ArtifactsDirectory; + public readonly string Version; + public readonly string? RepositoryOwner; + public readonly string? RepositoryUrl; + public readonly bool IsTag; + public readonly bool IsRunningOnGitHubActions; + public readonly string? GitHubToken; + public readonly string? NuGetAccessToken; + public readonly string MonoGameAsepritePath; + public readonly string MonoGameAsepriteContentPipelinePath; + public readonly string MonoGameAsepriteTestsPath; + + public BuildContext(ICakeContext context) : base(context) + { + ArtifactsDirectory = context.Argument(nameof(ArtifactsDirectory), ".artifacts"); + MonoGameAsepritePath = context.Argument(nameof(MonoGameAsepritePath), "source/MonoGame.Aseprite/MonoGame.Aseprite.csproj"); + MonoGameAsepriteContentPipelinePath = context.Argument(nameof(MonoGameAsepriteContentPipelinePath), "source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj"); + MonoGameAsepriteTestsPath = context.Argument(nameof(MonoGameAsepriteTestsPath), "tests/MonoGame.Aseprite.Tests/MonoGame.Aseprite.Tests.csproj"); + Version = context.XmlPeek("source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", "/Project/PropertyGroup/Version"); + + IsRunningOnGitHubActions = context.BuildSystem().IsRunningOnGitHubActions; + if (IsRunningOnGitHubActions) + { + RepositoryOwner = context.EnvironmentVariable("GITHUB_REPOSITORY_OWNER"); + RepositoryUrl = $"https://github.com/{context.EnvironmentVariable("GITHUB_REPOSITORY")}"; + GitHubToken = context.EnvironmentVariable("GITHUB_TOKEN"); + IsTag = context.EnvironmentVariable("GITHUB_REF_TYPE") == "tag"; + + if (IsTag) + { + NuGetAccessToken = context.EnvironmentVariable("NUGET_ACCESS_TOKEN"); + } + } + } + + +} \ No newline at end of file diff --git a/.build/BuildTask.cs b/.build/BuildTask.cs new file mode 100644 index 00000000..a923611c --- /dev/null +++ b/.build/BuildTask.cs @@ -0,0 +1,28 @@ +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.Build; +using Cake.Common.Tools.DotNet.MSBuild; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(BuildTask))] +public sealed class BuildTask : FrostingTask +{ + public override void Run(BuildContext context) + { + DotNetMSBuildSettings msBuildSettings = new DotNetMSBuildSettings(); + msBuildSettings.WithProperty("Version", context.Version); + + DotNetBuildSettings buildSettings = new DotNetBuildSettings() + { + MSBuildSettings = msBuildSettings, + Configuration = "Release", + Verbosity = DotNetVerbosity.Minimal, + NoLogo = true + }; + + context.DotNetBuild(context.MonoGameAsepritePath, buildSettings); + context.DotNetBuild(context.MonoGameAsepriteContentPipelinePath, buildSettings); + context.DotNetBuild(context.MonoGameAsepriteTestsPath, buildSettings); + } +} \ No newline at end of file diff --git a/.build/DeployToGithubTask.cs b/.build/DeployToGithubTask.cs new file mode 100644 index 00000000..49c78b0c --- /dev/null +++ b/.build/DeployToGithubTask.cs @@ -0,0 +1,22 @@ +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.NuGet.Push; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(DeployToGitHubTask))] +public sealed class DeployToGitHubTask : FrostingTask +{ + public override bool ShouldRun(BuildContext context) => context.IsRunningOnGitHubActions; + + public override void Run(BuildContext context) + { + DotNetNuGetPushSettings pushSettings = new DotNetNuGetPushSettings() + { + Source = $"https://nuget.pkg.github.com/{context.RepositoryOwner}/index.json", + ApiKey = context.GitHubToken + }; + + context.DotNetNuGetPush($"{context.ArtifactsDirectory}/*.nupkg", pushSettings); + } +} \ No newline at end of file diff --git a/.build/DeployToNuGetTask.cs b/.build/DeployToNuGetTask.cs new file mode 100644 index 00000000..b10e686a --- /dev/null +++ b/.build/DeployToNuGetTask.cs @@ -0,0 +1,28 @@ +using System; +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.NuGet.Push; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(DeployToNuGetTask))] +public sealed class DeployToNuGetTask : FrostingTask +{ + public override bool ShouldRun(BuildContext context) => + context.IsRunningOnGitHubActions && + context.IsTag && + !string.IsNullOrEmpty(context.RepositoryOwner) && + context.RepositoryOwner.Equals("AristurtleDev", StringComparison.InvariantCultureIgnoreCase); + + + public override void Run(BuildContext context) + { + DotNetNuGetPushSettings pushSettings = new DotNetNuGetPushSettings() + { + Source = "https://api.nuget.org/v3/index.json", + ApiKey = context.NuGetAccessToken + }; + + context.DotNetNuGetPush($"{context.ArtifactsDirectory}/*.nupkg", pushSettings); + } +} \ No newline at end of file diff --git a/.build/PackageTask.cs b/.build/PackageTask.cs new file mode 100644 index 00000000..7d9abe99 --- /dev/null +++ b/.build/PackageTask.cs @@ -0,0 +1,30 @@ +using Cake.Common.IO; +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.MSBuild; +using Cake.Common.Tools.DotNet.Pack; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(PackageTask))] +public sealed class PackageTask : FrostingTask +{ + public override void Run(BuildContext context) + { + context.CleanDirectory(context.ArtifactsDirectory); + context.CreateDirectory(context.ArtifactsDirectory); + + DotNetMSBuildSettings msBuildSettings = new DotNetMSBuildSettings(); + msBuildSettings.WithProperty("Version", context.Version); + msBuildSettings.WithProperty("PackageVersion", context.Version); + + DotNetPackSettings packSettings = new DotNetPackSettings() + { + Configuration = "Release", + OutputDirectory = context.ArtifactsDirectory, + MSBuildSettings = msBuildSettings + }; + + context.DotNetPack(context.MonoGameAsepritePath, packSettings); + } +} \ No newline at end of file diff --git a/.build/Program.cs b/.build/Program.cs new file mode 100644 index 00000000..ebb78742 --- /dev/null +++ b/.build/Program.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using Cake.Core; +using Cake.Core.Diagnostics; +using Cake.Frosting; + +namespace BuildScripts; + +public static class Program +{ + public static int Main(string[] args) + { + return new CakeHost() + .UseContext() + .UseWorkingDirectory("../") + .Run(args); + } +} + +[TaskName("Default")] +[IsDependentOn(typeof(RestoreTask))] +[IsDependentOn(typeof(BuildTask))] +[IsDependentOn(typeof(TestTask))] +[IsDependentOn(typeof(PackageTask))] +public sealed class DefaultTask : FrostingTask {} + +[TaskName("Deploy")] +[IsDependentOn(typeof(DeployToGitHubTask))] +[IsDependentOn(typeof(DeployToNuGetTask))] +public sealed class DeployTask : FrostingTask {} \ No newline at end of file diff --git a/.build/RestoreTask.cs b/.build/RestoreTask.cs new file mode 100644 index 00000000..5337ef65 --- /dev/null +++ b/.build/RestoreTask.cs @@ -0,0 +1,20 @@ +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.Restore; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(RestoreTask))] +public sealed class RestoreTask : FrostingTask +{ + public override void Run(BuildContext context) + { + DotNetRestoreSettings restoreSettings = new DotNetRestoreSettings() + { + Verbosity = DotNetVerbosity.Quiet + }; + context.DotNetRestore(context.MonoGameAsepritePath, restoreSettings); + context.DotNetRestore(context.MonoGameAsepriteContentPipelinePath, restoreSettings); + context.DotNetRestore(context.MonoGameAsepriteTestsPath, restoreSettings); + } +} \ No newline at end of file diff --git a/.build/TestTask.cs b/.build/TestTask.cs new file mode 100644 index 00000000..0c0c2672 --- /dev/null +++ b/.build/TestTask.cs @@ -0,0 +1,18 @@ +using Cake.Common.Tools.DotNet; +using Cake.Common.Tools.DotNet.Test; +using Cake.Frosting; + +namespace BuildScripts; + +[TaskName(nameof(TestTask))] +public sealed class TestTask : FrostingTask +{ + public override void Run(BuildContext context) + { + DotNetTestSettings testSettings = new DotNetTestSettings() + { + Configuration = "Release", + }; + context.DotNetTest(context.MonoGameAsepriteTestsPath, testSettings); + } +} \ No newline at end of file diff --git a/.github/release-notes.txt b/.github/release-notes.txt index cd49da5f..fc4048f9 100644 --- a/.github/release-notes.txt +++ b/.github/release-notes.txt @@ -48,4 +48,7 @@ ## 5.1.1 - Resolved issue where using Linked Cels can cause an out of bounds exception. +## 5.1.2 +- Resolves issue where AsepriteFile.TryGetSlice always returned false even when slice exists + \ No newline at end of file diff --git a/.github/workflows/buildandtest.yml b/.github/workflows/buildandtest.yml index 40540222..053ce43f 100644 --- a/.github/workflows/buildandtest.yml +++ b/.github/workflows/buildandtest.yml @@ -1,10 +1,9 @@ name: build-and-test on: push: + tags: [v*] pull_request: - branches: - - 'release' - - 'main' + branches: ['main'] env: @@ -12,22 +11,50 @@ env: jobs: - build: + build-test-pack-job: + name: "Build-Test-Pack" runs-on: ubuntu-latest steps: - - name: Clone Repository + - name: "Clone Repository" uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Setup .NET + - name: "Setup .NET" uses: actions/setup-dotnet@v3 with: dotnet-version: ${{ env.DOTNET_VERSION }} - - name: Cake Target Test - shell: bash - run: | - cd ./.tools - dotnet tool restore - dotnet cake --target=Test \ No newline at end of file + - name: "CAKE (Build -> Test -> Package)" + run: dotnet run --project ./.build/Build.csproj -- --target=Default + + - name: "Upload Artifacts For Deploy" + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@main + with: + name: MonoGame.Aseprite + path: ./artifacts/* + + deploy-job: + name: "Deploy NuGets" + runs-on: ubuntu-latest + permissions: + packages: write + contents: write + needs: [build-test-pack-job] + if: ${{ github.event_name == 'push' }} + steps: + - name: "Clone Repository" + uses: actions/checkout@v4 + + - name: "Download Artifacts For Deploy" + uses: actions/download-artifact@v3 + with: + name: MonoGame.Aseprite + path: artifacts + + - name: "Push Packages" + run: dotnet run --project ./.build/Build.csproj -- --target=Deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUGET_ACCESS_TOKEN: ${{ secrets.NUGET_ACCESS_TOKEN }} \ No newline at end of file diff --git a/.nuget/README.md b/.nuget/README.md index a1bffa32..c6c3cb17 100644 --- a/.nuget/README.md +++ b/.nuget/README.md @@ -3,7 +3,7 @@ A Cross Platform C# Library That Adds Support For Aseprite Files in MonoGame Projects. [![build-and-test](https://github.com/AristurtleDev/monogame-aseprite/actions/workflows/buildandtest.yml/badge.svg)](https://github.com/AristurtleDev/monogame-aseprite/actions/workflows/buildandtest.yml) -[![Nuget 5.1.1](https://img.shields.io/nuget/v/MonoGame.Aseprite?color=blue&style=flat-square)](https://www.nuget.org/packages/MonoGame.Aseprite/5.1.1) +[![Nuget 5.1.2](https://img.shields.io/nuget/v/MonoGame.Aseprite?color=blue&style=flat-square)](https://www.nuget.org/packages/MonoGame.Aseprite/5.1.2) [![License: MIT](https://img.shields.io/badge/📃%20license-MIT-blue?style=flat)](LICENSE) [![Twitter](https://img.shields.io/badge/%20-Share%20On%20Twitter-555?style=flat&logo=twitter)](https://twitter.com/intent/tweet?text=MonoGame.Aseprite%20by%20%40aristurtledev%0A%0AA%20cross-platform%20C%23%20library%20that%20adds%20support%20for%20Aseprite%20files%20in%20MonoGame%20projects.%20https%3A%2F%2Fgithub.com%2FAristurtleDev%2Fmonogame-aseprite%0A%0A%23monogame%20%23aseprite%20%23dotnet%20%23csharp%20%23oss%0A) diff --git a/.tools/.config/dotnet-tools.json b/.tools/.config/dotnet-tools.json deleted file mode 100644 index 4d2d6477..00000000 --- a/.tools/.config/dotnet-tools.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "cake.tool": { - "version": "3.0.0", - "commands": [ - "dotnet-cake" - ] - }, - "grynwald.mddocs": { - "version": "0.5.180", - "commands": [ - "mddocs" - ] - } - } -} \ No newline at end of file diff --git a/.tools/build.cake b/.tools/build.cake deleted file mode 100644 index e724202a..00000000 --- a/.tools/build.cake +++ /dev/null @@ -1,408 +0,0 @@ -#nullable enable -/////////////////////////////////////////////////////////////////////////////// -/// Arguments -/////////////////////////////////////////////////////////////////////////////// -string target = Argument(nameof(target), "Default"); -string configuration = Argument(nameof(configuration), "Release"); -bool restore = Argument(nameof(restore), true); -bool clean = Argument(nameof(clean), true); -bool test = Argument(nameof(test), true); -bool generateDocs = Argument(nameof(generateDocs), false); - -/////////////////////////////////////////////////////////////////////////////// -/// Variables -/////////////////////////////////////////////////////////////////////////////// -string version = string.Empty; - -/////////////////////////////////////////////////////////////////////////////// -/// Setup -/////////////////////////////////////////////////////////////////////////////// - -Setup((context) => -{ - version = XmlPeek("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", "//Version"); - Information($"Version: {version}"); - - if(target is "Docs" || generateDocs) - { - XmlPoke("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", "//GenerateDocumentationFile", "True"); - } -}); - -/////////////////////////////////////////////////////////////////////////////// -/// Teardown -/////////////////////////////////////////////////////////////////////////////// - -Teardown((context) => -{ - // Turn off xml document generation for docs task - if(target is "Docs" || generateDocs) - { - XmlPoke("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", "//GenerateDocumentationFile", "False"); - } -}); - -/////////////////////////////////////////////////////////////////////////////// -/// Tasks -/////////////////////////////////////////////////////////////////////////////// -Task("Version") -.Description("Displays the parsed version number used for builds and publish") -.Does(() => Information($"Version: {version}")); - -Task("Clean") -.WithCriteria(clean) -.Does(() => -{ - DotNetClean("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj"); - DotNetClean("../source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj"); - DotNetClean("../tests/MonoGame.Aseprite.Tests/MonoGame.Aseprite.Tests.csproj"); - CleanDirectory("../.artifacts"); -}); - -Task("Restore") -.IsDependentOn("Clean") -.WithCriteria(restore) -.Does(() => -{ - DotNetRestore("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj"); - DotNetRestore("../source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj"); - DotNetRestore("../tests/MonoGame.Aseprite.Tests/MonoGame.Aseprite.Tests.csproj"); -}); - -Task("Build") -.Does(() => -{ - DotNetMSBuildSettings msBuildSettings = new(); - msBuildSettings.WithProperty("Version", version); - - DotNetBuildSettings buildSettings = new(); - buildSettings.Configuration = configuration; - buildSettings.MSBuildSettings = msBuildSettings; - - DotNetBuild("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", buildSettings); - DotNetBuild("../source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj", buildSettings); - DotNetBuild("../tests/MonoGame.Aseprite.Tests/MonoGame.Aseprite.Tests.csproj", buildSettings); -}); - -Task("Test") -.IsDependentOn("Build") -.WithCriteria(test) -.Does(() => -{ - DotNetTestSettings testSettings = new(); - testSettings.Configuration = configuration; - testSettings.NoBuild = true; - - DotNetTest("../tests/MonoGame.Aseprite.Tests/MonoGame.Aseprite.Tests.csproj", testSettings); -}); - -Task("Pack") -.IsDependentOn("Test") -.Does(() => -{ - DotNetMSBuildSettings msBuildSettings = new(); - msBuildSettings.WithProperty("PackageVersion", version) - .WithProperty("Version", version); - - DotNetPackSettings packSettings = new(); - packSettings.Configuration = configuration; - packSettings.OutputDirectory = "../.artifacts"; - packSettings.NoBuild = true; - packSettings.NoRestore = true; - packSettings.MSBuildSettings = msBuildSettings; - - DotNetPack("../source/MonoGame.Aseprite/MonoGame.Aseprite.csproj", packSettings); -}); - -Task("PublishNuGet") -.IsDependentOn("Pack") -.Does(context => -{ - if(BuildSystem.GitHubActions.IsRunningOnGitHubActions) - { - FilePath nupkgPath = $"../.artifacts/MonoGame.Aseprite.{version}.nupkg"; - - Information("Publishing {0} to NuGet...", nupkgPath.GetFilename().FullPath); - - DotNetNuGetPushSettings pushSettings = new(); - pushSettings.ApiKey = context.EnvironmentVariable("NUGET_API_KEY"); - pushSettings.Source = "https://api.nuget.org/v3/index.json"; - - DotNetNuGetPush(nupkgPath, pushSettings); - - } -}); - -Task("PublishGitHub") -.IsDependentOn("Pack") -.Does(context => -{ - if(BuildSystem.GitHubActions.IsRunningOnGitHubActions) - { - FilePath nupkgPath = $"../.artifacts/MonoGame.Aseprite.{version}.nupkg"; - - Information("Publishing {0} to GitHub...", nupkgPath.GetFilename().FullPath); - - DotNetNuGetPushSettings pushSettings = new(); - pushSettings.ApiKey = context.EnvironmentVariable("GITHUB_TOKEN"); - pushSettings.Source = "https://nuget.pkg.github.com/AristurtleDev/index.json"; - - DotNetNuGetPush(nupkgPath, pushSettings); - - } -}); - -Task("Docs") -.IsDependentOn("Default") -.Does(() => -{ - // --------------------------------------------------- - // Use mddcos dotnet tool to create the initial - // documentation files in the .artifacts directory - // --------------------------------------------------- - DotNetToolSettings toolSettings = new(); - toolSettings.ArgumentCustomization = builder => - { - builder.Append("apireference"); - builder.AppendSwitch("--configurationFilePath", "./mddocs.config.json"); - builder.AppendSwitch("--assemblies", $"../source/MonoGame.Aseprite/bin/{configuration}/net6.0/MonoGame.Aseprite.dll"); - builder.AppendSwitchQuoted("--outdir", "../.artifacts/documentation"); - return builder; - }; - - DotNetTool("mddocs", toolSettings); - - // --------------------------------------------------- - // Go through all documentation directories and change - // the lowercase directory names title case - // --------------------------------------------------- - Dictionary renamedDirMap = new(); - foreach(string dir in (string[])System.IO.Directory.GetDirectories("../.artifacts/documentation", "*", SearchOption.AllDirectories)) - { - System.IO.DirectoryInfo dirInfo = new(dir); - - if(char.IsLower(dirInfo.Name[0])) - { - string? containingDirectoryPath = System.IO.Path.GetDirectoryName(dir); - if(containingDirectoryPath is null) - { - throw new Exception($"System.IO.Path.GetDirectoryname for directory '{dir}' returned null!"); - } - string newDirName = $"{char.ToUpper(dirInfo.Name[0])}{dirInfo.Name[1..]}"; - string newPath = System.IO.Path.Combine(containingDirectoryPath, newDirName); - renamedDirMap.TryAdd(dirInfo.Name, newDirName); - dirInfo.MoveTo(newPath); - } - } - - - // --------------------------------------------------- - // Go through all documentation files and perform the following - // - Rename all "index.md" files to "[directoryName].md" - // - Read each file line-by-line and - // - Replace the first line with generated yaml frontmatter - // - Fix links to index.md from the previous name change - // - Fix links to directories that names changed from the - // lowercase to uppercase change prior - // --------------------------------------------------- - // Rename index.md files to [directoryName].md - foreach(string file in (string[])System.IO.Directory.GetFiles("../.artifacts/documentation", "*.md", SearchOption.AllDirectories)) - { - string? newName = default; - - FileInfo fileInfo = new(file); - if(fileInfo.Name == "index.md") - { - if(fileInfo.Directory is null) - { - throw new System.Exception($"Unable to get directory name for '{fileInfo.Name}'"); - } - - newName = fileInfo.Directory.Name + ".md"; - string newPath = System.IO.Path.Combine(fileInfo.Directory.FullName , newName); - fileInfo.MoveTo(newPath); - - // Don't forget to update the fileInfo reference after moving to new path - fileInfo = new(newPath); - - } - - StringBuilder sb = new(); - - using(System.IO.FileStream fileStream = new(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - using(System.IO.StreamReader streamReader = new(fileStream)) - { - bool isFirstLine = true; - string? line = default; - bool previousLineStartsCodeBlock = false; - bool inCommentChain = false; - while((line = streamReader.ReadLine()) is not null) - { - if(isFirstLine && line.StartsWith("#")) - { - string title = line.Replace("#", string.Empty).Trim(); - string id = title.ToLower().Replace('.', '-').Replace(' ', '-'); - string? label = default; - - if(line.Contains("Namespace")) - { - label = fileInfo.Directory?.Name; - } - - if(label is null) - { - label = title.Replace("Namespace", string.Empty) - .Replace("Class", string.Empty) - .Replace("Method", string.Empty) - .Replace("Property", string.Empty) - .Replace("Enum", string.Empty) - .Replace("Field", string.Empty) - .Replace("Event", string.Empty) - .Trim(); - } - - - bool isMainNamespace = false; - if(label is "Aseprite") - { - isMainNamespace = true; - // This should only occur for the MonoGame.Aseprite namespace document - // but we want the label for that to be "MonoGame.Aseprite" and not "Aseprite" - label = "MonoGame.Aseprite Namespace"; - } - else - { - // Otherwise, we want to remove the first part of the label up to the '.' character - // if the label has a '.' character. - // This effectibly changes the Property/Field/Method/Indexor from being "Type.Property" - // to just "Property". - // This is to remove clutter in the sidbar labeling so instead of this - // - // MonoGame.Aseprite - // ↳ AsepriteFile - // ↳ Methods - // ↳ AsepriteFile.GetFrame - // - // We get this - // - // Monogame.Aseprite - // ↳ AsepriteFile - // ↳ Methods - // ↳ GetFrame - - int dotIndex = label.IndexOf('.'); - if(dotIndex >= 0) label = label[(dotIndex + 1)..]; - } - - - - string yaml = - $""" - --- - title: {title} - sidebar_label: {label} - {(isMainNamespace ? "sidebar_position: 0" : string.Empty)} - --- - """; - sb.AppendLine(yaml); - } - else - { - // Replace all calls to an index.md with an empty string - string sanatized = line.Replace("index.md", string.Empty); - - // Replace all calls to the lowercase folder names to uppercase since we changed them - // in the previous loop - foreach(KeyValuePair entry in renamedDirMap) - { - sanatized = sanatized.Replace($"({entry.Key}/", $"({entry.Value}/") - .Replace($"../{entry.Key}/", $"../{entry.Value}/"); - } - - - // Fix issue where mddocs removes intentional new lines in blocks by appending - // a new line anytime comment lines are discovered - if(line.StartsWith("//") && !inCommentChain && !previousLineStartsCodeBlock) - { - inCommentChain = true; - sb.AppendLine(); - } - else - { - inCommentChain = false; - } - - // Fix issue where sometimes the space between words and links are removed because of a - // newline in the XML comment, resulting in something like this - // - // word[Link](link) - // - // The regex will match any word character that is directly connected to a '[', for instance - // the 'd[' in the above example. - // If a match is found, it then replaces it with a space between it like 'd [' - string pattern = @"\w\["; - System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(sanatized, pattern); - - if(match.Success) - { - sanatized = System.Text.RegularExpressions.Regex.Replace(sanatized, pattern, match.Value.Insert(1, " ")); - } - - // In one document so far, I'm using '### Header' in the section. mddocs is escaping - // the "###" as "\#\#\#". Find this and fix it - if(sanatized.Contains(@"\#\#\#")) - { - sanatized = sanatized.Replace(@"\#\#\#", "\n\n###"); - } - - // Fix external links in the see also secitons - if(sanatized.StartsWith(@"- [https:\/\/docs.monogame.net\/api\/")) - { - sanatized = sanatized.Replace(@"https:\/\/docs.monogame.net\/api\/", string.Empty) - .Replace(".html]", "]"); - } - - sb.AppendLine(sanatized); - } - isFirstLine = false; - previousLineStartsCodeBlock = line.StartsWith("```cs"); - } - } - } - - System.IO.File.WriteAllText(fileInfo.FullName, sb.ToString()); - } - - - // --------------------------------------------------- - // Move the "Aseprite" directory out of the MonoGame" - // directory and rename it to "MonoGame.Aseprite" - // then delete the "MonoGame" directory - // --------------------------------------------------- - new System.IO.DirectoryInfo("../.artifacts/documentation/MonoGame/Aseprite").MoveTo("../.artifacts/documentation/MonoGame.Aseprite"); - System.IO.Directory.Delete("../.artifacts/documentation/MonoGame", true); - - // --------------------------------------------------- - // Rename the "Aseprite.md" file to "MonoGame.Aseprite.md" - // --------------------------------------------------- - new System.IO.FileInfo("../.artifacts/documentation/MonoGame.Aseprite/Aseprite.md").MoveTo("../.artifacts/documentation/MonoGame.Aseprite/MonoGame.Aseprite.md"); - -}); - - -Task("Default") -.IsDependentOn("Clean") -.IsDependentOn("Restore") -.IsDependentOn("Build") -.IsDependentOn("Test"); - -Task("Publish") -.IsDependentOn("Default") -.IsDependentOn("PublishNuGet") -.IsDependentOn("PublishGitHub"); - -/////////////////////////////////////////////////////////////////////////////// -/// Execution -/////////////////////////////////////////////////////////////////////////////// -RunTarget(target); \ No newline at end of file diff --git a/.tools/mddocs.config.json b/.tools/mddocs.config.json deleted file mode 100644 index 63b0d26a..00000000 --- a/.tools/mddocs.config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mddocs": { - "apireference": { - "template": { - "default": { - "includeAutoGeneratedNotice": false, - "includeVersion": false - } - } - } - } -} \ No newline at end of file diff --git a/README.md b/README.md index e4f50a69..554ab21f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A Cross Platform C# Library That Adds Support For Aseprite Files in MonoGame Projects. [![build-and-test](https://github.com/AristurtleDev/monogame-aseprite/actions/workflows/buildandtest.yml/badge.svg)](https://github.com/AristurtleDev/monogame-aseprite/actions/workflows/buildandtest.yml) -[![Nuget 5.1.1](https://img.shields.io/nuget/v/MonoGame.Aseprite?color=blue&style=flat-square)](https://www.nuget.org/packages/MonoGame.Aseprite/5.1.1) +[![Nuget 5.1.2](https://img.shields.io/nuget/v/MonoGame.Aseprite?color=blue&style=flat-square)](https://www.nuget.org/packages/MonoGame.Aseprite/5.1.2) [![License: MIT](https://img.shields.io/badge/📃%20license-MIT-blue?style=flat)](LICENSE) [![Twitter](https://img.shields.io/badge/%20-Share%20On%20Twitter-555?style=flat&logo=twitter)](https://twitter.com/intent/tweet?text=MonoGame.Aseprite%20by%20%40aristurtledev%0A%0AA%20cross-platform%20C%23%20library%20that%20adds%20support%20for%20Aseprite%20files%20in%20MonoGame%20projects.%20https%3A%2F%2Fgithub.com%2FAristurtleDev%2Fmonogame-aseprite%0A%0A%23monogame%20%23aseprite%20%23dotnet%20%23csharp%20%23oss%0A) diff --git a/source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj b/source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj index edaa4043..7dfdb912 100644 --- a/source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj +++ b/source/MonoGame.Aseprite.Content.Pipeline/MonoGame.Aseprite.Content.Pipeline.csproj @@ -3,8 +3,8 @@ net6.0 enable enable - False - 5.1.1 + True + 5.1.2 @@ -21,9 +21,9 @@ MonoGame.Aseprite.Content.Pipeline - 5.1.1 - 5.1.1 - 5.1.1 + 5.1.2 + 5.1.2 + 5.1.2 Christopher Whitley Aristurtle MIT @@ -38,9 +38,9 @@ MonoGame;Aseprite;import;processes;read;write;sprite;animation;tileset;tilemap;spritesheet;pipeline;mgcb - Version 5.1.1 + Version 5.1.2 The following changes were implemented: - - Resolved issue where using Linked Cels can cause an out of bounds exception. + - Resolves issue where AsepriteFile.TryGetSlice always returned false even when slice exists MonoGame.Aseprite.Content.Pipeline is a cross-platform C# library that adds an extension to the MonoGame diff --git a/source/MonoGame.Aseprite.Shared/AsepriteFile.cs b/source/MonoGame.Aseprite.Shared/AsepriteFile.cs index 7eb9dd35..0d5a19c8 100644 --- a/source/MonoGame.Aseprite.Shared/AsepriteFile.cs +++ b/source/MonoGame.Aseprite.Shared/AsepriteFile.cs @@ -532,7 +532,7 @@ public bool TryGetSlice(string sliceName, [NotNullWhen(true)] out AsepriteSlice? for (int i = 0; i < _slices.Length; i++) { - if (_tags[i].Name == sliceName) + if (_slices[i].Name == sliceName) { located = _slices[i]; break; diff --git a/source/MonoGame.Aseprite/MonoGame.Aseprite.csproj b/source/MonoGame.Aseprite/MonoGame.Aseprite.csproj index 05b41774..02d5a8ef 100644 --- a/source/MonoGame.Aseprite/MonoGame.Aseprite.csproj +++ b/source/MonoGame.Aseprite/MonoGame.Aseprite.csproj @@ -3,8 +3,8 @@ net6.0 enable enable - False - 5.1.1 + True + 5.1.2 @@ -29,9 +29,9 @@ README.md - Version 5.1.1 + Version 5.1.2 The following changes were implemented: - - Resolved issue where using Linked Cels can cause an out of bounds exception. + - Resolves issue where AsepriteFile.TryGetSlice always returned false even when slice exists MonoGame.Aseprite is a cross-platofrm C# library that adds support to MonoGame projects for diff --git a/tests/MonoGame.Aseprite.Tests.sln b/tests/MonoGame.Aseprite.Tests.sln index 41cfed32..ebd3630a 100644 --- a/tests/MonoGame.Aseprite.Tests.sln +++ b/tests/MonoGame.Aseprite.Tests.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Aseprite.Tests", "MonoGame.Aseprite.Tests\MonoGame.Aseprite.Tests.csproj", "{CA70FF5A-3331-4C7D-90C5-491D35F33825}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Aseprite", "..\source\MonoGame.Aseprite\MonoGame.Aseprite.csproj", "{943BBD8C-B128-4C0C-B028-177805E4C277}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -18,5 +20,9 @@ Global {CA70FF5A-3331-4C7D-90C5-491D35F33825}.Debug|Any CPU.Build.0 = Debug|Any CPU {CA70FF5A-3331-4C7D-90C5-491D35F33825}.Release|Any CPU.ActiveCfg = Release|Any CPU {CA70FF5A-3331-4C7D-90C5-491D35F33825}.Release|Any CPU.Build.0 = Release|Any CPU + {943BBD8C-B128-4C0C-B028-177805E4C277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {943BBD8C-B128-4C0C-B028-177805E4C277}.Debug|Any CPU.Build.0 = Debug|Any CPU + {943BBD8C-B128-4C0C-B028-177805E4C277}.Release|Any CPU.ActiveCfg = Release|Any CPU + {943BBD8C-B128-4C0C-B028-177805E4C277}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/tests/MonoGame.Aseprite.Tests/AsepriteTypeTests/AsepriteFileTests.cs b/tests/MonoGame.Aseprite.Tests/AsepriteTypeTests/AsepriteFileTests.cs new file mode 100644 index 00000000..78e54ddf --- /dev/null +++ b/tests/MonoGame.Aseprite.Tests/AsepriteTypeTests/AsepriteFileTests.cs @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- +MIT License + +Copyright (c) 2018-2023 Christopher Whitley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +---------------------------------------------------------------------------- */ + +using Microsoft.Xna.Framework; +using MonoGame.Aseprite.AsepriteTypes; + +namespace MonoGame.Aseprite.Tests; + +public sealed class AsepriteFileTests +{ + // https://github.com/AristurtleDev/monogame-aseprite/issues/93 + [Fact] + public void TryGetSlice_True_When_Slice_Exists() + { + Color[] palette = Array.Empty(); + AsepriteFrame[] frames = Array.Empty(); + AsepriteLayer[] layers = Array.Empty(); + AsepriteTag[] tags = Array.Empty(); + AsepriteTileset[] tilesets = Array.Empty(); + AsepriteUserData userData = new AsepriteUserData(); + + string expectedSliceName = "TestSlice"; + + AsepriteSlice[] slices = new AsepriteSlice[] + { + new AsepriteSlice(expectedSliceName, false, false, Array.Empty()) + }; + + AsepriteFile aseFile = new AsepriteFile("Test", 1, 1, palette, frames, layers, tags, slices, tilesets, userData); + + Assert.True(aseFile.TryGetSlice(expectedSliceName, out AsepriteSlice? slice)); + } +}