草庐IT

c# - 如何从命令行整合所有适用的项目和 nuget 包?

coder 2024-05-21 原文

我正在合并两个解决方案,现在有以下情况

这是一个大项目,合并一个包需要足够的时间。巩固 26,我会在这里一整天。有没有办法批量合并,这样我就可以去吃午饭,回来后就可以完成?

最佳答案

关于评论,我将在此处发布我的解决方案。它是一个更大工具的一部分,所以我会在这里发布关键类,将它连接在一起应该非常简单。 已安装的软件包(您可能会使用较新的版本):

"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 方法用于获取所选包的可用版本。用户可以选择他感兴趣的版本。完成后,他单击更新,更新 函数将使用用户选择的版本替换解决方案中所有 project.json 中的所有依赖项。

用户可以选择所有包的最新版本,而不是一个一个地选择版本,这很容易结合

GetSolutionDependencies + GetLatestVersion 每个包 + Update

基本上,结果是用最新版本的包更新的 project.json 列表。

您只需运行 nuget restore 或使用 VS 构建解决方案,后者将自动调用 restore。

关于c# - 如何从命令行整合所有适用的项目和 nuget 包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43065518/

有关c# - 如何从命令行整合所有适用的项目和 nuget 包?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