Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 1 addition & 35 deletions src/NuGetForUnity.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using NugetForUnity;
using NugetForUnity.Configuration;
using NugetForUnity.Helper;
Expand Down Expand Up @@ -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");
Expand All @@ -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);
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions src/NuGetForUnity.Tests/Assets/Tests/Editor/NuGetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 60 additions & 0 deletions src/NuGetForUnity/Editor/Helper/AnalyzerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using NugetForUnity.Models;

Expand All @@ -16,6 +17,11 @@ internal static class AnalyzerHelper
/// </summary>
private const string AnalyzersFolderName = "analyzers";

/// <summary>
/// Used to let unity know an asset is a Roslyn-Analyzer.
/// </summary>
private const string RoslynAnalyzerLabel = "RoslynAnalyzer";

/// <summary>
/// Name of the root folder containing dotnet analyzers.
/// </summary>
Expand Down Expand Up @@ -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)
Expand All @@ -64,6 +75,55 @@ public static bool ShouldEnableRoslynAnalyzer(string path)
return true;
}

/// <summary>
/// Writes initial Unity import settings for a Roslyn analyzer DLL before Unity imports it for the first time.
/// </summary>
/// <param name="analyzerDllPath">The path to the analyzer DLL.</param>
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)
{
Expand Down
14 changes: 14 additions & 0 deletions src/NuGetForUnity/Editor/NugetPackageInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using JetBrains.Annotations;
using NugetForUnity.Configuration;
using NugetForUnity.Helper;
using NugetForUnity.Models;
using NugetForUnity.PluginSupport;
using UnityEditor;
Expand Down Expand Up @@ -219,6 +220,7 @@ private static PackageInstallOperationResult Install(
var libs = new Dictionary<string, List<ZipArchiveEntry>>();
var csFiles = new Dictionary<string, List<ZipArchiveEntry>>();
var anyFiles = new Dictionary<string, List<ZipArchiveEntry>>();
var extractedAnalyzerDllPaths = new List<string>();

foreach (var entry in zip.Entries)
{
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -336,6 +345,11 @@ private static PackageInstallOperationResult Install(
{
TryExtractBestFrameworkSources(anyFiles, baseDirectory, package, packageConfig);
}

foreach (var analyzerDllPath in extractedAnalyzerDllPaths)
{
AnalyzerHelper.WriteInitialRoslynAnalyzerImportSettings(analyzerDllPath);
}
}
}
else
Expand Down
Loading