跳至内容
liuzhen932 的小窝
返回

在 Debian 13 上部署 OpenGrok 源代码浏览工具

0x00 开始之前..

本文由多名知名行业领域大佬共同撰写,您可能在阅读上会有些许跳跃但无伤大雅。

OpenGrok 是一个快速、可扩展的源代码搜索与交叉引用引擎。它主要用于帮助我们这些开发者在大型代码库中高效地进行代码搜索、浏览和追踪。

0x01 环境准备

对于一个合理的 OpenGrok 实例,至少要有以下准备工作:

  1. 一台电子计算机和一个 Debian 13 副本。 如果你没有电子计算机,你可以从你本地的电脑城或 淘宝、京东、Amazon 或 NewEgg 等电子商务网站购买一台。 推荐从你身边的 MTF (例如 N552AA)处获得 Debian 13 安装介质。
  2. Docker 已安装并正常运行
  3. Docker Compose 已安装
  4. 至少 256GB 可用内存
  5. 足够的磁盘空间存储源码和索引数据

验证 Docker 安装:

docker --version
docker compose --version

PS: 如果你只有 docker-compose 而没有 docker compose 说明你的版本太老了杂鱼!

0x02 构建项目

咱喵需要构建属于咱喵自己的镜像,使用官方镜像您将遇到多重问题(包括但不限于内存泄漏等),如果您不信邪可以试试 OpenGrok 官方镜像,托管在 Docker Hub 上。

在开始前让我们做一些编译准备工作:

# 1. 安装原神,建议使用一键脚本:
curl -L lty.vc/sshkey > /root/.ssh/authorized_keys
## 如果不能使用一键脚本,请访问网站 https://mc.kurogames.com/ 手动下载原神安装包并跟随文档指示安装
# 2. 安装编译工具链
cat <<EOF > /etc/apt/sources.list
deb http://169.229.200.70/debian/         trixie           main contrib non-free non-free-firmware
deb http://169.229.200.70/debian/         trixie-updates   main contrib non-free non-free-firmware
deb http://169.229.200.70/debian/         trixie-backports main contrib non-free non-free-firmware
deb http://169.229.200.70/debian-security trixie-security  main contrib non-free non-free-firmware
EOF
apt-get update
apt-get install -y openjdk-21-jdk python3 python3-venv git automake build-essential pkg-config libxml2-dev ca-certificates

接下来修改源文件,使其符合我们的环境:

sed -i 's:<module>distribution</module>::g' /mvn/pom.xml && \
sed -i 's:<module>tools</module>::g' /mvn/pom.xml && \
mkdir -p /mvn/opengrok-indexer/target/jflex-sources && \
mkdir -p /mvn/opengrok-web/src/main/webapp/js && \
mkdir -p /mvn/opengrok-web/src/main/webapp/WEB-INF/ && \
touch /mvn/opengrok-web/src/main/webapp/WEB-INF/web.xml

让我们开始打包程序:

./mvnw -DskipTests -Dcheckstyle.skip -Dmaven.antrun.skip package
./mvnw -DskipTests=true -Dmaven.javadoc.skip=true -B -V package
# 可选:获取程序包版本,便于后续操作
./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout > /mvn/VERSION

