求类似JS的parse-gitignore的Dart库或代码示例
实现类似parse-gitignore功能的Dart方案
1. 现有Dart库推荐
目前pub.dev上有gitignore包,它可以解析.gitignore规则,支持处理注释、空行、否定模式、通配符匹配等核心功能,和你提到的parse-gitignore功能对齐。你可以通过pub add gitignore安装后使用,基本用法如下:
import 'package:gitignore/gitignore.dart'; void main() { // 从文件加载.gitignore内容 final gitignore = GitIgnore.fromFile('.gitignore'); // 检查文件是否应该被忽略 print(gitignore.shouldIgnore('build/')); // true print(gitignore.shouldIgnore('lib/main.dart')); // false(如果没在规则里) }
2. 手动实现核心逻辑(如果不想依赖第三方库)
如果需要自己实现核心解析逻辑,核心步骤是处理.gitignore的语法规则:
- 跳过空行和以
#开头的注释行 - 处理否定模式(以
!开头的规则,优先级高于之前的匹配规则) - 处理目录模式(以
/结尾的规则,仅匹配目录) - 处理通配符(
*匹配任意字符,**匹配任意层级目录)
以下是一个简化的实现示例:
import 'package:path/path.dart' as path; class GitIgnoreParser { final List<String> _includePatterns = []; final List<String> _excludePatterns = []; GitIgnoreParser(String content) { _parse(content); } void _parse(String content) { final lines = content.split('\n'); for (var line in lines) { line = line.trim(); // 跳过空行和注释 if (line.isEmpty || line.startsWith('#')) continue; if (line.startsWith('!')) { // 否定模式,加入包含列表 _includePatterns.add(_normalizePattern(line.substring(1).trim())); } else { // 排除模式,加入排除列表 _excludePatterns.add(_normalizePattern(line)); } } } String _normalizePattern(String pattern) { // 统一路径分隔符为Unix风格 return path.posix.normalize(pattern); } bool shouldIgnore(String filePath) { final normalizedPath = path.posix.normalize(filePath); // 先检查是否在包含列表里(优先级更高) for (var pattern in _includePatterns) { if (_matches(pattern, normalizedPath)) { return false; } } // 再检查排除列表 for (var pattern in _excludePatterns) { if (_matches(pattern, normalizedPath)) { return true; } } return false; } bool _matches(String pattern, String filePath) { // 处理目录模式:以/结尾,匹配目录本身或其下的所有内容 final isDirPattern = pattern.endsWith('/'); final adjustedPattern = isDirPattern ? pattern.substring(0, pattern.length - 1) : pattern; // 处理**通配符:替换为跨目录匹配的正则 String regexStr = adjustedPattern .replaceAll(r'**', r'.*') .replaceAll(r'*', r'[^/]*') .replaceAll(r'?', r'.'); // 目录模式需要匹配路径前缀或完全一致 if (isDirPattern) { regexStr = r'^' + regexStr + r'(/.*)?$'; } else { regexStr = r'^' + regexStr + r'$'; } return RegExp(regexStr).hasMatch(filePath); } } // 使用示例 void main() { final gitignoreContent = ''' # 注释 *.dart.js !test.dart.js build/ lib/**/*.g.dart '''; final parser = GitIgnoreParser(gitignoreContent); print(parser.shouldIgnore('main.dart.js')); // true print(parser.shouldIgnore('test.dart.js')); // false print(parser.shouldIgnore('build/output.js')); // true print(parser.shouldIgnore('lib/src/utils.g.dart')); // true }
注意事项
- 完整的.gitignore语法还包含字符集匹配(
[abc])、开头/限制根目录匹配等细节,若需完全兼容官方规范,优先使用成熟第三方库 - 手动实现时通过
path包统一处理路径分隔符,可适配不同操作系统的路径格式
内容的提问来源于stack exchange,提问作者redDwarf
相关产品推荐
相关产品推荐

