Как консолидировать все применимые проекты и пакеты nuget из командной строки?

Я объединяю два решения и теперь имею следующую ситуацию.

введите описание изображения здесь

введите описание изображения здесь

Это большой проект, и объединение одного пакета занимает достаточно времени. Консолидация 26, и я буду здесь весь день. Есть ли способ консолидировать пакет, чтобы я мог пообедать, и это будет сделано, когда я вернусь?

Ответ 1

Что касается комментариев, я выложу свое решение здесь. Это часть более крупного инструмента, поэтому я опубликую здесь ключевой класс, соединить его будет довольно просто. Установленные пакеты (возможно, вы можете использовать более новые версии):

"NuGet.Core": "2.12.0-rtm-815",
"NuGet.Packaging": "3.5.0-beta2-1484",
"NuGet.ProjectManagement": "3.5.0-beta2-1484",

Источник:

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;
    }
}

В основном приложение использует NugetUpdater GetSolutionDependencies для отображения пользователю всех зависимостей в решении.

Затем метод GetVersions используется для получения доступных версий для выбранного пакета. Пользователь может выбрать интересующую его версию. Когда он заканчивает, он нажимает кнопку "Обновить", и функция " Update будет использовать выбранные пользователем версии для замены всех зависимостей во всех файлах project.json в решении.

Вместо того, чтобы выбирать версии одну за другой, пользователь может выбрать последние версии для всех пакетов, это довольно легко с помощью комбинации

GetSolutionDependencies + GetLatestVersion для каждого отдельного пакета + Update.

В результате получается список project.json, обновленный последними версиями пакетов.

Все, что вам нужно сделать, это запустить nuget restore или создать решение с VS, которое автоматически вызовет restore.