简体   繁体   中英

How to consolidate all applicable projects and nuget packages from the command line?

I'm merging two solutions and now have the following situation

在此处输入图像描述

在此处输入图像描述

It is a large project and consolidating a single package takes enough time. Consolidating 26 and I'll be here all day. Is there a way to batch consolidate so I can go an have lunch and it will be done when I get back?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM