diff --git a/src/NuGetForUnity.Cli/Program.cs b/src/NuGetForUnity.Cli/Program.cs index b77c355f..e30add4b 100644 --- a/src/NuGetForUnity.Cli/Program.cs +++ b/src/NuGetForUnity.Cli/Program.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Text; using NugetForUnity; using NugetForUnity.Configuration; using NugetForUnity.Helper; @@ -81,7 +80,6 @@ private static void FixRoslynAnalyzerImportSettings() return; } - UTF8Encoding? utf8NoBom = null; foreach (var packageDirectoryPath in Directory.EnumerateDirectories(ConfigurationManager.NugetConfigFile.RepositoryPath)) { var analyzersDirectoryPath = Path.Combine(packageDirectoryPath, "analyzers"); @@ -92,39 +90,7 @@ private static void FixRoslynAnalyzerImportSettings() foreach (var analyzerDllPath in Directory.EnumerateFiles(analyzersDirectoryPath, "*.dll", SearchOption.AllDirectories)) { - var analyzerDllMetaPath = $"{analyzerDllPath}.meta"; - if (File.Exists(analyzerDllMetaPath)) - { - continue; - } - - var isSupportedRoslynAnalyzer = AnalyzerHelper.ShouldEnableRoslynAnalyzer(analyzerDllPath); - var labelsForAsset = isSupportedRoslynAnalyzer ? - """ - labels: - - RoslynAnalyzer - """ : - "labels: []"; - utf8NoBom ??= new UTF8Encoding(false); - File.WriteAllText( - analyzerDllMetaPath, - $""" - fileFormatVersion: 2 - guid: {Guid.NewGuid():N} - {labelsForAsset} - PluginImporter: - serializedVersion: 2 - platformData: - - first: - : Any - second: - enabled: 0 - - first: - Any: - second: - enabled: 0 - """, - utf8NoBom); + AnalyzerHelper.WriteInitialRoslynAnalyzerImportSettings(analyzerDllPath); } } } diff --git a/src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs b/src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs index 33680a7e..e928e45a 100644 --- a/src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs +++ b/src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs @@ -111,11 +111,22 @@ public void InstallRoslynAnalyzerTest([Values] InstallMode installMode) var analyzer = new NugetPackageIdentifier("ErrorProne.NET.CoreAnalyzers", "0.1.2") { IsManuallyInstalled = true }; // install the package - NugetPackageInstaller.InstallIdentifier(analyzer); + NugetPackageInstaller.InstallIdentifier(analyzer, false); try { - AssetDatabase.Refresh(); var path = $"Assets/Packages/{analyzer.Id}.{analyzer.Version}/analyzers/dotnet/cs/ErrorProne.NET.Core.dll"; + var analyzerDllPath = Path.Combine( + ConfigurationManager.NugetConfigFile.RepositoryPath, + $"{analyzer.Id}.{analyzer.Version}", + "analyzers", + "dotnet", + "cs", + "ErrorProne.NET.Core.dll"); + var analyzerMetaPath = $"{analyzerDllPath}.meta"; + Assert.That(analyzerMetaPath, Does.Exist.IgnoreDirectories, "Expected analyzer import settings before AssetDatabase.Refresh"); + Assert.That(File.ReadAllText(analyzerMetaPath), Does.Contain("- RoslynAnalyzer")); + + AssetDatabase.Refresh(); var meta = (PluginImporter)AssetImporter.GetAtPath(path); #if UNITY_2022_3_OR_NEWER diff --git a/src/NuGetForUnity/Editor/Helper/AnalyzerHelper.cs b/src/NuGetForUnity/Editor/Helper/AnalyzerHelper.cs index ac4a143d..e00f88e3 100644 --- a/src/NuGetForUnity/Editor/Helper/AnalyzerHelper.cs +++ b/src/NuGetForUnity/Editor/Helper/AnalyzerHelper.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Text; using JetBrains.Annotations; using NugetForUnity.Models; @@ -16,6 +17,11 @@ internal static class AnalyzerHelper /// private const string AnalyzersFolderName = "analyzers"; + /// + /// Used to let unity know an asset is a Roslyn-Analyzer. + /// + private const string RoslynAnalyzerLabel = "RoslynAnalyzer"; + /// /// Name of the root folder containing dotnet analyzers. /// @@ -53,6 +59,11 @@ public static bool ShouldEnableRoslynAnalyzer(string path) .Where(version => version != null && version.CompareTo(maxSupportedRoslynVersion) <= 0) .ToArray(); + if (allEnabledRoslynVersions.Length == 0) + { + return false; + } + // If most recent valid analyzers exist elsewhere, don't add label `RoslynAnalyzer` var maxMatchingVersion = allEnabledRoslynVersions.Max(); if (!allEnabledRoslynVersions.Contains(assetRoslynVersion) || assetRoslynVersion < maxMatchingVersion) @@ -64,6 +75,55 @@ public static bool ShouldEnableRoslynAnalyzer(string path) return true; } + /// + /// Writes initial Unity import settings for a Roslyn analyzer DLL before Unity imports it for the first time. + /// + /// The path to the analyzer DLL. + public static void WriteInitialRoslynAnalyzerImportSettings([NotNull] string analyzerDllPath) + { + var analyzerDllMetaPath = $"{analyzerDllPath}.meta"; + if (File.Exists(analyzerDllMetaPath)) + { + return; + } + + var labelsForAsset = ShouldEnableRoslynAnalyzer(analyzerDllPath) ? + $"labels:{Environment.NewLine}- {RoslynAnalyzerLabel}{Environment.NewLine}" : + $"labels: []{Environment.NewLine}"; + + File.WriteAllText( + analyzerDllMetaPath, + "fileFormatVersion: 2" + Environment.NewLine + + $"guid: {Guid.NewGuid():N}" + Environment.NewLine + + labelsForAsset + + "PluginImporter:" + Environment.NewLine + + " externalObjects: {}" + Environment.NewLine + + " serializedVersion: 2" + Environment.NewLine + + " iconMap: {}" + Environment.NewLine + + " executionOrder: {}" + Environment.NewLine + + " defineConstraints: []" + Environment.NewLine + + " isPreloaded: 0" + Environment.NewLine + + " isOverridable: 0" + Environment.NewLine + + " isExplicitlyReferenced: 0" + Environment.NewLine + + " validateReferences: 1" + Environment.NewLine + + " platformData:" + Environment.NewLine + + " - first:" + Environment.NewLine + + " Any: " + Environment.NewLine + + " second:" + Environment.NewLine + + " enabled: 0" + Environment.NewLine + + " settings: {}" + Environment.NewLine + + " - first:" + Environment.NewLine + + " Editor: Editor" + Environment.NewLine + + " second:" + Environment.NewLine + + " enabled: 0" + Environment.NewLine + + " settings:" + Environment.NewLine + + " DefaultValueInitialized: true" + Environment.NewLine + + " userData: " + Environment.NewLine + + " assetBundleName: " + Environment.NewLine + + " assetBundleVariant: " + Environment.NewLine, + new UTF8Encoding(false)); + } + [CanBeNull] private static NugetPackageVersion GetRoslynVersionNumberFromAnalyzerPath(string analyzerAssetPath) { diff --git a/src/NuGetForUnity/Editor/NugetPackageInstaller.cs b/src/NuGetForUnity/Editor/NugetPackageInstaller.cs index 88267384..684400df 100644 --- a/src/NuGetForUnity/Editor/NugetPackageInstaller.cs +++ b/src/NuGetForUnity/Editor/NugetPackageInstaller.cs @@ -5,6 +5,7 @@ using System.Linq; using JetBrains.Annotations; using NugetForUnity.Configuration; +using NugetForUnity.Helper; using NugetForUnity.Models; using NugetForUnity.PluginSupport; using UnityEditor; @@ -219,6 +220,7 @@ private static PackageInstallOperationResult Install( var libs = new Dictionary>(); var csFiles = new Dictionary>(); var anyFiles = new Dictionary>(); + var extractedAnalyzerDllPaths = new List(); foreach (var entry in zip.Entries) { @@ -292,6 +294,13 @@ private static PackageInstallOperationResult Install( var extractedFilePath = PackageContentManager.ExtractPackageEntry(entry, baseDirectory); + if (extractedFilePath != null && + entryFullName.StartsWith("analyzers/", StringComparison.Ordinal) && + entryFullName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + { + extractedAnalyzerDllPaths.Add(extractedFilePath); + } + if (extractedFilePath != null && (entryFullName.StartsWith("runtimes/", StringComparison.Ordinal) || entryFullName.Contains("/runtimes/")) && RuntimePluginFileExtentions.Any(extension => entryFullName.EndsWith(extension, StringComparison.OrdinalIgnoreCase))) @@ -336,6 +345,11 @@ private static PackageInstallOperationResult Install( { TryExtractBestFrameworkSources(anyFiles, baseDirectory, package, packageConfig); } + + foreach (var analyzerDllPath in extractedAnalyzerDllPaths) + { + AnalyzerHelper.WriteInitialRoslynAnalyzerImportSettings(analyzerDllPath); + } } } else