当前位置: 首页 > news >正文

[code-review] 文件过滤逻辑 | 范围管理器

第5章:文件过滤逻辑(范围管理器)

欢迎回来

在第4章:AI聊天接口(语言模型通信器)中,我们探索了机器人如何与ChatGPT等强大的AI模型智能通信

它知道如何提出正确的问题并理解答案by json)。

但想象一下,我们正在审查一个庞大的编码项目

一个拉取请求可能涉及数百个文件,从核心应用程序逻辑到临时构建文件、图像资源,甚至是来自外部库(如node_modules)的文件。

我们真的想把所有这些都发送给AI审查吗?可能不需要

这就是文件过滤逻辑(范围管理器)发挥作用的地方

负责智能决定拉取请求中哪些文件应该实际发送给AI审查的组件。它就像一个高效的独家俱乐部保镖,确保只有相关且可管理的代码变更能够进入AI审查环节。

它解决了什么问题?

ChatGPT-CodeReview机器人在决定审查哪些文件时面临两个主要挑战:

  1. AI成本和性能:向AI发送过多代码会增加成本并延长处理时间。AI模型还有"令牌限制",意味着它们一次只能处理一定量的文本。发送不相关或非常大的文件可能会触及这些限制,导致审查失败或不完整。
  2. 相关性:并非所有文件对代码审查都同等重要。我们可能不需要AI对以下内容的反馈:
    • 配置文件(如.envpackage-lock.json)。
    • 生成的代码(如dist文件夹中的编译JavaScript)。
    • 大型第三方库(node_modules)。
    • 文档或图像文件。

范围管理器通过提供清晰的规则来解决这些问题,规定包含什么、忽略什么以及哪些内容对AI来说太大而无法高效处理。它确保AI将其宝贵的注意力(和我们的预算)集中在真正重要的代码上

范围管理器的规则(保镖的检查清单)

我们机器人的保镖(范围管理器)有几个关键规则来决定哪些文件可以进入:

