简体   繁体   English

如何从命令行合并所有适用的项目和 nuget 包?

[英]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.这是一个大项目,整合一个 package 需要足够的时间。 Consolidating 26 and I'll be here all day.巩固 26,我会在这里一整天。 Is there a way to batch consolidate so I can go an have lunch and it will be done when I get back?有没有办法批量合并,这样我就可以 go 吃午饭,等我回来就可以完成?

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.基本上,应用程序使用NugetUpdater GetSolutionDependencies向用户显示解决方案中的所有依赖项。

Then GetVersions method is used to get available versions for the selected package.然后GetVersions方法用于获取所选包的可用版本。 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.用户可以选择他感兴趣的版本。当他完成时,他点击更新, Update功能将使用用户选择的版本替换解决方案中所有 project.jsons 中的所有依赖项。

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 .每个包的GetSolutionDependencies + GetLatestVersion + Update

Basically the result is a list of project.json's updated with the latest versions of packages.基本上,结果是使用最新版本的包更新的 project.json 列表。

All you have to do is either run nuget restore or build the solution with VS which will automatically call restore.您所要做的就是运行nuget restore或使用 VS 构建解决方案,该解决方案将自动调用 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".当您在VS中右键单击解决方案时,您可以select“管理解决方案的包NuGet”。 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.这将通过将它们全部更新到最新版本来有效地整合项目之间的所有包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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