注册
登录
新闻动态
其他科技
返回
Fork Freshness:Ruby 生态系统中的项目生命周期
作者:
糖果
发布时间:
2024-04-20 07:58:32 (2天前)
来源:
the-ruby-ecosystem/
我构建了一个名为Fork Freshness的应用程序。公平警告:这篇博文将包含对我的新应用的一些公然自我宣传。但是在构建该应用程序的过程中,我学到了一些关于开源项目如何随着时间发展的有趣事情。我一直特别关注 Ruby 项目。 什么是叉子新鲜度? 几年前,我需要将 UPS 运输选项恢复到名为 的 Ruby gem active_shipping,它非常适合计算运输成本。我想知道是否还有其他人恢复了这些相同的运输选项,因为 UPS 是如此受欢迎的供应商。最近,我创建了 Fork Freshness 来回答这个问题,我发现答案是肯定的。 这是 Fork Freshness 报告Shopify/active_shipping。它链接到所有项目最活跃和最近的下游分支。只需按照这些链接,您就可以学到很多东西。 Shopify 创建了active_shipping,然后他们放弃了它,但是在 Shopify 放弃该项目后,该项目的 34 个分支继续开发,并且这 34 个分支中的几乎每个分支都将 UPS 功能重新添加到 gem 中。 如果那时我有 Fork Freshness,我就不需要恢复其他人已经恢复的相同功能。我本可以查看现有的前叉并选择看起来最好的前叉。如果我修复了任何错误,这些错误修复就不会是我的雇主和我们的叉子独有的。我们使用的任何叉子也会受益。 这就是 Fork Freshness 的用途。 不管怎样,抛开自我推销不谈,为了创建这个项目,我必须学习用 Ruby 分析 git repos,并在 GitHub 上发现 Ruby 生态系统的一些实际情况。所以让我们谈谈它是如何工作的以及我学到的一些东西。为了减轻自我推销的因素,我将首先讨论野外的 Ruby gems。 我学到了什么 首先,我还不能肯定地说大多数废弃的 Ruby gems 都有仍然活跃的分叉。但我怀疑是这样。Fork Freshness 到目前为止已经分析了 5,762 个 git repos,但只有 23 个项目。但是,在这 23 个项目中,有 17 个的分叉比原始项目更活跃。这大约是 74%。并非所有这些都是 Ruby 项目,但大多数都是。 相对于 GitHub 上的代码总量,这是一个很小的样本量,我只分析了我希望有活跃下游分叉的项目,所以它不是随机抽样。但大多数时候,当我希望一个“死”的项目在下游真的还活着时,事实证明这是真的。 无论如何,具有活跃的下游分叉的项目通常只有两层深,就多少分叉也被分叉而言。通常人们只是分叉原始的,或者最多他们分叉另一个分叉,但他们通常不会得到比这更多的递归。 我说“通常”是因为这确实发生在一个名为RailRoad的项目中。这是一个不同寻常的项目。我发现铁路最深叉是一个原始项目的叉子叉的叉子叉的叉。有六层深。 但即使在那里,我也必须警告“原始项目”部分,因为原始项目的自述文件是这样说的: 我(Peter Hoeg)并不是要劫持 Javier 的项目,但由于他自 08 年 5 月以来没有发布任何新版本,我想我最好发布一个以便使铁路与 rails v2.3 一起工作。 这意味着早在 2009 年,当 RailRoad 的 git 历史开始时,真正的原始项目是一个叫 Javier 的人的另一个项目。其他项目甚至可能不在 GitHub 上。如果您在 00 年代后期发布开源,您就会知道 GitHub 还不是今天的默认设置。还有很多其他选择。所以真正的原始项目可能会被时间和/或 SourceForge 的迷雾所迷惑,但我们仍然可以说 README 中的这个注释意味着最深的分叉在技术上必须至少有七层深。所以它是原始项目的一个叉杆 在这一系列分叉的某个时刻,这个世系更名,从 RailRoad 改为 railroady。仅就上下文而言,RailRoad/railroady 是一个用于.dot使用 2.3 之前的某些版本的 Rails生成 GraphViz文件的项目。它至少在 13 年前就开始了。Fork Freshness 甚至还不能分析它——也许很快,如果我改变一些代码——因为当我开始使用 Fork Freshness 时,我不知道一个项目的 fork 树可能有这么多层次。 我认为 RailRoad/railroady 代表了可发现性和治理问题。README 担心劫持别人的项目,但今天我什至不知道那个项目是什么。这些分叉的存在可能是因为人们对项目应该如何进行存在分歧,而其他的可能是因为人们找不到已经完成的工作。Fork Freshness 只是想解决可发现性问题。 您可以通过考虑 来理解另一个可发现性问题ClosureTree/with_advisory_lock。这是一个异常值,因为大多数保留 Ruby gem 的人也继续定期使用这些 gem。在这种情况下,维护者会保持这个 gem 运行,但他也在GitHub 问题中表示他不再使用 Rails。(这是一个 Rails gem。)他在 2017 年说过。值得称赞的是,他仍在维护它,但可以合理地假设某些下游分支可能比原始分支更活跃,即使原始分支不是t 技术上放弃。 这个假设是正确的。我的 Fork Freshness 用户界面目前没有显示这一点,但在幕后,我可以在 Rails 控制台中看到,有 15 个人为下游分支添加了提交main或master分支,with_advisory_lock而从未将这些提交合并回上游。(我可能会在未来调整 UI 以显示这样的东西。)只有 15 人曾经为原始存储库做出过贡献,而且需要明确的是,下游贡献者的数量是原始 15 人之外的另外 15 人。这意味着与为官方原始项目做出贡献的人一样,许多人都在保持下游分叉的活力。 由于我正在尝试推广我的新应用程序,但我刚刚向您展示了两个不稳定的边缘情况,我想我应该向您展示一个更典型的情况,它会发光。您已经看到 Fork Freshness 如何揭示Shopify/active_shipping. 让我们看一个类似的 gem:sferik/twitter. sferik/twitter是推特的宝石。它自 2020 年 2 月以来一直没有更新,这并没有让该项目的发起人感到羞耻。第一次提交是在 2006 年 12 月 15 日。在 15 年过去之后继续你的生活并没有错。顺便说一下,Fork Freshness 在内部使用了这个 gem,尽管我现在可能会切换到另一个 fork。 创业板12个活跃叉,这是说12个叉具有提交的main或master那些比去年新提交上main或master原始项目。这些下游分支添加了对新端点的支持,更新了 OAuth 实现,并使 gem 与新版本的 Ruby 保持同步。如果我切换到这些分叉之一,那将是为了这些功能。 盲点 在这一点上,GitHub 有一个盲点可能很明显。如果您正在考虑使用在 GitHub 上找到的项目,您希望看到正在进行的开发,以便确信您不仅仅是在承担责任。但是一个项目必须对其发起者保持有用,才能使其持续的发展可见。如果一个项目不符合这个标准——这最终是一个非常随机的标准,并且可能不是故意选择的——那么其他随机程序员注定会一遍又一遍地将完全相同的 UPS 功能重新添加到完全相同的废弃 gem 中,彼此不知道彼此的努力,因为该项目太有用了,不能真正消亡,但在一种非常特殊的方式上还不够有用,这会导致 GitHub 认识到其继续存在。 这就是我们回到自我推销的地方,因为我创建了 Fork Freshness 来修复盲点。 例如,我最近使用 Fork Freshness 分析将我的一个 JavaScript 博客插件的 fork 称为elelty-plugin-svg-contents并使其成为最新的 fork。只有一个其他活跃的分叉,但也有大量针对原始存储库的 Dependabot PR,该项目的创建者忽略了这些。我从这些 PR 和另一个活跃的 fork 中挑选了提交到我的 fork 中。这是一项微不足道的努力,但让项目保持整洁和运作感觉很好。 这就是我希望人们对 Fork Freshness 所做的事情。需要明确的是,主要用例只是确定一个项目是否真的死了。如果您正在处理遗留代码,或者如果您发现一个有用但似乎已被放弃的项目,您想知道“死”是否真的意味着死。 但是想象一下你喜欢一个项目,而它的发起人放弃了它。这在 Node.js 世界中引起了很多戏剧性的事件,这让任何人都感到失望。如果你是让废弃项目保持活力的人之一,Fork Freshness 让你很容易找到所有其他做同样事情的人。也许在未来,所有 34 个active_shipping比原始项目更活跃的分叉都可以联合起来创建一个active_shipping每个人都可以使用的规范分叉。 “规范分叉”这个短语在 GitHub 心智模型中是一个矛盾,但它并不需要如此。GitHub 的创始人偏见并不是 git 可以支持的唯一心理模型。Git 是去中心化和分布式设计的。说最重要的分叉是社区仍在努力的分叉是非常合乎逻辑的。 我们应该如何可视化项目? GitHub 最近发布了一个项目,该项目探索了可视化代码库的新方法。很高兴看到这项工作发生,因为我认为它有点晚了。 我有一个宠物理论,即 GitHub,尽管有这个名字,但并没有真正将项目建模为中心。它将它们组织为列表。从最深层的意义上来说,这可能是也可能不是,但对于“洞察”选项卡来说,这是无可争议的。 在这个 UI 中,项目的原始 repo 也是该项目的规范示例,即使在发起者放弃项目之后,即使其他分支继续看到正在进行的开发。始发者保持在列表的顶部;所有其他叉子只是按字母顺序排列。 我认为 GitHub 在将项目中的所有 repos 组织为一个列表时犯了一个错误。这是用户界面的一个被忽视的角落。顾名思义,将原始版本视为具有许多辐条的中心,将使社交编码更容易。这与发起者无关;这是关于社区的。如果集线器的辐条比集线器本身更活跃,只需突出显示该辐条。 例如,这是一个力导向图,它表示使用适度的可视化实验的活动分叉,lardawge/carrierwave_backgrounder稍后可能会出现在分叉新鲜度上: 通过查看此图,您可以看到carrierwave_backgrounder比原始项目提前 3 次提交的 fork是从另一个已经提前 2 次提交的 fork 分叉的。但是大部分fork都是从原项目分叉出来的,也就是说原项目是这个git repos小集群中的枢纽。你几乎可以称它为 git hub。 我尚未将此代码应用于 RailRoad/railroady 系列项目(我在上面讨论过),但这可能是查看该组项目并了解您所看到的内容的唯一方法。与简单列表相比,这种用于理解同一代码库的不同变体之间关系的中心/辐射心智模型具有一些优势。它更清晰,更准确,它暴露了更多信息,而且它的名字是该死的。 无论哪种方式,都有我的肥皂盒。让我们谈谈 Fork Freshness 的工作原理。 工作原理:用户界面 Fork Freshness 是一个 Rails 应用程序,但它有一个只读网站。您不能使用 Fork Freshness 网站请求分析;你必须用你希望它分析的项目的 GitHub URL来推特@ForkFreshnessTwitter 帐户。 我这样做是出于三个原因。首先,我希望这个应用程序获得的所有数据都是公开的。这是一个分析开源项目的应用程序,所以它的分析应该与大家分享。 其次,每个 Rails 应用程序最终都有一个摩天大楼大小的 User 对象。这个反模式的官方名称是“God Object”,但如果你把它想象成哥斯拉对象,你会更清楚地理解这个问题。我已经厌倦了与这些该死的 kaiju 作斗争,我想看看我可以在没有任何 User 模型的情况下构建一个 Rails 应用程序能走多远。 当然,在实践中,AnalysisRequest 模型——本质上代表了一条传入的推文——几乎变成了哥斯拉对象。我现在的理论是,任何最接近 UI 的 ActiveRecord 模型都将变得庞大,因为它包含了一个全面的用户交互目录。这是一个有趣的问题,但它也是另一个话题。 我没有用户模型并将 Twitter 设为 UI 的第三个原因是 Fork Freshness 执行的分析不适合网站和应用程序的抽搐、近乎即时的 UI 节奏。相反,它非常适合异步通信的节奏。克隆超过一千个 repos 并分析它们各自的历史需要时间,而一个能够深入洞察重大决策的应用程序可能比一个仅仅满足一些愚蠢反射的应用程序花费更多的时间。反射是默认设置,甚至可能是大多数人甚至认可的唯一类别,但这是一种适得其反的默认设置。如果更多的应用程序围绕着深入的洞察力和异步通信,我们可能会发现全新的计算机有用工作类别。 Dependabot是异步运行的应用程序的一个完美示例,它可以完成更深入的工作,而不仅仅是满足无意义的反射。然而,就像技术中的任何事物一样,它也有权衡。 无论如何,由于 Twitter 聊天机器人是有效的 UI,Fork Freshness 有一个 Sidekiq 定期作业运行来检查 Twitter。它使用我在上面讨论过的 Twitter gem 来做到这一点。当您在 上发推时@ForkFreshness,它会检查您的推文是否有 GitHub URL。如果已经有分析,它只会发回该分析的链接,否则,它会告诉您即将进行分析,开始进行该分析,然后在完成后将链接发送给您。 工作原理:Git 分析 当 Fork Freshness 进行新的分析时,它会通过 GitHub 的 GraphQL API 获取要克隆的分叉列表。我不得不承认 Fork Freshness 通过查看此列表并克隆每个项目来工作。我更喜欢这部分的工作方式不同,尽管编写实际的 git 分析代码很有趣。 我试图根据 GitHub 的 GraphQL API 中的信息计算新鲜度。pushedAt在 API 的 Repository 对象上,一个有希望的选项似乎是。pushedAt告诉您最新推送的日期和时间,这似乎非常相关。但是,我发现,它pushedAt计算拉取请求中的提交以及实际合并到项目中的提交,并且 Dependabot 在这些项目被放弃后的几个月甚至几年内继续向其他休眠的项目提交拉取请求。这意味着休眠的项目仍然可以有最近的值pushedAt,但那些“最近提交”是随机公关分支,没有人关注过。所以 Fork Freshness 不使用pushedAt. 如果 Fork Freshness确实使用了pushedAt,它会快很多。active-forks是一个类似于 Fork Freshness 的应用程序。这是多快,可能是数量级,并且还拥有更小的代码库,绝对几个数量级。active-forks在 GitHub REST API 上运行。如果active-forks说一个 repo 在 X 日期进行了最后一次推送,则意味着 GitHub REST API 为其pushed_at属性返回了该日期。GitHub 的 REST 文档不如其 GraphQL 文档详细,但pushed_at似乎pushedAt与 GitHub GraphQL API 返回的内容相同。 显然,我更喜欢我自己的应用程序,因为 Dependabot 给pushed_at/增加了噪音pushedAt,并且来自人类的任何未合并的拉取请求也会产生pushed_at/pushedAt噪音。active-forks似乎也没有与 Fork Freshness 中的后续提交想法等效的概念。后续提交表示在原始存储库main或master分支上的最后一次提交之后发生了多少次提交。这是对持续发展的衡量,我认为这是一个有用的指标。但公平地说,使用 Fork Freshness 进行的更深入分析也较慢。如果您赶时间,您可能会从active-forks. 巨大的速度差异来自于active-forks从 GitHub REST API 获取最新信息并几乎立即呈现给您的事实。相比之下,Fork Freshness 从 GitHub GraphQL API 获取项目列表,克隆这些项目中的每一个,然后使用Rugged gem分析它们,这是一个围绕 libgit2 的薄包装。 Caution 也会使 Fork Freshness 变慢。有趣的是,从开发 Fork Freshness 的过程中多次克隆许多项目来看,在我看来 GitHub 可能对克隆有速率限制。这种看法可能只是由于我自己软件中的错误,尤其是在开发早期;但是,不能肯定地说。GitHub 清楚明确地记录了其 REST 和 GraphQL API 的速率限制,但我能找到的唯一官方信息表明克隆速率限制可能存在,并且可能随时更改。所以为了避免激怒GitHub,Fork Freshness缓慢而温和地克隆。 一旦克隆完成,使用 Rugged gem 分析 git 就非常容易了。Rugged/libgit2 认为通过遍历树来浏览提交历史,就像遍历树的 解析器一样。因此,您遍历提交树,忽略不在首选分支上的提交,并在执行过程中收集元数据。Fork Freshness 收集围绕这些问题组织的元数据:这个 repo 是否有在原始项目的 repo 上次提交之后发生的提交,如果有,有多少,何时发生? Fork Freshness 在整个分析过程中将原始 repo 保留在文件系统上,以进行比较,但在分析完每个 fork 并将其与原始 repo 进行比较后立即删除,最后删除原始 repo。对于给定项目的每个分支,Fork Freshness 捕获最近的提交日期,计算后续提交的数量——也就是说,自原始存储库变暗以来发生了多少新提交——然后,在其 UI 中,排序项目的活跃程度和/或最近的活动。 为了避免组合爆炸和更嘈杂的数据,该应用程序只查看名为main或 的分支master。这意味着如果你的 fork 有你在放弃原始项目后开发的有用主题分支,Fork Freshness 只会在你合并这些主题分支后才会注意到。而这意味着该叉新鲜度很可能低估了的人保持各种项目活仔数。如果你为你的公司制作了一个分叉,但你希望有一天,你会发现原版仍然存在,那么你可能不会承诺main. 进一步探索 我在这里只是触及了您可以了解的有关 GitHub 项目和/或 Ruby gems 的生命周期的皮毛。如果您想了解更多信息,GitHub GraphQL API和RubyGems API都非常有用。您还可以根据 Bundlerupdate和outdated命令检查给定的 Gemfile ,或者使用bundleupgem 获得更好的命令行界面。 如果你想自动化你自己的 git 分析,git gem是很好的开始,但你会想要Rugged gem性能开始变得重要的那一刻。谈到只触及皮毛,James Coglan 写了一本优秀的书,他指导您在 Ruby 中重新实现 git,尽管我必须承认我还没有读完它。(非常全面。) 如果你有兴趣使用这些工具来保持你的依赖项健康,Rust 生态系统有一个相关的项目,称为lib.rs/about它以不同的方式计算新鲜度: 版本不仅在低于最新版本时被视为过时,而且当该 crate 的一半以上用户使用较新版本时,都会被视为过时。 (Rust 中的 crate 相当于 Ruby 中的 gem。) Fork Freshness当然是一个新项目,但它已经分析了数千个git repos。最初的结果使它看起来非常非常有可能有很多“死”的项目,实际上它们在下游非常健康和活跃。开源在我的生活中为我做了很多伟大的事情,所以我希望 Fork Freshness 能够回馈开源开发者,通过减少他们需要恢复 UPS 功能的次数active_shipping,并减少整个类别一般重复。 感谢您阅读这篇关于项目生命周期的概述和我的新应用程序的介绍。为了表达我的谢意,请欣赏这张河马车的照片。但在任何情况下都不要尝试这样做
收藏
举报
1 条回复
动动手指,沙发就是你的了!
登录
后才能参与评论