Skip to content

Instantly share code, notes, and snippets.

@ArztSamuel
Last active June 8, 2020 23:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArztSamuel/cdcf4534f1534ce3823c16c6eeed75f3 to your computer and use it in GitHub Desktop.
Save ArztSamuel/cdcf4534f1534ce3823c16c6eeed75f3 to your computer and use it in GitHub Desktop.
Using Roslyn Analyzers in combination with Unity
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value=".\Assets\Nuget" />
</config>
</configuration>
// Put this file inside Assets/Editor/
// This script generates the appropriate .csproj and csc.rsp files in order to
// also include your Roslyn Analyzers in the Visual Studio Project
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class PostProcessAssets : AssetPostprocessor
{
private const string ITEM_GROUP_SEARCH = @"<ItemGroup>";
private const string ANALYZER_DIR = @"\Assets\Nuget\"; // Use the same path as defined in 'nuget.config' here
private const string ITEM_GROUP_STRING = "<ItemGroup>\r\n";
private const string ITEM_GROUP_END_STRING = " </ItemGroup>\r\n ";
private const string ANALYZER_STRING_START = " <Analyzer Include=\"";
private const string ANALYZER_STRING_END = "\"/>\r\n";
private static void OnGeneratedCSProjectFiles()
{
string dir = Directory.GetCurrentDirectory();
string[] analyzerPaths = Directory.GetFiles(dir + ANALYZER_DIR, "*.dll", SearchOption.AllDirectories);
// Shorten analyzerPaths to be relative
for (int i = 0; i < analyzerPaths.Length; i++)
{
int assetsIndex = analyzerPaths[i].IndexOf("\\Assets\\");
if (assetsIndex > 0)
analyzerPaths[i] = analyzerPaths[i].Substring(assetsIndex + 1); // + 1 to cut off first \
}
// Add analyzers to csproj files
string[] csprojFiles = Directory.GetFiles(dir, "*.csproj");
foreach (string file in csprojFiles)
CsprojAddAnalyzers(file, analyzerPaths);
// Add analyzers to csc.rsp
string[] cscRspFiles = Directory.GetFiles(dir + "\\Assets\\", "csc.rsp");
if (cscRspFiles.Length == 0)
{
cscRspFiles = new string[1];
cscRspFiles[0] = dir + "\\Assets\\csc.rsp";
}
else if (cscRspFiles.Length > 1)
Debug.LogWarning("More than one csc rsp file defined in assets folder.");
RspAddAnalyzer(cscRspFiles[0], analyzerPaths);
}
private static void CsprojAddAnalyzers(string filePath, string[] analyzerPaths)
{
string fileContent = File.ReadAllText(filePath);
int firstItemGroupIndex = fileContent.IndexOf(ITEM_GROUP_SEARCH);
if (firstItemGroupIndex < 0)
{
Debug.LogWarning("Could not find ItemGroup to add analyzer to csproj file.");
return;
}
StringBuilder stringBuilder = new StringBuilder(fileContent, 0, firstItemGroupIndex, fileContent.Length);
stringBuilder.Append(ITEM_GROUP_STRING);
foreach (string analyzer in analyzerPaths)
{
stringBuilder.Append(ANALYZER_STRING_START);
stringBuilder.Append(analyzer);
stringBuilder.Append(ANALYZER_STRING_END);
}
stringBuilder.Append(ITEM_GROUP_END_STRING);
stringBuilder.Append("");
stringBuilder.Append(fileContent, firstItemGroupIndex, fileContent.Length - firstItemGroupIndex);
File.WriteAllText(filePath, stringBuilder.ToString());
}
private static void RspAddAnalyzer(string filePath, string[] analyzerPaths)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (string analyzer in analyzerPaths)
{
stringBuilder.Append("-a:");
stringBuilder.AppendLine(analyzer);
}
File.WriteAllText(filePath, stringBuilder.ToString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment