Datasette-ripgrep:用于您的源代码的正则表达式搜索引擎

2020-11-28 19:19:51

本周,我构建了datasette-ripgrep,这是一个基于源代码运行正则表达式搜索的Web应用程序,基于令人惊叹的ripgrep命令行工具构建。

该演示针对我的每个以数据集开头的GitHub存储库(目前为61个存储库)的源代码进行搜索,因此它应包括我的所有Datasette插件以及核心Datasette存储库本身。

由于它在ripgrep之上运行,因此支持正则表达式。这是非常有用的。一些例子:

我通常会在命令行上以rg的形式运行ripgrep,或者在Visual Studio Code中使用它(有趣的事实:VS Code的“查找文件”之所以如此出色,是因为它在后台运行ripgrep)。

那么为什么将其作为Web应用程序呢?因为这意味着我可以链接到它,将其添加为书签并在手机上使用。

已经有许多出色的现有代码搜索工具:我听说过关于livegrep的很棒的事情,而Google的快速搜索显示了很多其他选择。

除了是一个有趣的项目之外,datasette-ripgrep还具有一个关键优势:它可以从Datasette的发布机制中受益,这意味着它真的很容易部署。

通过将要搜索的源代码检出到all目录中,然后使用以下命令来部署ripgrep.datasette.io演示:

数据集发布cloudrun \ --metadata metadata.json \ --static all:all \ --install = datasette-ripgrep \ --servicedatasette-ripgrep \ --apt-get-install ripgrep

这里的所有都是它的!结果是在Google Cloud Run上运行了已部署的代码搜索引擎。

(如果您想自己尝试,则需要从GitHub安装Datasette,它使用的--apt-get-install命令是新命令,并且尚未发布。)

部署该演示的GitHub Action工作流还使用我的github-to-sqlite工具获取我的存储库,然后浅克隆以数据集开头的存储库。

如果您拥有自己的Google Cloud Run凭据,则可以针对自己的存储库运行该工作流程的副本。

Datasette是用于发布SQLite数据库的工具,因此大多数Datasette插件都以某种方式与SQLite集成。

datasette-ripgrep有所不同:它完全不使用SQLite,而是利用Datasette的URL路由,datasette发布部署和权限系统。

虽然该插件不使用SQLite,但确实与Datasette有着共同的理念:该插件将要搜索的源代码作为已部署的应用程序的一部分捆绑在一起,类似于Datasette通常捆绑一个或多个SQLite的方式数据库文件。

因此,它的运行成本极其低廉,可以部署到无服务器托管中。如果需要缩放,可以运行更多副本。

这确实意味着需要重新部署应用程序以获取对可搜索代码的更改。我可能会设置演示以每天执行一次。

实现过程中最棘手的部分是弄清楚如何使用Python的asyncio.create_subprocess_exec()方法来安全地运行rg进程以响应传入的请求。

我不希望使用昂贵的搜索来占用服务器,因此在此实施了两个限制。第一个是时间限制:默认情况下,搜索有第二个运行时间,此后将终止rg进程,并且仅返回到目前为止接收到的结果。这可以使用asyncio.wait_for()函数来实现。

我还对可返回的匹配行数实施了限制,默认为2,000。除此之外,该过程将尽早终止。

我本周的另一个项目是对til.simonwillison.net的升级:我终于花了一些时间为网站设计更好的URL。

为此,我利用了一个潜入Datasette 0.49:自定义页面模板的路径参数的功能。我可以创建一个名为pages / {topic} / {slug} .html的模板文件,然后Datasette使用该模板来处理与该模式匹配的404错误。

这是我的TIL网站的新页面/{topic}/{slug}.html模板。它使用来自datasette-template-sql插件的sql()模板函数来检索和呈现匹配的TIL,如果找不到TIL,则加4040。

我还需要设置从旧页面到新页面的重定向。我在Datasette的edirects上写了一篇TIL,解释了我是如何做到的。