Regarding the comments I'll post my solution here. It's a part of a bigger tool so I'll post key class here, it should be pretty straightforward to connect it together. Installed packages (you can probably use newer versions):
"NuGet.Core": "2.12.0-rtm-815",
"NuGet.Packaging": "3.5.0-beta2-1484",
"NuGet.ProjectManagement": "3.5.0-beta2-1484",
Source:
public class NugetSource
{
public string Name { get; set; }
public string Value { get; set; }
}
public class MyAppVersion
{
public double Id { get; set; }
public ObservableCollection<Dependency> Dependencies { get; set; }
public MyAppVersion()
{
Dependencies = new ObservableCollection<Dependency>();
}
}
public class Dependency : ReactiveObject
{
public Dependency()
{
AvailableVersions = new List<SemanticVersion>();
}
private SemanticVersion _version;
private string _name;
private List<SemanticVersion> _availableVersions;
[JsonProperty]
public string Name
{
get { return _name; }
set
{
_name = value;
this.RaiseAndSetIfChanged(ref _name, value);
}
}
[JsonProperty]
public SemanticVersion Version
{
get { return _version; }
set { this.RaiseAndSetIfChanged(ref _version, value); }
}
[JsonIgnore]
public List<SemanticVersion> AvailableVersions
{
get { return _availableVersions; }
set { this.RaiseAndSetIfChanged(ref _availableVersions, value); }
}
public override string ToString()
{
return $"Name: {Name}, Version: {Version}";
}
}
public class NugetUpdater : INugetUpdater
{
private readonly List<IPackageRepository> _supportedRepositories;
public NugetUpdater()
{
_supportedRepositories =
GetSources().Select(x => PackageRepositoryFactory.Default.CreateRepository(x.Value)).ToList();
}
public NugetSource[] GetSources()
{
var sources = new[]
{
new NugetSource() {Name = nameof(AppPaths.Dev), Value = AppPaths.Dev},
new NugetSource() {Name = nameof(AppPaths.Uat), Value = AppPaths.Uat},
new NugetSource() {Name = nameof(AppPaths.ThirdParty), Value = AppPaths.ThirdParty},
};
return sources;
}
public List<SemanticVersion> GetVersions(IEnumerable<string> feedUrls, string packageId)
{
var versions = new List<SemanticVersion>();
var repos = GetRepositories(feedUrls);
foreach (var currentRepo in repos)
{
var packages = currentRepo.FindPackagesById(packageId).ToList();
versions.AddRange(packages.Select(x => x.Version));
}
return versions;
}
public SemanticVersion GetLatestVersion(IEnumerable<string> feedUrls, string packageId)
{
var versions = GetVersions(feedUrls, packageId);
return versions.Any() ? versions.Max() : null;
}
public SemanticVersion GetLatestVersion(string feedUrl, string packageId)
{
return GetLatestVersion(new[] {feedUrl}, packageId);
}
public List<SemanticVersion> GetVersions(string feedUrl, string packageId)
{
return GetVersions(new[] {feedUrl}, packageId);
}
public List<Dependency> GetSolutionDependencies(string baseDir)
{
return Directory.EnumerateFiles(baseDir, "project.json", SearchOption.AllDirectories)
.Select(File.ReadAllText)
.Select(JObject.Parse)
.Select(GetDependencies)
.SelectMany(x => x)
.DistinctBy(x => x.Name)
.ToList();
}
private List<IPackageRepository> GetRepositories(IEnumerable<string> feedUrls)
{
return _supportedRepositories.Where(x => feedUrls.Contains(x.Source)).ToList();
}
public void Update(string baseDir, MyAppVersion version)
{
IEnumerable<string> jsonFiles =
Directory.EnumerateFiles(baseDir, "project.json", SearchOption.AllDirectories).ToList();
foreach (var projectJsonPath in jsonFiles)
{
var content = File.ReadAllText(projectJsonPath);
JObject json = JObject.Parse(content);
var projectDependencies = GetDependencies(json);
if (!projectDependencies.Any())
continue;
var projectDepNames = projectDependencies.Select(x => x.Name).ToList();
var toUpdateDependencies = version.Dependencies.Where(x => projectDepNames.Contains(x.Name)).ToList();
if (toUpdateDependencies.Count != projectDependencies.Count)
throw new Exception("Dependencies count is not equal. Something went wrong");
var dependenciesPairs = toUpdateDependencies.OrderBy(x => x.Name)
.Zip(projectDependencies.OrderBy(x => x.Name), (x, y) => new {ToUpdate = x, Project = y}).ToList();
bool anyChanged = false;
foreach (var dependencyPair in dependenciesPairs)
{
if (dependencyPair.Project.Version != dependencyPair.ToUpdate.Version)
{
anyChanged = true;
dependencyPair.Project.Version = dependencyPair.ToUpdate.Version;
}
}
if (anyChanged)
{
JObject obj = new JObject(projectDependencies.Select(x => new JProperty(x.Name, x.Version.ToNormalizedString())));
json["dependencies"] = obj;
File.WriteAllText(projectJsonPath, json.ToString(Formatting.Indented));
}
}
}
private static List<Dependency> GetDependencies(JObject json)
{
JObject dependenciesObject = (JObject) json["dependencies"];
var dependencies = dependenciesObject.Properties().Select(x => new Dependency
{
Name = x.Name,
Version = SemanticVersion.Parse(x.Value.Value<string>())
}).ToList();
return dependencies;
}
}
Basically application uses NugetUpdater
GetSolutionDependencies
to display to the user all dependencies in a solution.
Then GetVersions
method is used to get available versions for the selected package. User can select the version he is interested in. When he finishes he clicks update and Update
function will use user selected versions to replace all dependencies in all project.jsons in a solution.
Instead of selecting the versions one by one, user can select latest versions for all packages, it's pretty easy with combination of
GetSolutionDependencies
+ GetLatestVersion
for each single package + Update
.
Basically the result is a list of project.json's updated with the latest versions of packages.
All you have to do is either run nuget restore
or build the solution with VS which will automatically call restore.
There is no button for "Consolidate All" and I think there's a good reason why Microsoft hasn't added it, which I only just realized myself when dealing with this exact issue for the last few weeks.
There's no way for the system to automatically know how you want to consolidate the packages. Do you want to upgrade everything to the same version or downgrade some things?
If you just want to upgrade everything to the same version, there's an Upgrade all option, which makes perfect sense.
When you right click on the Solution in VS, you can select "Manage NuGet Packages for Solutions". On the Updates Tab, you can check the box for "Select All Packages" and then Update. This will effectively consolidate all your packages between the projects by updating them all to the latest version.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.