From 55caaf62ebbbd72ad95a59428eee9f58199789e1 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Thu, 28 Dec 2023 06:12:13 +0100 Subject: [PATCH] support */dir1 pattern on ignore --- CONTRIBUTING.md | 8 ++++++++ docs/config/config-file.md | 2 +- dotdrop/utils.py | 24 ++++++++++++++++-------- tests-ng/ignore-patterns.sh | 8 ++++---- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 86d9f085..3822d930 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,6 +161,14 @@ dynvariables: ## Ignore pattern +Officially only `*/file` and `*/dir/*` should be used for ignore pattern. +However we still recursively process each path components to ensure +that pattern like `*/dir` are matched (see `_match_ignore_pattern` +in `utils.py`). + +We also append a separator to directory before checking +for a match with the ignore patterns. + **compare** * for files, match with ignore directly diff --git a/docs/config/config-file.md b/docs/config/config-file.md index 2258dde0..27f36f71 100644 --- a/docs/config/config-file.md +++ b/docs/config/config-file.md @@ -191,7 +191,7 @@ It is possible to ignore specific patterns when using dotdrop. * Using dotfiles block [upignore](config-dotfiles.md) * Using the command line switch `-i`/`--ignore` -The ignore pattern must follow Unix shell-style wildcards, like, for example `*/path/to/file` for files or +The ignore pattern must follow Unix shell-style wildcards, like for example `*/path/to/file` for files and `*/path/to/directory/*` for directories. Make sure to quote these when using wildcards in the config file. diff --git a/dotdrop/utils.py b/dotdrop/utils.py index 73bbf5c4..fa45a12d 100644 --- a/dotdrop/utils.py +++ b/dotdrop/utils.py @@ -227,15 +227,23 @@ def strip_home(path): def _match_ignore_pattern(path, pattern, debug=False): """ returns true if path matches the pattern + we test the entire path but also + any parent directory recursively to + be able to match pattern like "*/dir" """ - if debug: - msg = f'fnmatch \"{path}\" against {pattern}' - LOG.dbg(msg, force=True) - ret = fnmatch.fnmatch(path, pattern) - if debug: - LOG.dbg(f'ignore \"{pattern}\" match: {path}', - force=True) - return ret + subpath = path + while subpath != os.path.sep: + if debug: + msg = f'fnmatch \"{subpath}\" against {pattern}' + LOG.dbg(msg, force=True) + ret = fnmatch.fnmatch(subpath, pattern) + if debug: + LOG.dbg(f'ignore \"{pattern}\" match: {subpath}', + force=True) + if ret: + return ret + subpath = os.path.dirname(subpath) + return False def _must_ignore(path, ignores, neg_ignores, debug=False): diff --git a/tests-ng/ignore-patterns.sh b/tests-ng/ignore-patterns.sh index 4a4bce58..6bb01785 100755 --- a/tests-ng/ignore-patterns.sh +++ b/tests-ng/ignore-patterns.sh @@ -57,11 +57,11 @@ dotfiles: src: mpv dst: ${tmpd}/mpv cmpignore: - - '*/watch_later/*' + - '*/watch_later' upignore: - - '*/watch_later/*' + - '*/watch_later' instignore: - - '*/watch_later/*' + - '*/watch_later' profiles: p1: dotfiles: @@ -97,7 +97,7 @@ config: dotpath: dotfiles ignoreempty: true impignore: - - '*/watch_later/*' + - '*/watch_later' dotfiles: profiles: _EOF