Module: Elect::Processor
- Defined in:
- lib/elect/processor.rb
Overview
文件与目录扫描处理器。
职责:
- 遍历目录树,找出所有文本类文件
- 逐文件读取、检测水印、按选项清理或仅报告
- 输出统计信息
Defined Under Namespace
Classes: Result
Constant Summary collapse
- DEFAULT_EXTS =
默认扫描的文件扩展名
%w[ .md .txt .py .rb .js .ts .tsx .jsx .java .go .rs .c .h .cpp .hpp .cc .cs .php .swift .kt .scala .html .css .scss .less .vue .svelte .json .yaml .yml .toml .xml .sql .sh .bat .ps1 .tex .rst .adoc .org .csv .tsv .ini .conf .cfg ].freeze
Class Method Summary collapse
-
.process_dir(dir, dry_run: false, verbose: false, exts: nil, exclude: nil) ⇒ Object
扫描并处理目录。.
-
.process_file(path, dry_run: false, verbose: false) ⇒ Object
扫描并处理单个文件。.
-
.report(results) ⇒ Object
打印汇总报告.
Class Method Details
.process_dir(dir, dry_run: false, verbose: false, exts: nil, exclude: nil) ⇒ Object
扫描并处理目录。
参数:
dir - 目录路径
dry_run - true 时仅检测不修改
verbose - true 时输出详细日志
exts - 自定义扩展名数组(nil 用 DEFAULT_EXTS)
exclude - 排除的目录名数组(如 ["node_modules", ".git"])
返回: [Result, ...]
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/elect/processor.rb', line 94 def self.process_dir(dir, dry_run: false, verbose: false, exts: nil, exclude: nil) d = Pathname.new(dir) exts = (exts || DEFAULT_EXTS).map { |e| e.start_with?(".") ? e : ".#{e}" } exclude_set = (exclude || %w[node_modules .git .svn __pycache__ dist build]).to_set results = [] d.find do |path| next if path == d if path.directory? next if exclude_set.include?(path.basename.to_s) next end next unless exts.include?(path.extname.downcase) r = process_file(path, dry_run: dry_run, verbose: verbose) results << r end results end |
.process_file(path, dry_run: false, verbose: false) ⇒ Object
扫描并处理单个文件。
参数:
path - 文件路径(String 或 Pathname)
dry_run - true 时仅检测不改写文件
verbose - true 时输出详细日志
返回: Result
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/elect/processor.rb', line 39 def self.process_file(path, dry_run: false, verbose: false) p = Pathname.new(path) result = Result.new(path: p.to_s, removed: 0, status: :skip) unless p.file? result.status = :not_found return result end # 统一走二进制读取 + 编码强制转换,避免非 UTF-8 文件触发 ArgumentError raw = begin data = File.binread(p.to_s) data = data.force_encoding(Encoding::UTF_8) unless data.valid_encoding? data = data.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "?") end data rescue => e warn "[elect] 跳过 #{p}: #{e.}" if verbose result.status = :error return result end n = Cleaner.detect(raw) if n.zero? result.status = :clean return result end if dry_run result.removed = n result.status = :found puts " [DRY] #{p} — 发现 #{n} 处水印" return result end cleaned, removed = Cleaner.clean(raw) p.write(cleaned, encoding: "utf-8") result.removed = removed result.status = :cleaned puts " [OK] #{p} — 移除 #{removed} 处水印" if verbose result end |
.report(results) ⇒ Object
打印汇总报告
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/elect/processor.rb', line 118 def self.report(results) total = results.size found = results.count { |r| r.status == :found } cleaned = results.count { |r| r.status == :cleaned } clean = results.count { |r| r.status == :clean } skipped = results.count { |r| r.status == :skip } errors = results.count { |r| r.status == :error } total_rm = results.sum { |r| r.removed } puts puts "=" * 50 puts " 扫描完毕" puts "=" * 50 puts " 扫描文件 : #{total}" puts " 发现水印 : #{found + cleaned} 个文件" puts " 已清理 : #{cleaned} 个文件 (共移除 #{total_rm} 处水印)" puts " 无水印 : #{clean} 个文件" puts " 跳过 : #{skipped}" puts " 错误 : #{errors}" if errors.positive? puts "=" * 50 end |