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"
}
Boris Callens
  • 90,659
  • 85
  • 207
  • 305

3 Answers3

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>
LarryDavid
  • 736
  • 6
  • 16
Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • Dammit! I just found it yesterday evening! And I finished the package to import the dictionary too. Thanks though :) – Boris Callens Nov 29 '13 at 08:40
  • 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. – myermian Jan 23 '14 at 18:03
  • 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. – Nicole Calinoiu Jan 23 '14 at 18:49
  • @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. – myermian Jan 28 '14 at 23:31
  • @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. – Nicole Calinoiu Jan 29 '14 at 17:05
  • 1
    @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. – myermian Jan 29 '14 at 19:10
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;
ettanany
  • 19,038
  • 9
  • 47
  • 63
-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.

Krishna
  • 170
  • 7
  • 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. – Boris Callens Dec 10 '13 at 14:19