NuGroom

Features

Detailed documentation of NuGroom’s analysis and management features.


Central Package Management (CPM)

The tool automatically detects and supports Central Package Management in scanned repositories.

How It Works

  1. When scanning a repository, the tool looks for Directory.Packages.props files
  2. If the file contains <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>, CPM is active
  3. All <PackageVersion Include="..." Version="..."/> entries are read into a version lookup
  4. Project files with <PackageReference> entries that omit a Version attribute have their versions populated from the CPM lookup
  5. If a project file specifies VersionOverride, that version takes precedence over the central version

MSBuild Variable Resolution

Directory.Packages.props files commonly use MSBuild property variables ($(PropertyName)) to define package versions in a single place. NuGroom automatically resolves these variables during scanning so that the actual version number is used for analysis, warnings, and updates.

Supported patterns:

Pattern Example Resolved
Simple variable $(NetCoreVersion)10.0.0 10.0.0
Composed variables $(MajorVersion).$(MinorVersion).$(PatchVersion) 13.0.3
Indirect reference $(FullVersion) where FullVersion = $(Major).$(Minor).$(Patch) 13.0.3
Partial literal $(MajorVersion).0.3 13.0.3

Behavior details:

Example:

<Project>
  <PropertyGroup>
    <NetCoreVersion>10.0.0</NetCoreVersion>
    <JsonVersion>13.0.3</JsonVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(NetCoreVersion)" />
    <PackageVersion Include="Newtonsoft.Json" Version="$(JsonVersion)" />
    <PackageVersion Include="Serilog" Version="3.1.1" />
  </ItemGroup>
</Project>

NuGroom resolves this as:

No configuration is needed — variable resolution happens automatically whenever a Directory.Packages.props file is parsed.

Auto-Update Behavior

When CPM is active, package version updates target Directory.Packages.props instead of individual project files. This means a single update to the central props file can update the version for all projects in the repository.

No configuration is needed — CPM detection is automatic.

Migrating to CPM

For repositories that do not yet use Central Package Management, the --migrate-to-cpm option generates a Directory.Packages.props file and updates all project files to remove inline Version attributes.

Dry-run preview:

NuGroom --config settings.json --migrate-to-cpm --dry-run

Apply migration (creates branches and PRs):

NuGroom --config settings.json --migrate-to-cpm --update-references

How Migration Works

  1. All scanned project files with explicit <PackageReference ... Version="..."/> are collected
  2. Package versions are merged across projects — the highest version of each package becomes the central version in Directory.Packages.props
  3. If different projects reference different versions of the same package, the project with the lower version receives a VersionOverride attribute and a warning is emitted
  4. A Directory.Packages.props file is created at the repository root (or per project with --per-project)
  5. Each project file is modified to remove inline Version attributes from <PackageReference> elements

Version Conflict Resolution

When multiple projects reference different versions of the same package, the migration resolves the conflict as follows:

For example, given two projects:

The migration produces:

Directory.Packages.props (central version: highest)

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
  </ItemGroup>
</Project>

App1.csproj (version removed — uses central version)

<PackageReference Include="Newtonsoft.Json" />

App2.csproj (gets VersionOverride to preserve lower version)

<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.0" />

Warning emitted:

Version conflict: package 'Newtonsoft.Json' in project 'src/App2/App2.csproj'
  uses version 12.0.0 (VersionOverride) while central version is 13.0.3

Per-Project Mode

By default, --migrate-to-cpm creates a single Directory.Packages.props at the repository root. Use --per-project to create a separate file alongside each project file instead:

NuGroom --config settings.json --migrate-to-cpm --per-project --dry-run

In per-project mode:

Important: When migrating a repository that already contains a Directory.Packages.props file (mixed repo), the migration merges existing PackageVersion entries into the generated output so they are not lost. However, the output file is regenerated from scratch — any other XML content in the original file such as comments, conditions, extra PropertyGroup elements, or custom items is not preserved.

Target Branch Auto-Creation

When the CPM migration creates pull requests and the configured target branch does not exist, the tool automatically creates it from the source branch instead of skipping the repository.

This allows migrations to target branches that do not yet exist, for example when introducing a new branching strategy alongside the CPM migration.


Legacy packages.config Support

For repositories that still use the legacy packages.config format (common in .NET Framework projects), the tool can optionally scan and extract package references from these files.

Enabling

Legacy packages.config scanning is opt-in to avoid noise in modern codebases:

CLI:

NuGroom --config settings.json --include-packages-config