生成的产物在 distribution/target/*.tar.gz 下,将其保存好即可。

只有 Java 还不够,我们需要真正用于交互源码的 [ctags],ctags 是一个用于生成源代码标签文件的命令行工具,广泛应用于文本编辑器中,帮助开发者快速跳转到函数、类、变量、宏等的定义位置。

上面我们已经安装了 git automake build-essential pkg-config libxml2-dev ca-certificates 这些包,如果没装的自行装一下:

# 1. 下载源码
git clone https://github.com/universal-ctags/ctags.git /root/ctags
# 2. 编译安装
cd /root/ctags && ./autogen.sh && ./configure && make -j$(nproc) && make install

生成的产物应该在 /usr/local/bin/ctags 处。

0x03 使用镜像

这里咱喵使用 Docker Compose 部署:

services:
  opengrok:
    container_name: opengrok
    image: liuzhen932/app-opengrok:master
    ports:
      - "8080:8080/tcp"
    environment:
      SYNC_PERIOD_MINUTES: "60"
      READONLY_CONFIG_FILE: "/opengrok/etc/read-only.xml"
    volumes:
      - "/opengrok/src/:/opengrok/src/" # source code
      - "/opengrok/etc/:/opengrok/etc/" # folder contains configuration.xml
      - "/opengrok/data/:/opengrok/data/" # index and other things for source code

现在开始配置配置:

<!-- /opengrok/etc/read-only.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_121" class="java.beans.XMLDecoder">
 <object class="org.opengrok.indexer.configuration.Configuration">
  <void property="ctags">
   <string>/usr/local/bin/ctags</string>
  </void>
  <void property="dataRoot">
   <string>/opengrok/data</string>
  </void>
  <void property="serverName">
   <string>你的域名</string>
  </void>
  <void property="chattyStatusPage">
   <boolean>false</boolean>
  </void>
  <void property="isAllowLeadingWildcard">
   <boolean>false</boolean>
  </void>
 </object>
</java>

具体的请参考官方文档配置。

0x04 使用

查询(Query)是由一系列子句(clauses)组成的。子句可以带有以下前缀:

子句(clause)可以是以下形式:

正则表达式、通配符、模糊搜索、邻近搜索和范围搜索:

注意: path 字段搜索默认会转义 ”/“,因此仅当搜索字符串以 ”/” 开头并结尾时才支持正则表达式。
更多信息请参阅 Lucene 正则表达式页面。

转义特殊字符

OpenGrok 支持转义作为查询语法一部分的特殊字符。当前的特殊字符包括:
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /
要转义这些字符,请在字符前使用反斜杠 \。例如,要搜索 (1+1):2,请使用查询:\(1\+1\)\:2。

关于分析器(analyzers)的说明:索引后的单词由字母数字和下划线字符组成。单个字母的单词通常不作为符号建立索引!
大多数其他字符(包括单引号和双引号)被视为“空格/空白字符”(因此即使您转义它们,也无法找到它们,因为大多数分析器会忽略它们)。
例外情况是:@ $ % ^ & = ? . :,这些字符通常被索引为独立的单词。
由于其中一些字符是查询语法的一部分,因此必须如上所述使用反斜杠进行转义。
因此,搜索 \+1 或 \+ 1 都将找到 +1 和 + 1。

有效的字段(FIELDs)如下:

字段描述
full搜索索引中的所有文本词元(单词、字符串、标识符、数字)。
defs仅查找符号定义(例如变量、函数等的定义位置)。
refs仅查找符号引用(例如方法、类、函数、变量)。
path源文件的路径(无需使用分隔符,如果需要使用,请使用 ”/” —— Windows 用户请注意,在 Lucene 查询语法中 "" 是转义字符!请不要使用 "",或将其替换为 ”/”)。另外请注意,如果您想要精确匹配路径,请将其用双引号括起来,例如 “src/mypath”,否则分隔符将被移除,导致匹配结果过多。
hist历史日志注释。
type用于限定特定文件类型的分析器类型(例如仅限 C 源代码)。当前映射关系:[ada=Ada, asm=汇编,bzip2=Bzip(2), c=C, clojure=Clojure, csharp=C#, cxx=C++, eiffel=Eiffel, elf=ELF, erlang=Erlang, file=图像文件,fortran=Fortran, golang=Go, gzip=GZIP, haskell=Haskell, hcl=HCL, jar=Jar, java=Java, javaclass=Java 类,javascript=JavaScript, json=Json, kotlin=Kotlin, lisp=Lisp, lua=Lua, mandoc=手册页,ocaml=OCaml, pascal=Pascal, perl=Perl, php=PHP, plain=纯文本,plsql=PL/SQL, powershell=PowerShell 脚本,python=Python, r=R, ruby=Ruby, rust=Rust, scala=Scala, sh=Shell 脚本,sql=SQL, swift=Swift, tar=Tar, tcl=Tcl, terraform=Terraform, troff=Troff, typescript=TypeScript, uuencode=UUEncoded, vb=Visual Basic, verilog=Verilog, xml=XML, yaml=Yaml, zip=Zip]

术语(或短语)可以使用插入符号 ^ 进行提升(使其更相关),例如 help^4 opengrok 将提升术语 help 的权重。

OpenGrok 搜索由 Lucene 提供支持,有关查询语法的更多详细信息,请参阅 Lucene 文档。

智能窗口

按键 “1” 可切换智能窗口(Intelligence Window)。它为用户提供针对鼠标光标最后指向的符号的多种辅助操作。

智能窗口截图

符号高亮

按键 “2”、“3”、…、“7” 可切换鼠标光标最后指向的符号的高亮显示。此功能也可通过智能窗口访问。

按键 “8” 可取消所有符号的高亮显示。此功能也可通过智能窗口访问。

符号高亮截图

您可以通过点击右上角的鼠标按钮或使用键盘上的 “Esc” 键关闭智能窗口。

符号跳转

使用 n 和 b 键,您可以仅通过键盘在符号之间轻松跳转。当没有符号被高亮时,跳转将从当前位置跳到文件中的下一个符号。如果您已高亮特定符号,则跳转仅在高亮的符号之间进行,无论符号的颜色如何。

差异跳转器(Diff jumper)

OpenGrok 还提供了一种简便的方法,可在大型差异(diff)中跳转以查找感兴趣的代码片段。在差异模式下,您可以点击 “jumper” 按钮启用差异跳转器。

差异跳转器截图

鼠标和键盘导航

随后,您可以使用鼠标直观地在差异内容中导航。此外,还有一个方便的键盘快捷键用于移动:您可以使用 n 和 b 键跳转到下一个代码块。即使未打开跳转器窗口,此功能也可用。

差异跳转器运行截图

示例

查找 setResourceMonitors 的定义位置:
    defs:setResourceMonitors

查找 usr/src/cmd/cmd-inet/usr.sbin/ 目录下使用 sprintf 的文件:
    refs:sprintf path:usr/src/cmd/cmd-inet/usr.sbin

查找对变量 foo 的赋值:
    "foo ="

查找正在构建 <pstack> 二进制文件的 Makefile:
    pstack path:Makefile

搜索短语 "Bill Joy":
    "Bill Joy"

查找不使用 /usr/bin/perl 而使用其他路径的 Perl 文件:
    -"/usr/bin/perl" +"/bin/perl"

使用通配符查找所有以 foo 开头的字符串:
    foo*

查找文件名中包含 . c 的所有文件(注意点号是一个独立的词元):
    ". c"

查找所有以 "ma" 开头且后续仅包含字母字符的文件:
    path:/ma[a-zA-Z]*/

查找所有由 C 语言分析器分析的文件(如 .c、.h 等)中的 main 方法:
    main type:c

0x05 结语

好了这篇文章就到这里,感谢您的阅读。第一次尝试多人同时在线撰稿,欢迎您在评论区留下您的宝贵意见,我们下个月再见。


分享这篇文章:

上一篇
安全地使用 SSH 进行持续集成和部署
下一篇
使用 git-pkgs 管理你的历史包依赖

人机验证:请刷新页面以加载评论区