Skip to content

DotNetClassicTool incompatible with central package management #41

@bgrainger

Description

@bgrainger

Switch a project using Faithlife.Build to central package management.

After you do, DotNetClassicTool.TryCreateFrom fails, because the <PackageReference> element no longer has a @Version attribute. Failing code is:

var packageVersion = ((IEnumerable) XDocument.Load(projectPath).XPathEvaluate("//PackageReference"))
.OfType<XElement>()
.Where(x => string.Equals(x.Attribute("Include")?.Value, packageName, StringComparison.OrdinalIgnoreCase))
.Select(x => x.Attribute("Version")?.Value)
.FirstOrDefault();

An example project that repros the bug is https://github.com/bgrainger/CentrallyManagedTool.

One solution would be to hard-code checks for Directory.Packages.props and look there for the version, but also respect @VersionOverride etc. However, it seems less brittle to use MSBuild to parse the project file and resolve the version to use.

Based on dotnet outdated, one way to do this is to shell out to MSBuild, then parse the JSON it produces: https://github.com/dotnet-outdated/dotnet-outdated/blob/782521a01639e4387dd6b3fa36f8e25cd279f137/src/DotNetOutdated.Core/Services/DependencyGraphService.cs#L28

Here's sample output from msbuild CentrallyManagedTool.csproj /t:Restore,GenerateRestoreGraphFile /p:RestoreGraphOutputPath=X:\Temp\graph.json. Note that it appears that one would need to parse version ranges that look like "NUnit.ConsoleRunner": "[3.15.2, )" in order to find a range of versions that might be installed. I don't know if there's a way to resolve it to the version that actually would get restored?

{
  "format": 1,
  "restore": {
    "X:\\CentrallyManagedTool\\CentrallyManagedTool.csproj": {}
  },
  "projects": {
    "X:\\CentrallyManagedTool\\CentrallyManagedTool.csproj": {
      "version": "1.0.0",
      "restore": {
        "projectUniqueName": "X:\\CentrallyManagedTool\\CentrallyManagedTool.csproj",
        "projectName": "CentrallyManagedTool",
        "projectPath": "X:\\CentrallyManagedTool\\CentrallyManagedTool.csproj",
        "packagesPath": "X:\\Users\\me\\.nuget\\packages\\",
        "outputPath": "X:\\CentrallyManagedTool\\obj\\",
        "projectStyle": "PackageReference",
        "centralPackageVersionsManagementEnabled": true,
        "fallbackFolders": [
          "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
        ],
        "configFilePaths": [
          "X:\\CentrallyManagedTool\\NuGet.Config",
          "X:\\Users\\me\\AppData\\Roaming\\NuGet\\NuGet.Config",
          "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
        ],
        "originalTargetFrameworks": [
          "net6.0"
        ],
        "sources": {
          "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
          "F:\\Packages": {},
          "https://api.nuget.org/v3/index.json": {},
          "https://pkgs.dev.azure.com/Faithlife/Packages/_packaging/main/nuget/v2": {}
        },
        "frameworks": {
          "net6.0": {
            "targetAlias": "net6.0",
            "projectReferences": {}
          }
        },
        "warningProperties": {
          "warnAsError": [
            "NU1605"
          ]
        }
      },
      "frameworks": {
        "net6.0": {
          "targetAlias": "net6.0",
          "dependencies": {
            "Faithlife.Build": {
              "target": "Package",
              "version": "[5.14.7, )",
              "versionCentrallyManaged": true
            },
            "NUnit.ConsoleRunner": {
              "target": "Package",
              "version": "[3.15.2, )",
              "versionCentrallyManaged": true
            }
          },
          "centralPackageVersions": {
            "Faithlife.Build": "[5.14.7, )",
            "NUnit.ConsoleRunner": "[3.15.2, )"
          },
          "imports": [
            "net461",
            "net462",
            "net47",
            "net471",
            "net472",
            "net48",
            "net481"
          ],
          "assetTargetFallback": true,
          "warn": true,
          "frameworkReferences": {
            "Microsoft.NETCore.App": {
              "privateAssets": "all"
            }
          },
          "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\6.0.402\\RuntimeIdentifierGraph.json"
        }
      }
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions