|
|
@@ -164,8 +164,13 @@ class WebhookService:
|
|
|
if is_dir:
|
|
|
# If it's a directory output, any change inside that directory counts
|
|
|
dir_path = path_pattern.rstrip("/")
|
|
|
- if f == dir_path or f.startswith(dir_path + "/"):
|
|
|
- return True
|
|
|
+ if '*' in dir_path:
|
|
|
+ import fnmatch
|
|
|
+ if fnmatch.fnmatch(f, dir_path + "/*") or fnmatch.fnmatch(f, dir_path):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ if f == dir_path or f.startswith(dir_path + "/"):
|
|
|
+ return True
|
|
|
else:
|
|
|
# Single file output: exact match
|
|
|
if f == path_pattern:
|
|
|
@@ -198,23 +203,47 @@ class WebhookService:
|
|
|
|
|
|
path_pattern = normalize_path(raw_path_pattern)
|
|
|
is_dir = is_directory_pattern(raw_path_pattern)
|
|
|
+ dir_path = path_pattern.rstrip("/")
|
|
|
|
|
|
if is_dir:
|
|
|
- # Directory pattern: fetch only this directory's files
|
|
|
- dir_path = path_pattern.rstrip("/")
|
|
|
- logger.info(f"Fetching directory: {dir_path} with patterns: {patterns}, excludes: {excludes}")
|
|
|
+ # Directory pattern: fetch files from the closest static parent directory
|
|
|
+ # For `data/*/test/`, that is `data/`
|
|
|
+ import re
|
|
|
+
|
|
|
+ # Split by first wildcard chunk path
|
|
|
+ wildcard_idx = dir_path.find('*')
|
|
|
+ if wildcard_idx != -1:
|
|
|
+ static_base = dir_path[:wildcard_idx]
|
|
|
+ # Trim back to the nearest directory separator
|
|
|
+ last_sep = static_base.rfind('/')
|
|
|
+ if last_sep != -1:
|
|
|
+ static_base = static_base[:last_sep]
|
|
|
+ else:
|
|
|
+ static_base = "" # ROOT
|
|
|
+ else:
|
|
|
+ static_base = dir_path
|
|
|
+
|
|
|
+ static_base = static_base.strip('/')
|
|
|
+
|
|
|
+ logger.info(f"Fetching directory: {static_base} (to match wildcard path: {dir_path}) with patterns: {patterns}, excludes: {excludes}")
|
|
|
|
|
|
- files = await self.gogs.get_directory_tree(owner, repo_name, commit_id, dir_path)
|
|
|
+ files = await self.gogs.get_directory_tree(owner, repo_name, commit_id, static_base)
|
|
|
|
|
|
for file_info in files:
|
|
|
file_path = file_info.get("path")
|
|
|
- # Calculate name relative to the watched directory
|
|
|
- # e.g. dir_path="a", file_path="a/b.txt" -> rel_name="b.txt"
|
|
|
- rel_name = (
|
|
|
- file_path[len(dir_path) + 1 :]
|
|
|
- if file_path.startswith(dir_path + "/")
|
|
|
- else file_path
|
|
|
- )
|
|
|
+
|
|
|
+ # 1. First verify if the full path matches the wildcard directory path provided
|
|
|
+ if '*' in dir_path:
|
|
|
+ # e.g dir_path: data/*/test/ -> match: data/*/test/*
|
|
|
+ if not fnmatch.fnmatch(file_path, dir_path + "/*") and not fnmatch.fnmatch(file_path, dir_path):
|
|
|
+ continue
|
|
|
+ else:
|
|
|
+ if not file_path.startswith(dir_path + "/"):
|
|
|
+ continue
|
|
|
+
|
|
|
+ # Calculate name relative to the matched base path segment for pattern matching
|
|
|
+ import os
|
|
|
+ rel_name = os.path.basename(file_path)
|
|
|
|
|
|
if self._match_patterns(rel_name, patterns, excludes):
|
|
|
try:
|