构建 CLI 功能通常可以归结为:
每一步都需要之前的一步,哎呀我们已经重新发明了瀑布项目管理。你会被痛苦所折磨,试图优雅地弥补错误,直到你一瘸一拐地恢复正常,但在出色之前就退出了。并且不要让我开始维护由此产生的临时“修复”和缺陷集群。
去过那里,做过那件事。我们知道我们需要超越瀑布式的方法。
以下是我们如何实现这一目标的故事,以及一路上提供帮助的一些工具。
我们想要廉价、快速的迭代,直到我们理解了该功能,然后才致力于昂贵的实施和长期支持。作为一个小团队,我经常从头到尾地执行这个过程,并希望依次关注每个部分。我们想要伪造实现部件,直到我们有足够的信心来实现它。
回到流程,首先是提出功能。我们想要摆脱抽象,但如果这意味着不成熟的实现,我们就不想这样做。受到 Github 此处描述的 Google Docs CLI 草图方法的启发,我们用“草图”伪造了它。
不幸的是,静态草图并没有给我们提供我们想要的反馈。我们的 CLI 随着时间的推移改变输出,更像是动画而不是绘图。为了实现更高的保真度,我编写了一些 Ruby 程序来获取基本输入并通过打印适当的预设响应来进行响应。
从那时起,我们找到了一种更好的方法来捕获动画 CLI 输出,但要解释这一点需要绕一些弯路。
当我们开始充实我们的 CLI 时,我们还想测试边缘情况并检测回归。我调查了基于 Cobra/bubbletea 的公共 CLI 来寻找想法,但令人沮丧的是,测试很少。然后我们偶然发现了 Charm 的 Teatest,这给了我们一个起点。
Teatest 专注于黄金测试,捕获已知的良好输出,然后断言未来的输出继续匹配它。这让我们再次回到了动画 CLI 输出的高保真捕获。 Teatest 为我们提供了基于框架的解决方案的好主意,例如翻页书,我们以此为基础:
─── SigninHeader ─────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` ─── SigninInput --────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` ? What is your username? ? user ─── SigninInput ──────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` * Signing in to your CLI account… ⠋ ─── SigninInput ──────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` * Signed in to your CLI account: user@example.com
这个简化的示例显示了基本授权命令的黄金输出可能是什么样子。水平线描绘框架,并带有指示活动模型的标签。总而言之,即使添加、删除或替换行,我们也能获得高保真度的输出捕获。
我们在测试套件中使用一个标志来更新具有黄金输出的文件,否则如果输出与文件不匹配,测试就会失败。这使我们能够了解输出的变化,并通过让我们了解输出应该是什么样子以及它是否发生变化来促进公关审查。我们非常喜欢它,因此计划将我们的草图程序替换为 Github 风格的谷歌文档中的黄金风格输出,这样我们就可以捕捉动画和风格创意。
有了我们曾经和未来的草图,让我们回到开始使用新的 API 端点。
我们同时致力于 API 和 CLI,因为这些的最佳设计源于紧密集成。我们能够做到这一点,同时仍然避免瀑布的危险,通过在更便宜的环境中迭代设计并等待直到需求固化为止。对于我们的 API,这意味着使用 OpenAPI 绘制草图:
openapi: 3.1.0 info: contact: email: contact@example.com description: An example API. title: Example API version: 0.0.1 servers: - url: https://api.example.com tags: - description: account operations name: account paths: '/v0/auth/signin': post: description: Signin to CLI. operationId: auth_signin responses: '200': content: 'application/json': schema: additionalProperties: false properties: email: description: Email address for authenticated user. example: username@example.com type: string required: - email type: object description: Successful signin. summary: Signin to CLI. tags: - account
这个简化的示例显示了基本授权命令的架构可能是什么样子。我们使用 Spectrum linter 来简化这些文件的处理。
有了草图,我们就可以在实现 CLI 时使用 prism 作为模拟 API 服务器。当我们不可避免地意识到犯了错误时,我们可以调整规范并返回到 CLI 迭代。在这种高水平上工作使我们能够一起发展 API 和 CLI,并推迟昂贵的实施,直到我们有更好的知识。
我们还依赖 OpenAPI 规范,以便在使用委员会的实施过程中保持诚实。 assert_schema_conform 测试对齐情况,中间件会通知我们任何实时差异。这些结合起来允许红绿实施,同时保护我们免受回归。
为了解决这个问题,我们的测试套件使用标志在模拟或代理模式下运行 prism。通过使用标志,我们可以专注于只编写一种测试,尽管这确实意味着我们在一种模式或另一种模式下跳过一些测试。我们在 Windows 和 macOS 上使用模拟测试来测试它们的速度,而我们的完整堆栈不在 CI 中运行。我们的代理测试让我们只需添加一个标志即可针对整个堆栈运行测试,从而在我们认为有必要时轻松运行端到端测试。
草图和规格帮助我们迭代抽象,而不必陷入实现的困境。然后模拟和代理帮助我们确保实现与草图相匹配。通过继续迭代我们的流程,每个功能都会减少痛苦,我们在构建本月晚些时候将提供的团队体验时对此深表赞赏。
我们将不断迭代我们的流程,我希望您从中学到一些东西,我也很乐意向您学习。你尝试过什么,哪些地方值得你骄傲,哪些地方仍然令人沮丧?
以上是开发 CLI的详细内容。更多信息请关注PHP中文网其他相关文章!