diff --git a/scripts/process-text-files.py b/scripts/process-text-files.py index 4f1aab2..8d22605 100644 --- a/scripts/process-text-files.py +++ b/scripts/process-text-files.py @@ -2,7 +2,9 @@ # -*- coding: utf-8 -*- from __future__ import print_function +import sys import re +import fnmatch import argparse from abc import abstractmethod import os @@ -12,13 +14,24 @@ import subprocess import jwutils from jwutils.log import * -def _regexify(l): - return '|'.join(x.replace('.', '\.') + '$' for x in l) - _exts_h = set([ '.h', '.H', '.hxx', '.HXX', '.hpp']) _exts_cpp = set([ '.cpp', '.CPP', '.c', '.C', '.cxx', '.CXX' ]) _exts_h_cpp = _exts_h | _exts_cpp +def _regexify(l): + return '|'.join(x.replace('.', '\.') + '$' for x in l) + +def _scantree(path, maxdepth=sys.maxsize, depth=0): + if depth == maxdepth: + return path + if depth > maxdepth: + return [] + for entry in os.scandir(path): + if entry.is_dir(follow_symlinks=False): + yield from _scantree(entry.path, maxdepth, depth+1) + else: + yield entry + # ----------------------------------------------------------------------------------- Base class class Cmd(jwutils.Cmd): @@ -338,7 +351,9 @@ class Cmd(jwutils.Cmd): def add_parser(self, parsers): p = super(Cmd, self).add_parser(parsers) p.add_argument('-r', "--root", help="Point in file system from which to start search", default='.') + p.add_argument("--name", help="Globbing pattern to select input file names", default=None) p.add_argument("--name-regex", help="Regular expression to select input file names", default=None) + p.add_argument("--maxdepth", help="Maximum directory search depth", type=int, default=None) p.add_argument("--replace-patterns-from", help="File with patterns to replace, side by side, divided by '->'", default=None) p.add_argument("--backup", help="Backup extension", default='rep') p.add_argument('-g', '--git', help="Use git mv for renaming files", action='store_true', default=False) @@ -357,11 +372,18 @@ class Cmd(jwutils.Cmd): async def run(self, args): self._init(args) files = [] - if args.name_regex is not None: - for root, dirs, names in os.walk(args.root): - for name in names: - if re.search(args.name_regex, name): - files.append((root, name)) + if args.name: + regex = fnmatch.translate(args.name) + else: + regex = args.name_regex + maxdepth = args.maxdepth if args.maxdepth is not None else int(args.maxdepth) + if regex is not None: + for entry in _scantree(args.root, args.maxdepth): + if re.search(regex, entry.name): + root = os.path.dirname(entry.path) + if not root: + root = '.' + files.append((root, entry.path)) self.process(args, files) @abstractmethod