From 6a887f5bf3b2e30a512337a1cf658b5760423003 Mon Sep 17 00:00:00 2001
From: JoC0de <53140583+JoC0de@users.noreply.github.com>
Date: Sun, 24 Sep 2023 21:37:29 +0200
Subject: [PATCH 1/3] only generate .sln on session start + fix nullable-adding
BOM handeling
---
.../Tests/SourceCodeFilesHandlerTest.cs | 27 +++++++++
.../Assets/Editor/MenuItemProvider.cs | 32 +++++++++--
.../Assets/Editor/ProjectFileGeneratorBase.cs | 57 +------------------
.../Assets/Editor/ProjectFileParser.cs | 54 ++++++++++++++++++
.../Assets/Editor/SourceCodeFilesHandler.cs | 47 ++++++++++++---
.../Editor/VisualStudioAssetPostprocessor.cs | 16 +++++-
6 files changed, 162 insertions(+), 71 deletions(-)
diff --git a/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs b/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
index 62e77ab..cf350e9 100644
--- a/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
+++ b/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
@@ -2,6 +2,8 @@
using System;
using System.IO;
+using System.Linq;
+using System.Text;
using NUnit.Framework;
namespace UnityVisualStudioSolutionGenerator.Tests
@@ -49,6 +51,7 @@ public class SourceCodeFilesHandlerTest
[TestCase("#nullable enable\n", "#nullable enable\n")]
[TestCase("#nullable enable\r\n", "#nullable enable\r\n")]
[TestCase("#nullable enable\n\npublic class Test\n{\n}\n", "#nullable enable\n\npublic class Test\n{\n}\n")]
+ [TestCase("public class Test\n{\n}\n", "#nullable enable\n\npublic class Test\n{\n}\n")]
public void SourceCodeFilesHandlerSimpleTest(string testSourceCode, string expectedSourceCode)
{
if (!testSourceCode.Contains('\n', StringComparison.Ordinal))
@@ -118,5 +121,29 @@ public void SourceCodeFilesHandlerMultiFileTest(string testSourceCode, string ex
File.Delete(testSourceCode2FilePath);
}
}
+
+ [Test]
+ public void TestByteOrderMaskHandling([Values] bool withBom, [Values] bool alreadyHasNullable)
+ {
+ const string testSourceCode1FilePath = "TestSourceCode.cs";
+ var utf8Encoding = new UTF8Encoding(withBom);
+ try
+ {
+ const string contentWithNullable = "#nullable enable\n\npublic class Test\n{\n}\n";
+ File.WriteAllText(testSourceCode1FilePath, alreadyHasNullable ? contentWithNullable : "public class Test\n{\n}\n", utf8Encoding);
+ SourceCodeFilesHandler.AddNullableToFile(testSourceCode1FilePath);
+ var expected = utf8Encoding.GetBytes(contentWithNullable);
+ if (withBom)
+ {
+ expected = Encoding.UTF8.GetPreamble().Concat(expected).ToArray();
+ }
+
+ Assert.That(File.ReadAllBytes(testSourceCode1FilePath), Is.EqualTo(expected));
+ }
+ finally
+ {
+ File.Delete(testSourceCode1FilePath);
+ }
+ }
}
}
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/MenuItemProvider.cs b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/MenuItemProvider.cs
index 7acd32b..b13a0c6 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/MenuItemProvider.cs
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/MenuItemProvider.cs
@@ -30,14 +30,34 @@ public static bool OpenSolutionEnabled()
return GeneratorSettings.IsVisualStudioEditorEnabled();
}
+ ///
+ /// Regenerates the Visual Studio solution file and the C# project files.
+ ///
+ [MenuItem("Visual Studio/Generate Solution", priority = 1)]
+ public static void SyncSolution()
+ {
+ VisualStudioAssetPostprocessor.MarkAsChanged();
+ CodeEditor.CurrentEditor.SyncAll();
+ }
+
+ ///
+ /// Returns whether or not the menu item should be enabled.
+ ///
+ /// True if the menu item should be enabled, False otherwise.
+ [MenuItem("Visual Studio/Generate Solution", true)]
+ public static bool SyncSolutionEnabled()
+ {
+ return GeneratorSettings.IsSolutionGeneratorEnabled();
+ }
+
///
/// Regenerates the Visual Studio solution file and the C# project files as SDK-style projects.
///
- [MenuItem("Visual Studio/Generate Solution (Sdk-Style)", priority = 1)]
+ [MenuItem("Visual Studio/Generate Solution (Sdk-Style)", priority = 2)]
public static void SyncSolutionSdkStyle()
{
GeneratorSettings.GenerateSdkStyleProjects = true;
- CodeEditor.CurrentEditor.SyncAll();
+ SyncSolution();
}
///
@@ -53,11 +73,11 @@ public static bool SyncSolutionSdkStyleEnabled()
///
/// Regenerates the Visual Studio solution file and the C# project files as Legacy-style projects.
///
- [MenuItem("Visual Studio/Generate Solution (Legacy-Style)", priority = 2)]
+ [MenuItem("Visual Studio/Generate Solution (Legacy-Style)", priority = 3)]
public static void SyncSolutionLegacyStyle()
{
GeneratorSettings.GenerateSdkStyleProjects = false;
- CodeEditor.CurrentEditor.SyncAll();
+ SyncSolution();
}
///
@@ -73,7 +93,7 @@ public static bool SyncSolutionLegacyStyleEnabled()
///
/// Checks all '.cs' files to contain '#nullable enable' at the start.
///
- [MenuItem("Visual Studio/Apply enable nullable to all files", priority = 3)]
+ [MenuItem("Visual Studio/Apply enable nullable to all files", priority = 4)]
public static void EnableNullableOnAllFiles()
{
SourceCodeFilesHandler.EnableNullableOnAllFiles(SolutionFile.CurrentProjectSolution);
@@ -92,7 +112,7 @@ public static bool EnableNullableOnAllFilesEnabled()
///
/// Opens the solution generation preferences page.
///
- [MenuItem("Visual Studio/Preferences", priority = 4)]
+ [MenuItem("Visual Studio/Preferences", priority = 5)]
public static void OpenPreferences()
{
SettingsService.OpenProjectSettings(GeneratorSettingsProvider.PreferencesPath);
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileGeneratorBase.cs b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileGeneratorBase.cs
index 569baeb..1d5e754 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileGeneratorBase.cs
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileGeneratorBase.cs
@@ -16,8 +16,6 @@ namespace UnityVisualStudioSolutionGenerator
///
public abstract class ProjectFileGeneratorBase : ProjectFileParser
{
- private string? assemblyDefinitionFilePath;
-
///
/// Initializes a new instance of the class.
///
@@ -33,45 +31,8 @@ protected ProjectFileGeneratorBase(string filePath)
///
protected string ProjectName { get; }
- ///
- /// Gets the path of the assembly definition file associated with this project. It is extracted from the project file generated by Unity.
- ///
- protected string AssemblyDefinitionFilePath
- {
- get
- {
- assemblyDefinitionFilePath ??= ExtractAssemblyDefinitionFilePath();
- return assemblyDefinitionFilePath;
- }
- }
-
private string ProjectOutputFilePath => Path.ChangeExtension(AssemblyDefinitionFilePath, ".csproj");
- ///
- /// Determines whether the project is from the package cache.
- ///
- /// True if the project file is from a package, False otherwise.
- public bool IsProjectFromPackageCache()
- {
- if (assemblyDefinitionFilePath is not null)
- {
- return IsProjectFileFromPackageCache(assemblyDefinitionFilePath);
- }
-
- var anyProjectFilePath = ProjectElement.Descendants(XmlNamespace + "None")
- .Concat(ProjectElement.Descendants(XmlNamespace + "Compile"))
- .Select(element => element.Attribute("Include")?.Value)
- .FirstOrDefault(itemPath => itemPath is not null);
-
- if (anyProjectFilePath is not null)
- {
- return IsProjectFileFromPackageCache(Path.GetFullPath(anyProjectFilePath, DirectoryPath));
- }
-
- LogHelper.LogWarning($"The project file: {FilePath} has no content so skipping it.");
- return true;
- }
-
///
/// Writes the project file to disk inside .
///
@@ -114,7 +75,8 @@ internal static ProjectFileGeneratorBase Create(string filePath)
}
///
- /// Determines the root directory that contains all project files, the directory that contains the .
+ /// Determines the root directory that contains all project files, the directory that contains the
+ /// .
///
/// The absolute path to the project root directory.
internal string GetProjectRootDirectoryPath()
@@ -223,21 +185,6 @@ private static bool MatchesPattern(string value, IReadOnlyList pattern)
return true;
}
- private string ExtractAssemblyDefinitionFilePath()
- {
- var assemblyDefinitionFilePaths = ProjectElement.Descendants(XmlNamespace + "None")
- .Select(noneElement => noneElement.Attribute("Include")?.Value)
- .Where(noneItemPath => noneItemPath?.EndsWith(".asmdef", StringComparison.OrdinalIgnoreCase) == true)
- .ToList();
- if (assemblyDefinitionFilePaths.Count != 1)
- {
- throw new InvalidOperationException(
- $"The csproj file '{FilePath}' need to have exactly one '.asmdef' file but it has ['{string.Join("', '", assemblyDefinitionFilePaths)}']");
- }
-
- return Path.GetFullPath(assemblyDefinitionFilePaths[0], DirectoryPath);
- }
-
private void RemoveExcludedAnalyzers()
{
var excludedAnalyzers = GeneratorSettings.ExcludedAnalyzers;
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileParser.cs b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileParser.cs
index a588454..98b4907 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileParser.cs
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/ProjectFileParser.cs
@@ -13,6 +13,8 @@ namespace UnityVisualStudioSolutionGenerator
///
public class ProjectFileParser
{
+ private string? assemblyDefinitionFilePath;
+
///
/// Initializes a new instance of the class.
///
@@ -34,6 +36,18 @@ public ProjectFileParser(string filePath)
Path.GetDirectoryName(filePath) ?? throw new InvalidOperationException($"Failed to get directory path of '{filePath}'"));
}
+ ///
+ /// Gets the path of the assembly definition file associated with this project. It is extracted from the project file generated by Unity.
+ ///
+ public string AssemblyDefinitionFilePath
+ {
+ get
+ {
+ assemblyDefinitionFilePath ??= ExtractAssemblyDefinitionFilePath();
+ return assemblyDefinitionFilePath;
+ }
+ }
+
///
/// Gets the absolute path of the project file (.csproj).
///
@@ -54,6 +68,31 @@ public ProjectFileParser(string filePath)
///
protected string DirectoryPath { get; }
+ ///
+ /// Determines whether the project is from the package cache.
+ ///
+ /// True if the project file is from a package, False otherwise.
+ public bool IsProjectFromPackageCache()
+ {
+ if (assemblyDefinitionFilePath is not null)
+ {
+ return IsProjectFileFromPackageCache(assemblyDefinitionFilePath);
+ }
+
+ var anyProjectFilePath = ProjectElement.Descendants(XmlNamespace + "None")
+ .Concat(ProjectElement.Descendants(XmlNamespace + "Compile"))
+ .Select(element => element.Attribute("Include")?.Value)
+ .FirstOrDefault(itemPath => itemPath is not null);
+
+ if (anyProjectFilePath is not null)
+ {
+ return IsProjectFileFromPackageCache(Path.GetFullPath(anyProjectFilePath, DirectoryPath));
+ }
+
+ LogHelper.LogWarning($"The project file: {FilePath} has no content so skipping it.");
+ return true;
+ }
+
///
/// Read the Project file and extract all source code files. But exclude files that are inside a 'PackageCache'.
///
@@ -102,5 +141,20 @@ internal static bool IsProjectFileFromPackageCache(string projectFilePath)
$"{Path.DirectorySeparatorChar}Library{Path.DirectorySeparatorChar}PackageCache{Path.DirectorySeparatorChar}",
StringComparison.OrdinalIgnoreCase);
}
+
+ private string ExtractAssemblyDefinitionFilePath()
+ {
+ var assemblyDefinitionFilePaths = ProjectElement.Descendants(XmlNamespace + "None")
+ .Select(noneElement => noneElement.Attribute("Include")?.Value)
+ .Where(noneItemPath => noneItemPath?.EndsWith(".asmdef", StringComparison.OrdinalIgnoreCase) == true)
+ .ToList();
+ if (assemblyDefinitionFilePaths.Count != 1)
+ {
+ throw new InvalidOperationException(
+ $"The csproj file '{FilePath}' need to have exactly one '.asmdef' file but it has ['{string.Join("', '", assemblyDefinitionFilePaths)}']");
+ }
+
+ return Path.GetFullPath(assemblyDefinitionFilePaths[0], DirectoryPath);
+ }
}
}
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/SourceCodeFilesHandler.cs b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/SourceCodeFilesHandler.cs
index ee69321..7a96516 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/SourceCodeFilesHandler.cs
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/SourceCodeFilesHandler.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -32,7 +33,7 @@ public static void EnableNullableOnAllFiles(SolutionFile solutionFile)
Debug.Assert(Encoding.UTF8.GetBytes("#nullable enable").SequenceEqual(EnableNullableBytes), "Wrong enableNullableBytes detected.");
var (allProjects, _) = SolutionFileParser.Parse(solutionFile, false);
- var enableNullableReadBuffer = new byte[EnableNullableBytes.Length + 2];
+ var enableNullableReadBuffer = new byte[EnableNullableBytes.Length + Utf8BomBytes.Length];
// source code is small so we can read it into memory
var fullFileReadBuffer = new MemoryStream();
@@ -41,7 +42,14 @@ public static void EnableNullableOnAllFiles(SolutionFile solutionFile)
var originalProjectFilePath = Path.Combine(solutionFile.SolutionDirectoryPath, Path.GetFileName(projectFile.FilePath));
if (!File.Exists(originalProjectFilePath))
{
- LogHelper.LogWarning($"Can't find original (Unity) .csproj file at: '{originalProjectFilePath}'.");
+ var generatedProjectFileParser = new ProjectFileParser(projectFile.FilePath);
+ var assemblyDefinitionContent =
+ JsonUtility.FromJson(File.ReadAllText(generatedProjectFileParser.AssemblyDefinitionFilePath));
+ originalProjectFilePath = Path.Combine(solutionFile.SolutionDirectoryPath, $"{assemblyDefinitionContent.name}.csproj");
+ if (!File.Exists(originalProjectFilePath))
+ {
+ LogHelper.LogWarning($"Can't find original (Unity) .csproj file at: '{originalProjectFilePath}'.");
+ }
}
var projectFileParser = new ProjectFileParser(originalProjectFilePath);
@@ -58,7 +66,7 @@ public static void EnableNullableOnAllFiles(SolutionFile solutionFile)
/// The path to the file to add nullable setting to, if it doesn't already has it.
public static void AddNullableToFile(string sourceCodeFile)
{
- AddNullableToFile(sourceCodeFile, new byte[EnableNullableBytes.Length + 2], new MemoryStream());
+ AddNullableToFile(sourceCodeFile, new byte[EnableNullableBytes.Length + Utf8BomBytes.Length], new MemoryStream());
}
private static void AddNullableToFile(string sourceCodeFile, byte[] enableNullableReadBuffer, MemoryStream fullFileReadBuffer)
@@ -69,7 +77,7 @@ private static void AddNullableToFile(string sourceCodeFile, byte[] enableNullab
var readCount = fileStream.Read(enableNullableReadBuffer);
var readBytes = enableNullableReadBuffer.AsSpan(0, readCount);
var readBytesWithoutBom = readBytes;
- var hasUtf8Bom = readBytes.SequenceEqual(Utf8BomBytes);
+ var hasUtf8Bom = readBytes.StartsWith(Utf8BomBytes);
if (hasUtf8Bom)
{
readBytesWithoutBom = readBytes[Utf8BomBytes.Length..];
@@ -87,7 +95,7 @@ private static void AddNullableToFile(string sourceCodeFile, byte[] enableNullab
fullFileReadBuffer.Capacity = (int)fileStream.Length;
}
- fullFileReadBuffer.Write(readBytes);
+ fullFileReadBuffer.Write(readBytesWithoutBom);
fileStream.CopyTo(fullFileReadBuffer);
var newLineBytes = DetectNewLineBytes(fullFileReadBuffer);
@@ -95,17 +103,24 @@ private static void AddNullableToFile(string sourceCodeFile, byte[] enableNullab
// reset to start -> write enable nullable -> rest of file
fileStream.Position = 0;
+
+ if (hasUtf8Bom)
+ {
+ fileStream.Write(Utf8BomBytes);
+ }
+
fileStream.Write(EnableNullableBytes);
- var firstCharWasNewline = readBytes.StartsWith(newLineBytes);
+ var firstCharWasNewline = readBytesWithoutBom.StartsWith(newLineBytes);
if (!firstCharWasNewline)
{
fileStream.Write(newLineBytes);
}
- var secondCharWasNewLine = readBytes.IsEmpty ||
+ var secondCharWasNewLine = readBytesWithoutBom.IsEmpty ||
firstCharWasNewline &&
- (readBytes[Math.Min(newLineBytes.Length, readBytes.Length)..].StartsWith(newLineBytes) ||
- readBytes.Length == newLineBytes.Length);
+ (readBytesWithoutBom[Math.Min(newLineBytes.Length, readBytesWithoutBom.Length)..]
+ .StartsWith(newLineBytes) ||
+ readBytesWithoutBom.Length == newLineBytes.Length);
if (!secondCharWasNewLine)
{
fileStream.Write(newLineBytes);
@@ -143,5 +158,19 @@ private static byte[] DetectNewLineBytes(MemoryStream memoryStream)
previous = readByte;
}
}
+
+ [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local", Justification = "Instantiated by json-serializer.")]
+ private sealed class AssemblyDefinitionContent
+ {
+ [SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local", Justification = "Required by serializer.")]
+ [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Required by serializer.")]
+ [SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "Required by serializer.")]
+ [SuppressMessage(
+ "StyleCop.CSharp.NamingRules",
+ "SA1307:Accessible fields should begin with upper-case letter",
+ Justification = "Required by serializer.")]
+ [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Required by serializer.")]
+ public string name = string.Empty;
+ }
}
}
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/VisualStudioAssetPostprocessor.cs b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/VisualStudioAssetPostprocessor.cs
index 6445574..8fd2ee4 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/Editor/VisualStudioAssetPostprocessor.cs
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/Editor/VisualStudioAssetPostprocessor.cs
@@ -25,6 +25,16 @@ internal class VisualStudioAssetPostprocessor : AssetPostprocessor
private static DateTime lastSolutionGenerationTime;
+ ///
+ /// Clears the cached solution content so the next time the solution is generated.
+ ///
+ public static void MarkAsChanged()
+ {
+ lastSolutionGenerationTime = DateTime.MinValue;
+ lastInputSolutionContent = null;
+ lastOutputSolutionContent = null;
+ }
+
///
/// Called by unity if it reloads the assembly.
///
@@ -39,13 +49,17 @@ private static void Initialize()
var stopwatch = Stopwatch.StartNew();
var (allProjects, sourceContainsDuplicateProjects) = SolutionFileParser.Parse(solutionFile, false);
- if (!sourceContainsDuplicateProjects)
+ const string isSolutionGeneratedKey = "UnityVisualStudioSolutionGenerator.IsSolutionGenerated";
+ var isSolutionGenerated = SessionState.GetBool(isSolutionGeneratedKey, false);
+ if (!sourceContainsDuplicateProjects || isSolutionGenerated)
{
// if we don't call 'GenerateNewProjects' we need to ensure that all SourceCodeFileWatcher's are running
ProjectSourceCodeWatcherManager.Initialize(allProjects);
return;
}
+ SessionState.SetBool(isSolutionGeneratedKey, true);
+
// Sometimes 'OnGeneratedCSProjectFiles' is not called when the reload order is wrong so we regenerate it here.
// We detect this by checking if Unity generated the .sln and skipped all events like 'OnGeneratedCSProjectFiles'
// so the .sln contains both the .csproj from Unity and the one generated by GenerateNewProjects.
From 00b40bbef7a545a55671baa5bb7ae73d301853bb Mon Sep 17 00:00:00 2001
From: JoC0de <53140583+JoC0de@users.noreply.github.com>
Date: Sun, 24 Sep 2023 21:41:28 +0200
Subject: [PATCH 2/3] remove dublicat test case
---
.../Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs b/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
index cf350e9..bbe3a9b 100644
--- a/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
+++ b/src/UnityVisualStudioSolutionGenerator.Tests/Assets/Editor/Tests/SourceCodeFilesHandlerTest.cs
@@ -51,7 +51,6 @@ public class SourceCodeFilesHandlerTest
[TestCase("#nullable enable\n", "#nullable enable\n")]
[TestCase("#nullable enable\r\n", "#nullable enable\r\n")]
[TestCase("#nullable enable\n\npublic class Test\n{\n}\n", "#nullable enable\n\npublic class Test\n{\n}\n")]
- [TestCase("public class Test\n{\n}\n", "#nullable enable\n\npublic class Test\n{\n}\n")]
public void SourceCodeFilesHandlerSimpleTest(string testSourceCode, string expectedSourceCode)
{
if (!testSourceCode.Contains('\n', StringComparison.Ordinal))
@@ -123,17 +122,17 @@ public void SourceCodeFilesHandlerMultiFileTest(string testSourceCode, string ex
}
[Test]
- public void TestByteOrderMaskHandling([Values] bool withBom, [Values] bool alreadyHasNullable)
+ public void TestByteOrderMaskHandling([Values] bool withByteOrderMask, [Values] bool alreadyHasNullable)
{
const string testSourceCode1FilePath = "TestSourceCode.cs";
- var utf8Encoding = new UTF8Encoding(withBom);
+ var utf8Encoding = new UTF8Encoding(withByteOrderMask);
try
{
const string contentWithNullable = "#nullable enable\n\npublic class Test\n{\n}\n";
File.WriteAllText(testSourceCode1FilePath, alreadyHasNullable ? contentWithNullable : "public class Test\n{\n}\n", utf8Encoding);
SourceCodeFilesHandler.AddNullableToFile(testSourceCode1FilePath);
var expected = utf8Encoding.GetBytes(contentWithNullable);
- if (withBom)
+ if (withByteOrderMask)
{
expected = Encoding.UTF8.GetPreamble().Concat(expected).ToArray();
}
From 8e6eb79cefef1935cb4d5b9c8a98ad035d0e74f2 Mon Sep 17 00:00:00 2001
From: JoC0de <53140583+JoC0de@users.noreply.github.com>
Date: Sun, 24 Sep 2023 21:43:12 +0200
Subject: [PATCH 3/3] change version number to 1.0.9
---
src/UnityVisualStudioSolutionGenerator/Assets/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/UnityVisualStudioSolutionGenerator/Assets/package.json b/src/UnityVisualStudioSolutionGenerator/Assets/package.json
index f5eda93..f02defa 100644
--- a/src/UnityVisualStudioSolutionGenerator/Assets/package.json
+++ b/src/UnityVisualStudioSolutionGenerator/Assets/package.json
@@ -1,7 +1,7 @@
{
"name": "com.github-joc0de.visual-studio-solution-generator",
"displayName": "Unity Visual Studio Solution Generator",
- "version": "1.0.8",
+ "version": "1.0.9",
"description": "Visual Studio Solution Generator with improved developer productivity especially when working with multi-package unity projects",
"unity": "2021.2",
"keywords": [