diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index a3624f0..b4eb72b 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -84,7 +84,8 @@ "PublishPackageToGithub", "PublishPackageToNuGet", "Restore", - "Test" + "Test", + "Validate" ] } }, @@ -105,7 +106,8 @@ "PublishPackageToGithub", "PublishPackageToNuGet", "Restore", - "Test" + "Test", + "Validate" ] } }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c9f34..49a4d81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Parse model position - Parse model name +- Better validation for Unity meta files in build pipeline ## [2.1.2] - 2023-01-03 diff --git a/build/Build.cs b/build/Build.cs index 5d738f5..871c70d 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -52,43 +52,38 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - protected override void OnBuildInitialized() - { - if (GitRepository.CurrentCommitHasVersionTag()) - { - // Validate latest version in changelog file matches the version tag in git - Assert.True(ChangelogTasksExtensions.TryGetLatestVersionInChangelog(RootDirectory / "CHANGELOG.md", out SemanticVersion version, out string rawVersionValue) && version == GitRepository.GetLatestVersionTag(), - $"Latest version '{rawVersionValue}' in the changelog file does not match the version tag '{GitRepository.GetLatestVersionTag()}'!"); - - // Verify version in Unity package file matches the version tag in git - dynamic packageFile = JsonConvert.DeserializeObject(File.ReadAllText(Solution.VoxReader.Directory / "package.json")); - SemanticVersion versionInPackageFile = SemanticVersion.Parse(packageFile.version.ToString()); - - SemanticVersion versionTag = GitRepository.GetLatestVersionTag(); - - Assert.True(versionInPackageFile == versionTag, $"The version '{versionInPackageFile}' in the Unity package file does not match the latest version tag '{versionTag}'!"); - } - - // Verify that all *.cs files have a Unity meta file (if the meta file is missing the file will be ignored when imported into Unity) - // TODO: check meta file for all files and directories - // TODO: check if meta file count is equal to source file count - var voxReaderSourceFiles = Solution.VoxReader.Directory.GlobFiles("**/*.cs") - .Where(f => !f.ToString().Contains(Solution.VoxReader.Directory / "obj")) - .Where(f => !f.ToString().Contains(Solution.VoxReader.Directory / "bin")) - .OrderBy(f => f.ToString()) - .ToHashSet(); - var voxReaderSourceMetaFiles = Solution.VoxReader.Directory.GlobFiles("**/*.cs.meta") - .Where(f => !f.ToString().Contains(Solution.VoxReader.Directory / "obj")) - .Where(f => !f.ToString().Contains(Solution.VoxReader.Directory / "bin")) - .OrderBy(f => f.ToString()).ToHashSet(); - - foreach (AbsolutePath sourceFile in voxReaderSourceFiles) + Target Validate => _ => _ + .Executes(() => { - Assert.True(voxReaderSourceMetaFiles.Contains((AbsolutePath)(sourceFile + ".meta")), $"'{sourceFile}' is missing a Unity .meta file!"); - } - } + bool changelogHasValidVersion = ChangelogTasksExtensions.TryGetLatestVersionInChangelog(RootDirectory / "CHANGELOG.md", out SemanticVersion latestChangelogVersion, out string latestRawChangelogVersionValue); + + SemanticVersion versionInUnityPackageFile = Helper.GetVersionFromUnityPackageFile(Solution.VoxReader.Directory / "package.json"); + + if (GitRepository.CurrentCommitHasVersionTag()) + { + SemanticVersion versionTag = GitRepository.GetLatestVersionTag(); + + Assert.True(changelogHasValidVersion, $"Could not parse '{latestRawChangelogVersionValue}' as the latest version from the changelog file!"); + + Assert.True(latestChangelogVersion == versionInUnityPackageFile, + $"The latest version '{latestChangelogVersion}' in the changelog file does not match the version '{versionInUnityPackageFile}' in the Unity package file!"); + + Assert.True(latestChangelogVersion == versionTag, + $"Latest version '{latestRawChangelogVersionValue}' in the changelog file does not match the version tag '{versionTag}'!"); + + Assert.True(versionInUnityPackageFile == versionTag, + $"The version '{versionInUnityPackageFile}' in the Unity package file does not match the latest version tag '{versionTag}'!"); + } + + // Verify that all files and directories have a Unity meta file (if the meta file is missing the file will be ignored when imported into Unity) + Helper.AssertThatUnityMetaFilesExist(Solution.VoxReader.Directory, p => + p.StartsWith(Solution.VoxReader.Directory / "bin") + || p.StartsWith(Solution.VoxReader.Directory / "obj") + ); + }); Target Clean => _ => _ + .DependsOn(Validate) .Executes(() => { EnsureCleanDirectory(PublishDirectory); diff --git a/build/Helper.cs b/build/Helper.cs index ecb2bf9..ae46432 100644 --- a/build/Helper.cs +++ b/build/Helper.cs @@ -1,7 +1,11 @@ -using System.Text.RegularExpressions; +using System; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json; using NuGet.Versioning; using Nuke.Common; -using Nuke.Common.Git; +using Nuke.Common.IO; public static class Helper { @@ -22,4 +26,43 @@ public static bool IsValidVersionTag(string version, out SemanticVersion semanti return true; } + + /// + /// Checks recursively if all files and folders have a Unity meta file. + /// + /// The directory to check. + /// All paths to check are passed to this function. Return TRUE to exclude the current path. + public static void AssertThatUnityMetaFilesExist(AbsolutePath directory, Func excludePredicate = null) + { + var directories = directory.GlobDirectories("**").Where(d => d != directory); + + foreach (AbsolutePath d in directories) + { + if (excludePredicate != null && excludePredicate(d)) + continue; + + Assert.True((d.Parent / (d.Name + ".meta")).FileExists(), $"The directory '{d}' does not have a Unity meta file!"); + } + + var files = directory.GlobFiles("**/*").Where(f => !f.ToString().EndsWith(".meta")); + + foreach (AbsolutePath f in files) + { + if (excludePredicate != null && excludePredicate(f)) + continue; + + Assert.True((f.Parent / (f.Name + ".meta")).FileExists(), $"The file '{f}' does not have a Unity meta file!"); + } + } + + public static bool StartsWith(this AbsolutePath path, AbsolutePath other) + { + return path.ToString().StartsWith(other); + } + + public static SemanticVersion GetVersionFromUnityPackageFile(AbsolutePath file) + { + dynamic packageFile = JsonConvert.DeserializeObject(File.ReadAllText(file)); + return SemanticVersion.Parse(packageFile.version.ToString()); + } } \ No newline at end of file