redup 0.3.27__tar.gz → 0.3.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. {redup-0.3.27 → redup-0.3.28}/PKG-INFO +2 -2
  2. {redup-0.3.27 → redup-0.3.28}/README.md +1 -1
  3. {redup-0.3.27 → redup-0.3.28}/pyproject.toml +1 -1
  4. {redup-0.3.27 → redup-0.3.28}/src/redup/__init__.py +1 -1
  5. {redup-0.3.27 → redup-0.3.28}/src/redup/core/models.py +48 -2
  6. {redup-0.3.27 → redup-0.3.28}/src/redup/core/scanner.py +21 -8
  7. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/PKG-INFO +2 -2
  8. {redup-0.3.27 → redup-0.3.28}/LICENSE +0 -0
  9. {redup-0.3.27 → redup-0.3.28}/setup.cfg +0 -0
  10. {redup-0.3.27 → redup-0.3.28}/src/redup/__main__.py +0 -0
  11. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/__init__.py +0 -0
  12. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/config_builder.py +0 -0
  13. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/fuzzy_similarity.py +0 -0
  14. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/main.py +0 -0
  15. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/output_writer.py +0 -0
  16. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/scan_commands.py +0 -0
  17. {redup-0.3.27 → redup-0.3.28}/src/redup/cli_app/scan_helpers.py +0 -0
  18. {redup-0.3.27 → redup-0.3.28}/src/redup/core/__init__.py +0 -0
  19. {redup-0.3.27 → redup-0.3.28}/src/redup/core/cache.py +0 -0
  20. {redup-0.3.27 → redup-0.3.28}/src/redup/core/config.py +0 -0
  21. {redup-0.3.27 → redup-0.3.28}/src/redup/core/differ.py +0 -0
  22. {redup-0.3.27 → redup-0.3.28}/src/redup/core/fuzzy_similarity.py +0 -0
  23. {redup-0.3.27 → redup-0.3.28}/src/redup/core/hash_cache.py +0 -0
  24. {redup-0.3.27 → redup-0.3.28}/src/redup/core/hasher.py +0 -0
  25. {redup-0.3.27 → redup-0.3.28}/src/redup/core/lazy_grouper.py +0 -0
  26. {redup-0.3.27 → redup-0.3.28}/src/redup/core/lsh_matcher.py +0 -0
  27. {redup-0.3.27 → redup-0.3.28}/src/redup/core/matcher.py +0 -0
  28. {redup-0.3.27 → redup-0.3.28}/src/redup/core/pipeline.py +0 -0
  29. {redup-0.3.27 → redup-0.3.28}/src/redup/core/planner.py +0 -0
  30. {redup-0.3.27 → redup-0.3.28}/src/redup/core/ts_extractor.py +0 -0
  31. {redup-0.3.27 → redup-0.3.28}/src/redup/core/universal_fuzzy.py +0 -0
  32. {redup-0.3.27 → redup-0.3.28}/src/redup/core/utils/__init__.py +0 -0
  33. {redup-0.3.27 → redup-0.3.28}/src/redup/core/utils/duplicate_finders.py +0 -0
  34. {redup-0.3.27 → redup-0.3.28}/src/redup/core/utils/function_extractor.py +0 -0
  35. {redup-0.3.27 → redup-0.3.28}/src/redup/core/utils/hash_utils.py +0 -0
  36. {redup-0.3.27 → redup-0.3.28}/src/redup/core/utils/language_dispatcher.py +0 -0
  37. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/__init__.py +0 -0
  38. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/code2llm_reporter.py +0 -0
  39. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/enhanced_reporter.py +0 -0
  40. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/json_reporter.py +0 -0
  41. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/markdown_reporter.py +0 -0
  42. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/toon_reporter.py +0 -0
  43. {redup-0.3.27 → redup-0.3.28}/src/redup/reporters/yaml_reporter.py +0 -0
  44. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/SOURCES.txt +0 -0
  45. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/dependency_links.txt +0 -0
  46. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/entry_points.txt +0 -0
  47. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/requires.txt +0 -0
  48. {redup-0.3.27 → redup-0.3.28}/src/redup.egg-info/top_level.txt +0 -0
  49. {redup-0.3.27 → redup-0.3.28}/tests/test_e2e.py +0 -0
  50. {redup-0.3.27 → redup-0.3.28}/tests/test_hasher.py +0 -0
  51. {redup-0.3.27 → redup-0.3.28}/tests/test_matcher.py +0 -0
  52. {redup-0.3.27 → redup-0.3.28}/tests/test_models.py +0 -0
  53. {redup-0.3.27 → redup-0.3.28}/tests/test_pipeline.py +0 -0
  54. {redup-0.3.27 → redup-0.3.28}/tests/test_planner.py +0 -0
  55. {redup-0.3.27 → redup-0.3.28}/tests/test_reporters.py +0 -0
  56. {redup-0.3.27 → redup-0.3.28}/tests/test_scanner.py +0 -0
  57. {redup-0.3.27 → redup-0.3.28}/tests/test_ts_extractor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: redup
3
- Version: 0.3.27
3
+ Version: 0.3.28
4
4
  Summary: Code duplication analyzer and refactoring planner for LLMs
5
5
  Author-email: Tom Sapletta <tom@sapletta.com>
6
6
  License-Expression: Apache-2.0
@@ -84,7 +84,7 @@ Dynamic: license-file
84
84
  [![PyPI](https://img.shields.io/pypi/v/redup)](https://pypi.org/project/redup/)
85
85
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
86
86
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
87
- [![Version](https://img.shields.io/badge/version-0.3.27-green.svg)](https://pypi.org/project/redup/)
87
+ [![Version](https://img.shields.io/badge/version-0.3.28-green.svg)](https://pypi.org/project/redup/)
88
88
 
89
89
  reDUP scans codebases for duplicated functions, blocks, and structural patterns — then builds a prioritized refactoring map that LLMs can consume to eliminate redundancy systematically.
90
90
 
@@ -5,7 +5,7 @@
5
5
  [![PyPI](https://img.shields.io/pypi/v/redup)](https://pypi.org/project/redup/)
6
6
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
8
- [![Version](https://img.shields.io/badge/version-0.3.27-green.svg)](https://pypi.org/project/redup/)
8
+ [![Version](https://img.shields.io/badge/version-0.3.28-green.svg)](https://pypi.org/project/redup/)
9
9
 
10
10
  reDUP scans codebases for duplicated functions, blocks, and structural patterns — then builds a prioritized refactoring map that LLMs can consume to eliminate redundancy systematically.
11
11
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "redup"
7
- version = "0.3.27"
7
+ version = "0.3.28"
8
8
  description = "Code duplication analyzer and refactoring planner for LLMs"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "0.3.27"
5
+ __version__ = "0.3.28"
6
6
 
7
7
  from redup.core.models import (
8
8
  DuplicateFragment,
@@ -41,8 +41,54 @@ class ScanConfig:
41
41
  extensions: list[str] = field(default_factory=lambda: [".py"])
42
42
  exclude_patterns: list[str] = field(
43
43
  default_factory=lambda: [
44
- "__pycache__", ".git", ".venv", "venv", "node_modules",
45
- ".tox", ".mypy_cache", ".pytest_cache", "*.egg-info", "dist", "build",
44
+ # Universal system files (but not normal code files)
45
+ ".git/", ".svn/", ".hg/", "__pycache__/", ".pytest_cache/", ".mypy_cache/",
46
+ ".ruff_cache/", ".tox/", ".nox/", ".coverage", "htmlcov/", ".DS_Store",
47
+ "Thumbs.db", "*.swp", "*.swo", "*~", ".vscode/", ".idea/",
48
+
49
+ # Python specific
50
+ "*.pyc", "*.pyo", "*.pyd", "$py.class",
51
+ "python*/", "python3*/", "Python*/",
52
+ "venv*/", "env*/", ".venv*/", ".env*/",
53
+ "*.egg-info/", "*.egg", "build/", "dist/",
54
+ ".installer/", ".eggs/", "lib/", "lib64/", "parts/", "sdist/", "var/", "wheels/",
55
+
56
+ # Node.js/JavaScript
57
+ "node_modules/", "npm-debug.log*", "yarn-debug.log*", "yarn-error.log*",
58
+ "pnpm-debug.log*", ".npm/", ".yarn-integrity/", ".eslintcache/", ".stylelintcache/",
59
+ ".next/", ".nuxt/", ".vuepress/dist/",
60
+
61
+ # Java/Maven/Gradle
62
+ "target/", "build/", "out/", ".classpath/", ".project/", ".settings/",
63
+ ".mvn/", "gradle/", ".gradle/", "*.class", "*.jar", "*.war", "*.ear", "*.aar",
64
+
65
+ # Rust
66
+ "target/", "Cargo.lock", "**/*.rs.bk",
67
+
68
+ # Go
69
+ "vendor/", "*.exe", "*.exe~", "*.dll", "*.so", "*.dylib", "*.test", "*.out",
70
+
71
+ # Docker
72
+ ".dockerignore", ".docker/",
73
+
74
+ # Mobile
75
+ "android/app/build/", "ios/build/", "*.apk", "*.ipa", "*.xcarchive",
76
+
77
+ # Database
78
+ "*.db", "*.sqlite", "*.sqlite3", "data/", "logs/",
79
+
80
+ # Cloud/DevOps
81
+ ".terraform/", ".terraform.lock.hcl", "*.tfstate", "*.tfstate.*", ".ansible/", ".kube/",
82
+
83
+ # General build/cache
84
+ "cache/", ".cache/", "tmp/", ".tmp/", "*.tmp", "*.temp", "*.bak", "*.backup",
85
+
86
+ # Package managers
87
+ "composer.lock", "package-lock.json", "yarn.lock", "pnpm-lock.yaml",
88
+ "poetry.lock", "Pipfile.lock", "Gemfile.lock",
89
+
90
+ # Logs
91
+ "*.log", "logs/",
46
92
  ]
47
93
  )
48
94
  min_block_lines: int = 3
@@ -111,20 +111,33 @@ class MemoryFileCache:
111
111
 
112
112
  @functools.lru_cache(maxsize=1000)
113
113
  def _should_exclude(path: Path, patterns: tuple[str, ...]) -> bool:
114
- """Check if a path matches any exclusion pattern."""
114
+ """Check if a path matches any exclusion pattern with support for negation."""
115
115
  name = path.name
116
116
  str_path = str(path)
117
117
 
118
- # Check against patterns
118
+ # First check for exclusions (patterns starting with ! are inclusions)
119
119
  for pattern in patterns:
120
- if fnmatch.fnmatch(name, pattern) or fnmatch.fnmatch(str_path, pattern):
121
- return True
122
- # Check if any parent directory matches
123
- for part in path.parts:
124
- if fnmatch.fnmatch(part, pattern):
120
+ if not pattern.startswith('!'): # Regular exclusion pattern
121
+ if fnmatch.fnmatch(name, pattern) or fnmatch.fnmatch(str_path, pattern):
125
122
  return True
123
+ # Check if any parent directory matches
124
+ for part in path.parts:
125
+ if fnmatch.fnmatch(part, pattern):
126
+ return True
126
127
 
127
- return False
128
+ # Then check for explicit inclusions (negation patterns starting with !)
129
+ for pattern in patterns:
130
+ if pattern.startswith('!'):
131
+ # Remove ! and check if it matches
132
+ include_pattern = pattern[1:]
133
+ if fnmatch.fnmatch(name, include_pattern) or fnmatch.fnmatch(str_path, include_pattern):
134
+ return False # Explicitly included
135
+ # Check if any parent directory matches
136
+ for part in path.parts:
137
+ if fnmatch.fnmatch(part, include_pattern):
138
+ return False # Explicitly included
139
+
140
+ return False # Not excluded by any pattern
128
141
 
129
142
 
130
143
  def _collect_files(config: ScanConfig) -> list[Path]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: redup
3
- Version: 0.3.27
3
+ Version: 0.3.28
4
4
  Summary: Code duplication analyzer and refactoring planner for LLMs
5
5
  Author-email: Tom Sapletta <tom@sapletta.com>
6
6
  License-Expression: Apache-2.0
@@ -84,7 +84,7 @@ Dynamic: license-file
84
84
  [![PyPI](https://img.shields.io/pypi/v/redup)](https://pypi.org/project/redup/)
85
85
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
86
86
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
87
- [![Version](https://img.shields.io/badge/version-0.3.27-green.svg)](https://pypi.org/project/redup/)
87
+ [![Version](https://img.shields.io/badge/version-0.3.28-green.svg)](https://pypi.org/project/redup/)
88
88
 
89
89
  reDUP scans codebases for duplicated functions, blocks, and structural patterns — then builds a prioritized refactoring map that LLMs can consume to eliminate redundancy systematically.
90
90
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes