├── Editor.meta ├── Editor ├── Source.meta └── Source │ ├── ProjectFilesGeneration.cs │ └── ProjectFilesGeneration.cs.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── RequiredPackages.meta ├── RequiredPackages ├── StyleCop.Analyzers.CodeFixes.dll ├── StyleCop.Analyzers.CodeFixes.dll.meta ├── StyleCop.Analyzers.dll ├── StyleCop.Analyzers.dll.meta ├── UnityStyleCop.ruleset ├── UnityStyleCop.ruleset.meta ├── stylecop.json └── stylecop.json.meta ├── Stylecop.Analyzer.asmdef ├── Stylecop.Analyzer.asmdef.meta ├── package.json └── package.json.meta /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90b4c3b86c0f64dd4925788cf1cd7b6e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Source.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a7d9de44ef51b498c97d12ac8a3c63f4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Source/ProjectFilesGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace StyleCop.Analyzer 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Xml.Linq; 9 | using UnityEditor; 10 | using UnityEngine; 11 | 12 | /// 13 | /// Customize the project file generation with Roslyn Analyzers and custom c# version. 14 | /// 15 | public class ProjectFilesGeneration : AssetPostprocessor 16 | { 17 | private const string DefaultDirectory = "Packages/Unity-StyleCop/RequiredPackages"; 18 | private const string StyleCopAnalyzerDllName = "StyleCop.Analyzers.dll"; 19 | private const string StyleCopAnalyzerCodeFixesDllName = "StyleCop.Analyzers.CodeFixes.dll"; 20 | private const string StyleCopRulesetFileName = "UnityStyleCop.ruleset"; 21 | private const string StyleCopJsonFileName = "stylecop.json"; 22 | 23 | private static bool ValidateAnalyzerFolderIsSetup() 24 | { 25 | string currentDirectory = Directory.GetCurrentDirectory(); 26 | string analyzerDirectory = Path.Combine(currentDirectory, DefaultDirectory); 27 | if (!Directory.Exists(analyzerDirectory)) 28 | { 29 | return false; 30 | } 31 | 32 | IEnumerable files = Directory.GetFiles(analyzerDirectory).Select(Path.GetFileName).ToArray(); 33 | return files.Contains(StyleCopJsonFileName) && 34 | files.Contains(StyleCopAnalyzerDllName) && 35 | files.Contains(StyleCopAnalyzerCodeFixesDllName) && 36 | files.Contains(StyleCopRulesetFileName); 37 | } 38 | 39 | private static string OnGeneratedCSProject(string path, string contents) 40 | { 41 | #if STYLECOP_DEBUG 42 | Debug.Log("*.csproj change detected. Ensuring it adds StyleCop to project."); 43 | #endif 44 | XDocument xml = XDocument.Parse(contents); 45 | 46 | AddStyleCopRoslynAnalyzerToProjectFile(xml); 47 | 48 | using (var str = new Utf8StringWriter()) 49 | { 50 | xml.Save(str); 51 | return str.ToString(); 52 | } 53 | } 54 | 55 | private static void AddStyleCopRoslynAnalyzerToProjectFile(XDocument doc) 56 | { 57 | XElement projectContentElement = doc.Root; 58 | if (projectContentElement == null) 59 | { 60 | return; 61 | } 62 | 63 | XNamespace xmlns = projectContentElement.Name.NamespaceName; // do not use var 64 | AddStyleCopRoslynAnalyzer(projectContentElement, xmlns); 65 | } 66 | 67 | private static void AddStyleCopRoslynAnalyzer( 68 | XElement rootElement, 69 | XNamespace xmlNameSpace) 70 | { 71 | string currentDirectory = Directory.GetCurrentDirectory(); 72 | if (!ValidateAnalyzerFolderIsSetup()) 73 | { 74 | #if STYLECOP_DEBUG 75 | Debug.Log("One of the StyleCop required files is missing!"); 76 | #endif 77 | return; 78 | } 79 | 80 | var requiredFilesDirectoryInfo = new DirectoryInfo(Path.Combine(currentDirectory, DefaultDirectory)); 81 | FileInfo[] files = requiredFilesDirectoryInfo.GetFiles(); 82 | var itemGroup = new XElement(xmlNameSpace + "ItemGroup"); 83 | foreach (FileInfo file in files) 84 | { 85 | string extension = file.Extension; 86 | switch (extension) 87 | { 88 | case ".dll": 89 | { 90 | var reference = new XElement(xmlNameSpace + "Analyzer"); 91 | reference.Add(new XAttribute("Include", file)); 92 | itemGroup.Add(reference); 93 | break; 94 | } 95 | 96 | case ".json": 97 | { 98 | var reference = new XElement(xmlNameSpace + "AdditionalFiles"); 99 | reference.Add(new XAttribute("Include", file)); 100 | itemGroup.Add(reference); 101 | break; 102 | } 103 | 104 | case ".ruleset": 105 | SetOrUpdateProperty( 106 | rootElement, 107 | xmlNameSpace, 108 | "CodeAnalysisRuleSet", 109 | existing => file.FullName); 110 | break; 111 | } 112 | } 113 | 114 | rootElement.Add(itemGroup); 115 | } 116 | 117 | private static void SetOrUpdateProperty( 118 | XContainer root, 119 | XNamespace xmlns, 120 | string name, 121 | Func updater) 122 | { 123 | XElement element = root.Elements(xmlns + "PropertyGroup").Elements(xmlns + name).FirstOrDefault(); 124 | if (element != null) 125 | { 126 | string result = updater(element.Value); 127 | if (result != element.Value) 128 | { 129 | element.SetValue(result); 130 | } 131 | } 132 | else 133 | { 134 | AddProperty(root, xmlns, name, updater(string.Empty)); 135 | } 136 | } 137 | 138 | private static void AddProperty( 139 | XContainer root, 140 | XNamespace xmlns, 141 | string name, 142 | string content) 143 | { 144 | XElement propertyGroup = root.Elements(xmlns + "PropertyGroup") 145 | .FirstOrDefault(e => !e.Attributes(xmlns + "Condition").Any()); 146 | if (propertyGroup == null) 147 | { 148 | propertyGroup = new XElement(xmlns + "PropertyGroup"); 149 | root.AddFirst(propertyGroup); 150 | } 151 | 152 | propertyGroup.Add(new XElement(xmlns + name, content)); 153 | } 154 | 155 | private class Utf8StringWriter : StringWriter 156 | { 157 | public override Encoding Encoding 158 | { 159 | get { return Encoding.UTF8; } 160 | } 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /Editor/Source/ProjectFilesGeneration.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 274edcc8400a34d16b16faca3e4ab0f8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Luis Placid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 36af47cfd95584a4ca0e02c75bd0a5bf 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity-StyleCop 2 | 3 | A StyleCop integration package for Unity. 4 | 5 | ## About StyleCop 6 | 7 | StyleCop is an open source static code analysis tool that checks for code style 8 | violations. The default rules were established by consolidating the preferences 9 | of various teams across Microsoft and are designed to emphasize readability and 10 | maintainability of C# code, but users can also customize their own rules 11 | 12 | The version of StyleCop used by this system is based on the new [StyleCop.Analyzer 13 | package.](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) vs using the old 14 | StyleCop convention so that its portable to Rider as well as Visual Studio for 15 | Windows & Mac OS. **It does not work on VS Code as it doesn't support it as** 16 | **far as I am aware** 17 | 18 | ## Installing this Package 19 | 20 | - Open your preferred command line window and navigate to the root of your unity 21 | project. 22 | - Navigate to the `Packages` folder. 23 | - Clone this repository as follows: 24 | 25 | ```bash 26 | git clone https://github.com/ImLp/Unity-StyleCop 27 | ``` 28 | 29 | The package is now installed and ready to go. 30 | 31 | ## Using This Package 32 | 33 | After integrating this package to your project, it will automatically add itself 34 | to all detected `*.csproj` in your project ensuring all code is covered. 35 | 36 | This package includes a `UnityStyleCop.ruleset` file which drives all the rules 37 | being applied. This can be edited to match the team stylistic preference. 38 | All StyleCop rules have been annotated for convenience. 39 | 40 | ## Why Coding Style Matters - An opinion 41 | 42 | Good quality code is not based just in its execution. Good quality code is a readable, 43 | maintainable source that any engineer could understand and modify without requiring 44 | arcane knowledge about its functionality to fix / improve something. 45 | 46 | There is no magic bullet when it comes to a package that would make code be good 47 | quality code. Nonetheless if proper standards are followed you can get very close 48 | to a source base where you can develop with ease. StyleCop is a heavy handed approach, 49 | but it does push you towards embracing: 50 | 51 | - Correct documentation of Public APIs between classes ensuring readability and 52 | better maintainability. 53 | - Enforcement of correct encapsulation by discouraging use of `public` members. 54 | - Consistent naming conventions for readability. 55 | - Implicit enforcement of single responsibility principles by discouraging multiple 56 | classes in a single file (default rules). 57 | 58 | Unity encourages c# anti-patterns that simply lead to problematic code. Let's do 59 | better. -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d15b57274c6e64bb6977c80a19cb2955 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /RequiredPackages.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32491711bd6044ccaadecdde40a49131 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RequiredPackages/StyleCop.Analyzers.CodeFixes.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImLp/Unity-StyleCop/c5bb1d7de2f9f980d9b9db6a8fee70b0ada46998/RequiredPackages/StyleCop.Analyzers.CodeFixes.dll -------------------------------------------------------------------------------- /RequiredPackages/StyleCop.Analyzers.CodeFixes.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 592a11a95c76d4880b851c27d645619a 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 1 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Editor: 1 20 | Exclude Linux64: 1 21 | Exclude OSXUniversal: 1 22 | Exclude WebGL: 1 23 | Exclude Win: 1 24 | Exclude Win64: 1 25 | Exclude iOS: 1 26 | - first: 27 | Any: 28 | second: 29 | enabled: 0 30 | settings: {} 31 | - first: 32 | Editor: Editor 33 | second: 34 | enabled: 0 35 | settings: 36 | CPU: AnyCPU 37 | DefaultValueInitialized: true 38 | OS: AnyOS 39 | - first: 40 | Standalone: Linux64 41 | second: 42 | enabled: 0 43 | settings: 44 | CPU: None 45 | - first: 46 | Standalone: OSXUniversal 47 | second: 48 | enabled: 0 49 | settings: 50 | CPU: None 51 | - first: 52 | Standalone: Win 53 | second: 54 | enabled: 0 55 | settings: 56 | CPU: None 57 | - first: 58 | Standalone: Win64 59 | second: 60 | enabled: 0 61 | settings: 62 | CPU: None 63 | - first: 64 | Windows Store Apps: WindowsStoreApps 65 | second: 66 | enabled: 0 67 | settings: 68 | CPU: AnyCPU 69 | - first: 70 | iPhone: iOS 71 | second: 72 | enabled: 0 73 | settings: 74 | AddToEmbeddedBinaries: false 75 | CPU: AnyCPU 76 | CompileFlags: 77 | FrameworkDependencies: 78 | userData: 79 | assetBundleName: 80 | assetBundleVariant: 81 | -------------------------------------------------------------------------------- /RequiredPackages/StyleCop.Analyzers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImLp/Unity-StyleCop/c5bb1d7de2f9f980d9b9db6a8fee70b0ada46998/RequiredPackages/StyleCop.Analyzers.dll -------------------------------------------------------------------------------- /RequiredPackages/StyleCop.Analyzers.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb563adc11f534222b3d37c02ce72523 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 1 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Editor: 1 20 | Exclude Linux64: 1 21 | Exclude OSXUniversal: 1 22 | Exclude WebGL: 1 23 | Exclude Win: 1 24 | Exclude Win64: 1 25 | Exclude iOS: 1 26 | - first: 27 | Any: 28 | second: 29 | enabled: 0 30 | settings: {} 31 | - first: 32 | Editor: Editor 33 | second: 34 | enabled: 0 35 | settings: 36 | CPU: AnyCPU 37 | DefaultValueInitialized: true 38 | OS: AnyOS 39 | - first: 40 | Standalone: Linux64 41 | second: 42 | enabled: 0 43 | settings: 44 | CPU: None 45 | - first: 46 | Standalone: OSXUniversal 47 | second: 48 | enabled: 0 49 | settings: 50 | CPU: None 51 | - first: 52 | Standalone: Win 53 | second: 54 | enabled: 0 55 | settings: 56 | CPU: None 57 | - first: 58 | Standalone: Win64 59 | second: 60 | enabled: 0 61 | settings: 62 | CPU: None 63 | - first: 64 | Windows Store Apps: WindowsStoreApps 65 | second: 66 | enabled: 0 67 | settings: 68 | CPU: AnyCPU 69 | - first: 70 | iPhone: iOS 71 | second: 72 | enabled: 0 73 | settings: 74 | AddToEmbeddedBinaries: false 75 | CPU: AnyCPU 76 | CompileFlags: 77 | FrameworkDependencies: 78 | userData: 79 | assetBundleName: 80 | assetBundleVariant: 81 | -------------------------------------------------------------------------------- /RequiredPackages/UnityStyleCop.ruleset: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | -------------------------------------------------------------------------------- /RequiredPackages/UnityStyleCop.ruleset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9863c86d5366b4c86b3d479418a6afe3 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /RequiredPackages/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json" 3 | } 4 | -------------------------------------------------------------------------------- /RequiredPackages/stylecop.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7bb54e758ae094aa19ef5915e1d87bc0 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Stylecop.Analyzer.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StyleCop.Analyzer", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } 16 | -------------------------------------------------------------------------------- /Stylecop.Analyzer.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9abc9f6d1ce5a41f2bef8f0af8cad4ea 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.stylecop.analyzer", 3 | "description": "A package to easily add the Roslyn Stylecop.Analyzer package to an Unity project.", 4 | "version": "1.0.0", 5 | "unity": "2018.3", 6 | "displayName": "StyleCop.Analyzer", 7 | "hideInEditor": false 8 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ef6a27c6917a14b8093db2b1a5935ffc 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------