贡献
如果您计划投入大量精力进行一个大的拉取请求,其中涉及多个可能影响 Ruby LSP 长期维护的决策,请先开启一个讨论,以统一方向。
ruby-lsp 存储库包含三个子项目
- 语言服务器 (
ruby-lsp
),位于存储库的顶层。大多数功能都在这里实现,因为服务器中实现的所有内容都可用于所有编辑器 - VS Code 扩展,位于
vscode
目录下。任何自定义的 VS Code 功能都在这里实现 - 文档网站,位于
jekyll
目录下。Ruby LSP 和 Rails 附加组件的所有面向用户的文档都包含在此处
本贡献指南按每个组件进行划分。
初始化设置
要开始为 Ruby LSP 做贡献,请确保已按如下方式安装所有依赖项
- 顶层的
bundle install
将安装 Ruby 依赖项 jekyll
目录中的bundle install
将安装文档依赖项vscode
目录中的yarn install
将为 VS Code 扩展安装 Node.js 依赖项
为服务器做贡献
这是 ruby-lsp
gem 的结构
lib/ruby_indexer
:代码索引器,用于从工作区提取声明lib/ruby_lsp/*.rb
:语言服务器的基础部分,例如工作线程、队列、处理请求等lib/ruby_lsp/requests
:请求实现。这些与 语言服务器规范 一一对应lib/ruby_lsp/listeners
:Prism 调度器监听器。服务器的大部分基础设施依赖于监听器模式,以在遍历 AST 时最大限度地提高性能。请注意,单个请求可能依赖于多个监听器
在添加或更改现有功能时,首先在规范中确定哪个请求负责该功能。然后确定服务器中哪个文件实现了该请求,并开始考虑实现。
使用 VS Code 时,打开 lsp.code-workspace
文件,而不是只打开常规文件夹。它包含用于有效并排使用子项目的配置
调试
实时调试服务器
在使用 VS Code 时,可以实时调试当前正在运行的语言服务器的开发实例
CMD/CTRL + SHIFT + P
打开命令面板- 搜索
调试 Ruby LSP 服务器
。此命令将以调试模式重启服务器,允许您连接调试器。请注意,调试模式仅在编辑器关闭或 Ruby LSP 重启之前有效 - 服务器以调试模式启动后,通过转到
运行和调试
,选择附加到现有服务器
任务并单击运行来附加调试器 - 现在您应该能够在 UI 中设置断点,触发请求将在这些断点处停止
注意:由于您正在调试当前在您自己的编辑器中运行的语言服务器实例,如果执行当前在断点处暂停,则功能将不可用。
理解 Prism AST
Ruby LSP 使用 Prism 来解析和理解 Ruby 代码。在处理某个功能时,通常需要检查给定代码片段的 Prism AST 结构,以便您可以了解为什么以某种方式触发请求。
如果您正在使用 VS Code,则可以使用 显示语法树命令 来检查整个文档或选择的 AST 结构。
对于其他编辑器,使用我们的 IRB 配置是实现相同目的的最简单方法
bundle exec irb
使用我们的配置启动 IRB。它将为您要求所有库- 然后解析您想更好理解的 Ruby 代码并开始检查
source = <<~RUBY
class Foo
def bar
end
end
RUBY
ast = Prism.parse(source).value
查看 Prism 文档以获取更多相关信息。
追踪 LSP 请求和响应
在 VS Code 中,您可以通过启用追踪来验证服务器中发生的情况,这允许不同级别的日志记录。
{
// Your JSON settings
//
// - `off`: no tracing
// - `messages`: display requests and responses notifications
// - `verbose`: display each request and response as JSON
"ruby lsp.trace.server": "messages"
}
手动测试更改
在您进行更改或添加新功能后,您可以通过重启语言服务器在编辑器中进行验证。在 VS Code 中,可以通过运行命令 Ruby LSP: restart
来实现,这将重启服务器并拾取您的更改。
对于其他编辑器,您必须手动重启语言服务器才能拾取最新更改。
调试测试
在 VS Code 中,我们建议
- 在 UI 中设置断点
- 打开将命中该断点的测试
- 单击示例顶部的
debug
代码镜头按钮
或者(对于其他编辑器),在代码中添加 binding.b
语句并在终端中执行测试,这也允许您调试代码。
编写测试
Ruby LSP 中有两种类型的测试。第一种类型可能很熟悉:标准的 Minitest 文件,其中包含一堆使用方法声明语法的示例。
第二种类型的测试是我们的夹具/期望框架。在 test/fixtures
下添加新的夹具将自动使框架对该夹具运行所有请求。默认情况下,框架仅检查在对夹具运行时功能是否崩溃。这对于确保在使用不太常见的 Ruby 语法时,关键请求不会中断很有用。
要超越检查请求是否会因夹具而中断,您可以在 test/expectations/NAME_OF_THE_REQUEST
中添加一个期望,这允许您断言请求和夹具组合的预期响应。
例如,如果我们有一个 test/fixtures/foo.rb
,那么添加一个 test/expectations/semantic_highlighting/foo.exp.json
将使框架验证在 foo.rb
夹具中运行语义高亮时,期望的响应是 foo.exp.json
。
查看现有夹具和期望组合的示例。
何时使用每种类型的测试
夹具/期望框架主要用于完整文档请求(每次都为整个文件计算的语言服务器功能)。
特定于位置或在不同机制下运行的请求和功能应仅使用常规 Minitest 测试。
运行测试套件
有多种可用的执行测试的方法。
# Run the entire test suite
bundle exec rake
# Run only indexing tests
bundle exec rake test:indexer
# Run only language server tests (excluding indexing)
bundle exec rake test
# Using the custom test framework to run a specific fixture example
# bin/test test/requests/the_request_you_want_to_run_test.rb name_of_fixture
bin/test test/requests/diagnostics_expectations_test.rb def_bad_formatting
此外,我们使用 RuboCop 进行 linting,并使用 Sorbet 进行类型检查。
# Run linting
bundle exec rubocop
# Run type checking
bundle exec srb tc
为 VS Code 扩展做贡献
在本节开始之前,请确保已安装依赖项。
除了此处描述的内容之外,VS Code 扩展 API 文档也是一个很好的地方,可以收集有关扩展如何与编辑器交互的更多上下文。
VS Code 扩展当前具有以下主要部分
- 用于 Ruby 环境激活的版本管理器集成
- ruby/debug 客户端实现
- 测试控制器实现
- Copilot 聊天参与者
- 依赖关系树实现
- LSP 客户端
- 工作区抽象,用于表示编辑器中的每个活动工作区
测试更改
打开 lsp.code-workspace
文件,而不是只打开常规文件夹。它包含使用如下所述的“运行和调试”所需的配置。
我们尽量确保尽可能彻底的测试。但是,有些测试很难编写,特别是那些与 VS Code 小部件交互的测试。
例如,如果运行测试显示一个对话框,则测试没有简单的方法来单击其上的按钮以继续执行。对于这些情况,我们使用 sinon
来存根预期的调用和响应。
注意:client.test.ts
是一个集成风格的测试,它启动 ruby-lsp
gem 的开发版本并针对它运行请求。
运行测试
运行测试最简单的方法是在 运行和调试
中选择 扩展测试
任务,然后点击运行。这将运行所有测试,结果将显示在 VS Code 的调试控制台中。
或者,您也可以通过终端运行测试,这将在存储库内下载一个测试 VS Code 版本,并针对该版本运行测试。您可以通过运行启动任务来避免下载。
注意:无法运行单个测试文件或示例。
实时调试
可以对扩展的开发版本进行实时调试。详细信息可以在 VS Code 扩展文档 中找到,但本节包含一个简短的描述。
实时调试涉及两个 VS Code 窗口。第一个窗口是您将修改代码的地方,第二个窗口是扩展的开发版本将运行的地方。您需要在第一个窗口中更改代码,重新加载并在第二个窗口中验证更改。
- 首先,在
运行和调试
面板中使用运行扩展
任务启动扩展调试。这将打开第二个 VS Code 窗口,其中运行着扩展的开发版本。 - 在第一个原始 VS Code 窗口中进行所需的更改
- 单击 调试工具栏 中的重新加载按钮,将您最近的更改加载到第二个 VS Code 窗口中
- 在第二个窗口中执行操作以验证您的更改
如果您希望执行单步调试,您只需在第一个窗口(您正在修改代码的窗口)的 UI 中添加断点,而不是在第二个窗口(扩展的开发版本正在运行的窗口)中添加断点。
贡献文档
Ruby LSP 使用 Jekyll 来生成文档,其源代码位于 /jekyll
文件夹下。在进行任何更改之前,请确保您已 执行了初始设置。
之后,按照以下步骤进行并验证您的更改
- 进行所需的更改
- 在开发中启动 Jekyll
bundle exec jekyll serve
- 通过访问 https://127.0.0.1:4000/ruby-lsp 在本地验证您的更改
贡献 Ruby LSP Rails 附加组件
请参阅 https://github.com/Shopify/ruby-lsp-rails/blob/main/CONTRIBUTING.md