As part of a CI process we needed to regularly check for outdated packages for a dotnet solution. This particular solution used Central Package Management.
Before reading ahead, there is a global tool dotnet-outdated that does all this so before writing your own code consider using that.
We didn’t for this solution as we already have a fairly comprehensive set of rake-based commands for dev infrastructure and wanted to be self-contained without requiring additional commands to be installed.
Given this was rake (ruby make), the following code is in ruby:
def self.outdated_packages(sln_or_proj_path, only_minor = false)
dir = File.dirname(sln_or_proj_path)
json = `dotnet list #{sln_or_proj_path} package --outdated #{only_minor ? "--highest-minor" : ""} --format json`
data = JSON.parse(json)
transformed = {
packages: [
]
}
data["projects"].each do |project|
unless project["frameworks"].nil?
project["frameworks"].each do |framework|
framework["topLevelPackages"].each do |package|
transformed_package = transformed[:packages].find {|p| p[:id] == package["id"] && p[:current] == package["resolvedVersion"]}
if transformed_package.nil?
transformed[:packages] << {
"id": package["id"],
"current": package["resolvedVersion"],
"latest": package["latestVersion"],
"projects": [
project["path"]
]
}
else
transformed_package[:projects] << project["path"]
end
end
end
end
end
if transformed[:packages].empty?
puts "All packages up-to-date"
else
sorted = transformed[:packages].sort_by { |p| p[:id] }
sorted.each do |package|
printf "%-30s %-15s %-15s\n", package[:id], package[:current], package[:latest]
sorted_projects = package[:projects].sort
sorted_projects.each do |project|
puts "\t#{project.sub(dir, ".")}"
end
end
end
end
The output will look something like:
Microsoft.NET.Test.Sdk 17.8.0 17.9.0
/proj1/tests/IcCloud.Account.Tests.csproj
/proj2/tests/IcCloud.Common.Tests.csproj
/proj3/tests/IcCloud.Financials.Tests.csproj
/proj4/tests/IcCloud.Inventory.Tests.csproj
Quartz.Extensions.Hosting 3.6.3 3.8.0
/app/serviceapp.csproj
Of course you might want to get the result into machine readable format so you could act on any outdated packages (e.g. automate issuing a pull request to update to version xyz).
But for now that is left as an exercise for the reader.