(类似于bot的.ignore)

  1. 直接忽略列表(IGNORE:“这些特定文件永远不允许进入。”
  2. 忽略模式(IGNORE_PATTERNS:“任何匹配这些常见模式的文件不允许进入。”
  3. 包含模式(INCLUDE_PATTERNS:“只有匹配这些模式的文件允许进入。其他所有文件都排除在外!”(此规则优先级最高)。
  4. 最大变更大小(MAX_PATCH_LENGTH:“即使文件被允许,如果其变更太大,AI无法一次性处理,则跳过它。”

让我们看看如何在.github/workflows/cr.yml文件中配置这些规则。

配置范围管理器(设置保镖的规则)

我们使用GitHub Actions工作流中的环境变量来配置范围管理器,就像在第1章:GitHub Actions运行器(工作流集成)中看到的那样

以下是设置这些规则的示例

# 文件: .github/workflows/cr.yml (片段)- uses: anc95/ChatGPT-CodeReview@mainenv:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}# ... 其他设置 ...# 规则1: 要忽略的特定文件IGNORE: |package-lock.jsonyarn.lock.env# 规则2: 要忽略的文件模式(逗号分隔)IGNORE_PATTERNS: "*.md, .github/**, public/*, dist/**, *.test.js"# 规则3: *仅*包含匹配这些模式的文件(逗号分隔)# 如果设置,IGNORE和IGNORE_PATTERNS将被忽略!INCLUDE_PATTERNS: "src/**/*.js, src/**/*.ts, scripts/**"# 规则4: 每个文件的变更最大大小(字符数)MAX_PATCH_LENGTH: 1000 # 示例:仅审查最多1000个字符的变更

让我们分解每条规则:

1. IGNORE:要排除的特定文件

此变量是一个以换行符分隔的精确文件名列表。如果文件的名称匹配此列表中的任何条目,它将被立即过滤掉。

示例

          IGNORE: |package-lock.jsonyarn.lock.env

结果:如果拉取请求更改了package-lock.jsonyarn.lock.env,机器人将直接忽略这些变更,不会将它们发送给AI。

2. IGNORE_PATTERNS:要排除的文件模式

此变量是一个以逗号分隔的"glob模式"列表。Glob模式类似于通配符(*匹配任何内容,**匹配任何目录)。任何匹配任何这些模式的文件将被排除。

示例

          IGNORE_PATTERNS: "*.md, .github/**, public/*, dist/**, *.test.js"

结果

  • *.md:忽略所有Markdown文件(例如README.mdCONTRIBUTING.md)。
  • .github/**:忽略.github目录中的任何内容(例如工作流文件、问题模板)。
  • public/*:忽略public文件夹中的直接文件(例如public/index.html)。
  • dist/**:忽略dist目录或其子目录中的任何内容(常见于编译代码)。
  • *.test.js:忽略JavaScript测试文件。

3. INCLUDE_PATTERNS包含匹配这些模式的文件

这是最强大的过滤规则。如果设置了INCLUDE_PATTERNS,机器人将考虑匹配至少一个这些模式的文件。所有其他文件,无论IGNOREIGNORE_PATTERNS如何,都将被排除。这相当于一个"允许列表"。

示例

          INCLUDE_PATTERNS: "src/**/*.js, src/**/*.ts, scripts/**"

结果

  • src/**/*.js:仅包含src文件夹中的任何位置的JavaScript文件。
  • src/**/*.ts:仅包含src文件夹中的任何位置的TypeScript文件。
  • scripts/**:仅包含scripts文件夹中的任何位置的文件。
  • 重要:如果还有README.mdpublic/index.html的变更,它们将被忽略,因为它们不匹配任何INCLUDE_PATTERNS

4. MAX_PATCH_LENGTH:限制变更大小

即使文件通过了IGNOREINCLUDE_PATTERNS规则的检查,其变更的总大小(“补丁"或"差异”)可能对AI来说太大而无法有效处理。此变量设置单个文件补丁的字符限制。

示例

          MAX_PATCH_LENGTH: 1000 # 仅审查最多1000个字符的变更

结果:如果文件src/big-feature.js有2000个字符的变更,而MAX_PATCH_LENGTH为1000,机器人将跳过审查此文件,即使它匹配INCLUDE_PATTERNS。这可以避免触及AI令牌限制并节省成本。

幕后:范围管理器的工作原理

让我们追踪ChatGPT-CodeReview机器人如何应用这些规则。这发生在Probot应用核心(审查协调器)从GitHub获取变更文件列表之后。

解析:保镖的决策过程

  1. 获取所有变更:机器人首先向GitHub请求拉取请求中所有更改的文件。
  2. 加载规则:然后从环境变量中读取IGNOREIGNORE_PATTERNSINCLUDE_PATTERNS
  3. 优先检查INCLUDE_PATTERNS:如果设置了INCLUDE_PATTERNS,保镖会立即过滤列表,仅保留匹配至少一个这些模式的文件。任何不匹配的文件将被丢弃。
  4. 检查IGNORE列表:对于剩余的文件,保镖检查文件的精确名称是否在IGNORE列表中。如果是,文件将被丢弃。
  5. 检查IGNORE_PATTERNS:对于仍然剩余的文件,保镖检查文件是否匹配任何IGNORE_PATTERNS。如果匹配,文件将被丢弃。
  6. 最终列表:通过所有这些检查的文件被视为"相关"。
  7. 大小检查:在将每个"相关"文件发送给AI之前,机器人提取其特定变更(patch)。如果patch长度超过MAX_PATCH_LENGTH,则跳过该文件的审查,但其他文件仍可能被审查。

序列图

在这里插入图片描述

代码

在这里插入图片描述

核心过滤逻辑位于src/bot.ts中的app.on处理程序内。

  1. 加载配置
    首先,机器人从环境变量加载过滤偏好。

    // 文件: src/bot.ts (摘录)
    // ... 在app.on处理程序中 ...const ignoreList = (process.env.IGNORE || process.env.ignore || '').split('\n').filter((v) => v !== ''); // 按换行符分割,移除空条目
    const ignorePatterns = (process.env.IGNORE_PATTERNS || '').split(',').filter((v) => Boolean(v.trim())); // 按逗号分割
    const includePatterns = (process.env.INCLUDE_PATTERNS || '').split(',').filter((v) => Boolean(v.trim())); // 按逗号分割log.debug('ignoreList:', ignoreList);
    log.debug('ignorePatterns:', ignorePatterns);
    log.debug('includePatterns:', includePatterns);// ... 其余代码 ...
    

    此片段将IGNOREIGNORE_PATTERNSINCLUDE_PATTERNS字符串转换为干净的数组,便于检查。

  2. changedFiles应用过滤器
    接下来,机器人遍历每个变更文件,并使用filter方法应用规则。

    // 文件: src/bot.ts (摘录)
    // ... 加载配置后 ...changedFiles = changedFiles?.filter((file) => {const filePath = file.filename; // 被检查文件的路径// 规则3: INCLUDE_PATTERNS(优先级最高)if (includePatterns.length) {return matchPatterns(includePatterns, filePath); // 仅包含匹配的文件}// 规则1: IGNORE列表(次优先级)if (ignoreList.includes(filePath)) {return false; // 如果在忽略列表中,排除}// 规则2: IGNORE_PATTERNS(排除的最后优先级)if (ignorePatterns.length) {return !matchPatterns(ignorePatterns, filePath); // 如果匹配忽略模式,排除}return true; // 如果没有规则适用,默认包含文件});if (!changedFiles?.length) {log.info('过滤后未发现变更');return 'no change';
    }
    // ... 其余代码 ...
    

    filter函数逐个处理每个文件。注意includePatterns首先被检查。如果使用了它,其他忽略规则对该文件将被跳过。

  3. matchPatterns辅助函数
    matchPatterns函数是一个辅助函数,使用minimatch库检查文件路径是否匹配任何glob模式。它还支持回退到正则表达式。

    // 文件: src/bot.ts (摘录 - 文件底部)
    const matchPatterns = (patterns: string[], path: string) => 
    {return patterns.some((pattern) => { // 检查是否有任何模式匹配try {// 使用minimatch处理glob模式(例如"*.js"、"src/**")return minimatch(path, pattern.startsWith('/') ? "**" + pattern : pattern.startsWith("**") ? pattern : "**/" + pattern);} catch {// 如果不是glob,尝试作为正则表达式匹配try {return new RegExp(pattern).test(path);} catch (e) {return false; // 无效模式}}})
    }
    

    此函数使模式匹配功能强大且灵活。patterns.some()意味着如果列表中至少一个模式匹配path,则返回true

  4. MAX_PATCH_LENGTH检查
    在初始过滤后,机器人遍历剩余文件。对于每个文件,在将其patch发送给AI之前,检查MAX_PATCH_LENGTH

    // 文件: src/bot.ts (摘录)
    // ... 在发送文件给AI的循环中 ...
    const MAX_PATCH_COUNT = process.env.MAX_PATCH_LENGTH? +process.env.MAX_PATCH_LENGTH: Infinity; // 默认为无限制for (let i = 0; i < changedFiles.length; i++) {const file = changedFiles[i];const patch = file.patch || ''; // 获取实际代码变更if (!patch || patch.length > MAX_PATCH_COUNT) {log.info(`${file.filename} 因差异过大而被跳过`);continue; // 跳过此文件,继续下一个}// ... 调用chat?.codeReview(patch)在此处发生 ...
    }
    

    此检查确保即使大文件通过了名称/模式过滤,其单个变更也不会压倒AI或消耗过多令牌。

总结

**文件过滤逻辑(范围管理器)**是ChatGPT-CodeReview的关键组件。

它作为一个智能保镖,使用用户定义的规则(IGNOREIGNORE_PATTERNSINCLUDE_PATTERNS从拉取请求中选择最相关的文件

强制执行MAX_PATCH_LENGTH,确保发送给AI的单个代码变更可控,避免昂贵的审查和触及AI令牌限制

通过有效管理审查范围,机器人提供了更集中、高效且经济高效的反馈。

现在我们了解了机器人如何决定审查什么,让我们学习如何窥探幕后,看看机器人在做什么。在下一章中,我们将探索第6章:日志机制(调试)。


文章转载自:

http://TXg7CdRC.wkmjg.cn
http://jdIfWbB0.wkmjg.cn
http://M2aPmAmv.wkmjg.cn
http://NNa3Gd42.wkmjg.cn
http://2paDZFJi.wkmjg.cn
http://V92Fz1at.wkmjg.cn
http://OXd6EUOI.wkmjg.cn
http://aM60SpUA.wkmjg.cn
http://cDKgMSEB.wkmjg.cn
http://jMgcXE0i.wkmjg.cn
http://8fRNVbdH.wkmjg.cn
http://OnS9qaJX.wkmjg.cn
http://xLAUZPGH.wkmjg.cn
http://RJJkD7Kh.wkmjg.cn
http://HqucV1I8.wkmjg.cn
http://qvcchNUz.wkmjg.cn
http://32VShcWa.wkmjg.cn
http://fGDNRD44.wkmjg.cn
http://DRWNVGWN.wkmjg.cn
http://AU9HT5r0.wkmjg.cn
http://a2zZhOSZ.wkmjg.cn
http://wU2hnm1H.wkmjg.cn
http://eD6Qmsjw.wkmjg.cn
http://rC0qkAuy.wkmjg.cn
http://o1uikdRE.wkmjg.cn
http://SxMH3fVe.wkmjg.cn
http://UWzQrp1N.wkmjg.cn
http://qssMLHHJ.wkmjg.cn
http://U2t2iuan.wkmjg.cn
http://jkOKzjbM.wkmjg.cn
http://www.dtcms.com/a/381913.html

相关文章:

  • 学习嵌入式第五十三天
  • [code-review] 日志机制 | `LOG_LEVEL`
  • 物联网-无人自助茶室-如何实现24H智能营业?
  • JVM基础篇以及JVM内存泄漏诊断与分析
  • 【WRF数据准备】批量下载ERA5再分析数据-气象驱动数据
  • 如何实现文件批量重命名自动化
  • 【Unity 性能优化之路——概述(0)】
  • 零基础学AI大模型之SpringAI
  • AI行业应用:金融、医疗、教育、制造业的落地案例
  • 一文详解 Python 密码哈希库 Passlib
  • 360浏览器录屏功能、360浏览器录屏使用、免费录屏工具、Windows内置工具、开发者效率工具
  • 老梁聊全栈系列:现代全栈的「角色边界」与「能力雷达图」
  • ES——(三)DSL高级查询
  • 深度神经网络1——梯度问题+标签数不够问题
  • 【Unity UGUI 自动布局组(12)】
  • RAG 从入门到放弃?丐版 demo 实战笔记(go+python)
  • goland 断点调试显示“变量不可用”
  • Qt/C++,windows多进程demo
  • 再谈golang的sql链接dsn
  • pre-commit run --all-files 报错:http.client.RemoteDisconnected
  • STM32N6AI资料汇总
  • 【MySQL】E-R图
  • QT元对象系统(未完)
  • Netty 针对 Java NIO Selector 优化:SelectedSelectionKeySet
  • 抑制信号突变(模拟量采集+斜坡函数)
  • C语言入门指南:字符函数和字符串函数
  • JVM从入门到实战:从字节码组成、类生命周期到双亲委派及打破双亲委派机制
  • SQL-用户管理与操作权限
  • Airtable与Python:轻量级ETL数据管道实战
  • JavaScript 对象:一份全面的回顾