Config file:

{
  "IncludePackagesConfig": true
}

How It Works

  1. The tool discovers packages.config files in the repository
  2. Each file is associated with the co-located project file (.csproj, .vbproj, or .fsproj in the same directory)
  3. <package id="..." version="..."/> entries are extracted and tagged as PackagesConfig source kind
  4. Exclusion rules (prefix, exact, pattern) apply as usual
  5. Packages already discovered via <PackageReference> in the same project are deduplicated

Multi-Feed Resolution

Specify one or more feeds with --feed. The resolver queries each feed until a package is found, selecting the first match. The originating feed host is displayed next to each package.

Benefits:


Version Warnings

The version warning system helps identify version inconsistencies across your repositories.

Warning Types

  1. Version Mismatch (Used): Package version differs from the latest version used in other projects
  2. Version Mismatch (Available): Package version differs from the latest available version on feeds

Warning Levels

Configuration Examples

Warn About Minor Version Differences Globally

{
  "VersionWarnings": {
    "DefaultLevel": "Minor"
  }
}

Package-Specific Rules

{
  "VersionWarnings": {
    "DefaultLevel": "Minor",
    "PackageRules": [
      {
        "PackageName": "Newtonsoft.Json",
        "Level": "Major"
      },
      {
        "PackageName": "Microsoft.Extensions.Logging",
        "Level": "None"
      }
    ]
  }
}

Output Example

VERSION WARNINGS
================================================================================

Newtonsoft.Json:
  ⚠ Repository1/Project1.csproj
    Package version 12.0.3 differs from latest available version 13.0.3 (major version difference)

Serilog:
  ⚠ Repository2/Project2.csproj
    Package version 2.10.0 differs from latest used version 2.12.0 (minor version difference)

--------------------------------------------------------------------------------
Total warnings: 2
Packages with warnings: 2
Major version differences: 1
Minor version differences: 1

Package Update Recommendations

When version warnings are configured, the tool automatically generates actionable package update recommendations.

The tool recommends updates for packages where:

  1. Version warnings are configured (global or package-specific)
  2. A newer version exists that differs according to the warning level
  3. The package should be updated to either:
    • Latest available version from configured feeds (preferred)
    • Latest version already used in other projects in the solution

Recommendation Output

The recommendations section shows:

Recommendations are automatically generated whenever version warnings are configured. No additional configuration is needed. Set "DefaultLevel": "None" to disable.


Project File Filtering

Exclude specific project files from analysis using regex patterns.

Common Use Cases

Exclude Test Projects:

{
  "ExcludeProjectPatterns": [
    ".*\\.Test[s]?\\.csproj$",
    ".*\\.UnitTests\\.csproj$",
    ".*\\.IntegrationTests\\.csproj$"
  ]
}

Exclude Specific Project Types:

{
  "ExcludeProjectPatterns": [
    ".*\\.Benchmarks\\.csproj$",
    ".*\\.Samples\\.csproj$",
    ".*\\.Demo\\.csproj$"
  ]
}

Case-Sensitive Matching:

{
  "ExcludeProjectPatterns": [".*\\.TEST\\.csproj$"],
  "CaseSensitiveProjectFilters": true
}

Health & Risk Indicators

The tool flags packages with risk indicators:

Summary sections list all Deprecated, Outdated, and Vulnerable packages with details.


Vulnerability-Only Scan

Use --list-vulnerabilities to scan all packages exclusively for known vulnerabilities without making any changes. This mode performs a full package scan (local or Azure DevOps), runs vulnerability checks against NuGet feed advisories and the OSV.dev database, and reports only the vulnerable packages.

Behavior

Use Cases

Examples

# Local vulnerability scan
nugroom --paths ./src --list-vulnerabilities

# Azure DevOps vulnerability scan
nugroom --config settings.json --list-vulnerabilities

# With exported report for CI artifacts
nugroom --paths ./src --list-vulnerabilities --export-vulnerabilities vuln-report.json

See Vulnerability Scanning for full details on data sources, caching, and configuration.


Internal Package Source Detection

Cross-references packages not found on public feeds with project sources:


Debug Logging

Enable detailed diagnostic output for troubleshooting.

Automatic Enabling

Debug logging is automatically enabled when running with a debugger attached (e.g., from Visual Studio).

Manual Enabling

NuGroom --config settings.json --debug

Debug Output Includes

Debug messages are displayed in gray color with [DEBUG] prefix and timestamp.


See also: Automated Updates · Export Formats · Renovate Compatibility