Add code analysis ruleset through nuget package
Asked Answered
C

3

10

I'm trying to build a NuGet package that adds our company's code analysis dictionary automatically and updatable.

The rule set is added in the content folder and now I want to use the install.ps1 script to add the rule set in the project file.
I figured out the way to go would be to use the envDTE, but I can't find much useful documentation about it other then this overwhelming object graph in which I can't find the CodeAnalysisRuleset node.
http://msdn.microsoft.com/en-us/library/za2b25t3(v=vs.100).aspx

Am I pursuing the right path?
Is there any relevant tutorial/documentation on how to use the envDTE in NuGet powershell?
How can I run/debug my install script without having to actually add it to a package and install it against a project?

Sidenote
Although @Nicole Calinoiu showed the better way, this morsel of information might come in handy later on:

foreach ($config in $project.ConfigurationManager){
  $config.Properties.Item("CodeAnalysisRuleSet").Value = "myruleset.ruleset"
}
Crete answered 28/11, 2013 at 13:17 Comment(0)
K
18

There's no need to script this. Both the ruleset and dictionary can be registered via an imported MSBuild .props file, as described here https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#include-msbuild-props-and-targets-in-a-package

For example, your NuGet source folder structure might look like this (assuming "CodeAnalysisSettings" is your package ID):

  • build
    • CodeAnalysisSettings.props
  • content
    • MyCustomDictionary.xml
    • MyRules.ruleset

where the contents of CodeAnalysisSettings.props are something like the following:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <RunCodeAnalysis>true</RunCodeAnalysis>
        <CodeAnalysisRuleSet>MyRules.ruleset</CodeAnalysisRuleSet>
    </PropertyGroup>
    <ItemGroup>
        <CodeAnalysisDictionary Include="MyCustomDictionary.xml" />
    </ItemGroup>
</Project>
Kindliness answered 28/11, 2013 at 17:22 Comment(6)
Dammit! I just found it yesterday evening! And I finished the package to import the dictionary too. Thanks though :)Crete
Is there something I'm missing here? I created the props file, yet NuGet adds the CodeAnalysisDictionary as a type of Content when it should be a type of CodeAnalysisDictionary. I'm not sure why. It works fine when I use Compile for my cs files though.Linlithgow
That's because the VS UI uses different rules for deciding the content type than the code analysis MSBuild files do. Despite the UI display anomaly, you should find that your dictionary is being used by Code Analysis.Kindliness
@NicoleCalinoiu: Sadly, this is not the case. I created a NuGet package and published it on my local hard drive. When I added the package through "Manage NuGet Packages...", it did correctly add the files in the right location. However, because the dictionary is marked as a type of Content instead of a CodeAnalysisDictionary the Code Analysis engine does not recognize it and does not use the custom dictionary. You can reproduce this issue by breaking the CA1709 rule (create a public class named NuGet). Adding the dictionary (via NuGet) as Content does not fix this issue.Linlithgow
@m-y: What did you put in the dictionary? Did you add "Nu" as a casing exception in the acronyms section? This does work for me with a dictionary added via a NuGet package as described.Kindliness
@NicoleCalinoiu: Can you please share your NuGet solution (unpacked and packed) as well as a sample project. Whenever I use NuGet to get the dictionary file imported VS2013 marks it as a type of Content, which the CodeAnalysis engine ignores... the engine only ever looks for files marked as CodeAnalysisDictionary under the "Properties" of the file.Linlithgow
C
1

I had the same problem as reported in the comments: the dictionary was added as content, not as a CodeAnalysisDictionary.

I added this piece of code in the install.ps1 of the nuget package to solve this:

$dictionary = $project.ProjectItems | Where-Object {$_.Name.EndsWith("CustomDictionary.xml")}
$dictionary.Properties.Item("Buildaction").Value = [int]5;
Casual answered 25/11, 2016 at 9:43 Comment(0)
D
-3

You can also do it manually by using the following steps.

  • Right click project
  • Go to properties
  • Go to the dropdown [Run this rule set]
  • Select the [Browse..] option
  • Choose your company ruleset which you may place at a predefined location in source code.
  • Click Open on the Open window
  • Save the project file.

You may repeat the step for other projects in the solution.

Doyon answered 10/12, 2013 at 7:43 Comment(1)
That is what we are doing today. But with the hundreds of projects we have, the total sum of wasted time combined with the human errors that occur from time to time. A nuget package would be more interesting.Crete

© 2022 - 2024 — McMap. All rights reserved.