diff --git a/pyproject.toml b/pyproject.toml index e2f22b0..238cf5f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "socketsecurity" -version = "2.2.57" +version = "2.2.59" requires-python = ">= 3.10" license = {"file" = "LICENSE"} dependencies = [ diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index 798b847..53c3012 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,3 +1,3 @@ __author__ = 'socket.dev' -__version__ = '2.2.57' +__version__ = '2.2.59' USER_AGENT = f'SocketPythonCLI/{__version__}' diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index a76a794..9da7915 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -4,13 +4,10 @@ import tarfile import tempfile import time -import io import json from dataclasses import asdict -from glob import glob -from io import BytesIO -from pathlib import PurePath -from typing import BinaryIO, Dict, List, Tuple, Set, Union, TYPE_CHECKING, Optional +from pathlib import Path, PurePath +from typing import Dict, List, Tuple, Set, TYPE_CHECKING, Optional if TYPE_CHECKING: from socketsecurity.config import CliConfig @@ -315,15 +312,18 @@ def find_files(self, path: str, ecosystems: Optional[List[str]] = None) -> List[ for pattern in expanded_patterns: case_insensitive_pattern = Core.to_case_insensitive_regex(pattern) - file_path = os.path.join(path, "**", case_insensitive_pattern) - - log.debug(f"Globbing {file_path}") + + log.debug(f"Searching for pattern: {case_insensitive_pattern}") glob_start = time.time() - glob_files = glob(file_path, recursive=True) + + # Use pathlib.Path.rglob() instead of glob.glob() to properly match dotfiles/dotdirs + base_path = Path(path) + glob_files = base_path.rglob(case_insensitive_pattern) for glob_file in glob_files: - if os.path.isfile(glob_file) and not Core.is_excluded(glob_file, self.config.excluded_dirs): - files.add(glob_file.replace("\\", "/")) + glob_file_str = str(glob_file) + if os.path.isfile(glob_file_str) and not Core.is_excluded(glob_file_str, self.config.excluded_dirs): + files.add(glob_file_str.replace("\\", "/")) glob_end = time.time() log.debug(f"Globbing took {glob_end - glob_start:.4f} seconds") @@ -414,6 +414,11 @@ def has_manifest_files(self, files: list) -> bool: # Expand brace patterns for each manifest pattern expanded_patterns = Core.expand_brace_pattern(pattern_str) for exp_pat in expanded_patterns: + # If pattern doesn't contain '/', prepend '**/' to match files in any subdirectory + # This ensures patterns like '*requirements.txt' match '.test/requirements.txt' + if '/' not in exp_pat: + exp_pat = f"**/{exp_pat}" + for file in norm_files: # Use PurePath.match for glob-like matching if PurePath(file).match(exp_pat):