redup 0.4.32__tar.gz → 0.4.35__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.
- {redup-0.4.32/src/redup.egg-info → redup-0.4.35}/PKG-INFO +7 -5
- {redup-0.4.32 → redup-0.4.35}/README.md +6 -4
- {redup-0.4.32 → redup-0.4.35}/pyproject.toml +1 -1
- {redup-0.4.32 → redup-0.4.35}/src/redup/__init__.py +1 -1
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/models.py +7 -9
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_filters.py +28 -3
- {redup-0.4.32 → redup-0.4.35/src/redup.egg-info}/PKG-INFO +7 -5
- {redup-0.4.32 → redup-0.4.35}/LICENSE +0 -0
- {redup-0.4.32 → redup-0.4.35}/setup.cfg +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/__main__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/analysis_logic.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/compare_command.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/config_builder.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/fuzzy_similarity.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/intract_commands.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/main.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/output_writer.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/quality_commands.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/scan_commands.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/scan_helpers.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/cli_app/tasks_command.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/config.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/config_handler.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/cache.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/community.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/comparator.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/config.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/decision.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/differ.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/fuzzy_similarity.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/grouper.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/hash_cache.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/hasher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/lazy_grouper.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/lsh_matcher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/matcher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/pipeline/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/pipeline/duplicate_finder.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/pipeline/groups.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/pipeline/phases.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/pipeline_utils.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/planner.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/python_parser.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/refactor_advisor.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_cache.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_loader.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_models.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_types.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/scanner_utils.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/semantic.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/config.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/dispatcher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/base.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/c_family.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/dotnet.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/markup.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/php.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/query.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/ruby.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/shell.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/stylesheet.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/extractors/web.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/ts_extractor/main.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/universal_fuzzy.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/diff_helpers.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/duplicate_finders.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/function_extractor.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/hash_utils.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/core/utils/language_dispatcher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/integrations/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/integrations/intract/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/integrations/intract/adapter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/integrations/intract/policy.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/integrations/planfile_integration.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp/handlers.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp/schemas.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp/server.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp/utils.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp_server.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/mcp_server_clean.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/__init__.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/code2llm_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/enhanced_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/json_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/markdown_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/toon_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters/yaml_reporter.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/reporters.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup/utils.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup.egg-info/SOURCES.txt +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup.egg-info/dependency_links.txt +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup.egg-info/entry_points.txt +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup.egg-info/requires.txt +0 -0
- {redup-0.4.32 → redup-0.4.35}/src/redup.egg-info/top_level.txt +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_cli_import_compat.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_compare.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_e2e.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_hasher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_intent_integration.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_matcher.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_mcp_server.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_models.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_pipeline.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_planfile_integration.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_planner.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_quality_commands.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_reporters.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_scanner.py +0 -0
- {redup-0.4.32 → redup-0.4.35}/tests/test_ts_extractor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redup
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.35
|
|
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
|
|
@@ -94,16 +94,18 @@ Dynamic: license-file
|
|
|
94
94
|
[](https://pypi.org/project/redup/)
|
|
95
95
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
96
96
|
[](https://python.org)
|
|
97
|
-
[](https://pypi.org/project/redup/)
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
## AI Cost Tracking
|
|
101
101
|
|
|
102
|
-
   
|
|
103
|
+
  
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
- 🤖 **LLM usage:** $10.5256 (81 commits)
|
|
106
|
+
- 👤 **Human dev:** ~$3164 (31.6h @ $100/h, 30min dedup)
|
|
105
107
|
|
|
106
|
-
Generated on 2026-
|
|
108
|
+
Generated on 2026-07-05 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
|
|
107
109
|
|
|
108
110
|
---
|
|
109
111
|
|
|
@@ -5,16 +5,18 @@
|
|
|
5
5
|
[](https://pypi.org/project/redup/)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
[](https://python.org)
|
|
8
|
-
[](https://pypi.org/project/redup/)
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
## AI Cost Tracking
|
|
12
12
|
|
|
13
|
-
   
|
|
14
|
+
  
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
- 🤖 **LLM usage:** $10.5256 (81 commits)
|
|
17
|
+
- 👤 **Human dev:** ~$3164 (31.6h @ $100/h, 30min dedup)
|
|
16
18
|
|
|
17
|
-
Generated on 2026-
|
|
19
|
+
Generated on 2026-07-05 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
|
|
18
20
|
|
|
19
21
|
---
|
|
20
22
|
|
|
@@ -68,21 +68,19 @@ class ScanConfig:
|
|
|
68
68
|
"*.pyo",
|
|
69
69
|
"*.pyd",
|
|
70
70
|
"$py.class",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
".
|
|
77
|
-
"
|
|
71
|
+
"venv",
|
|
72
|
+
".venv",
|
|
73
|
+
"env",
|
|
74
|
+
".env",
|
|
75
|
+
"virtualenv",
|
|
76
|
+
".virtualenv",
|
|
77
|
+
"site-packages",
|
|
78
78
|
"*.egg-info",
|
|
79
79
|
"*.egg",
|
|
80
80
|
"build",
|
|
81
81
|
"dist",
|
|
82
82
|
".installer",
|
|
83
83
|
".eggs",
|
|
84
|
-
"lib",
|
|
85
|
-
"lib64",
|
|
86
84
|
"parts",
|
|
87
85
|
"sdist",
|
|
88
86
|
"var",
|
|
@@ -72,19 +72,32 @@ def _collect_target_files(config: ScanConfig) -> list[Path]:
|
|
|
72
72
|
def _collect_files(config: ScanConfig) -> list[Path]:
|
|
73
73
|
"""Collect all files to scan based on configuration.
|
|
74
74
|
|
|
75
|
-
Uses os.walk with topdown pruning to skip hidden
|
|
76
|
-
avoiding descent into .rebuild_ev/,
|
|
75
|
+
Uses os.walk with topdown pruning to skip hidden and excluded
|
|
76
|
+
directories early, avoiding descent into .rebuild_ev/, venv/,
|
|
77
|
+
node_modules/, site-packages/, etc. Without this, a populated
|
|
78
|
+
virtualenv (tens of thousands of files) gets fully walked and
|
|
79
|
+
stat'd before its files are filtered out, making every scan of a
|
|
80
|
+
repo root dramatically slower than scanning a subdirectory.
|
|
77
81
|
"""
|
|
78
82
|
if config.target_files is not None:
|
|
79
83
|
return _collect_target_files(config)
|
|
80
84
|
|
|
81
85
|
files = []
|
|
86
|
+
seen_real_paths = set()
|
|
82
87
|
ext_set = set(config.extensions)
|
|
83
88
|
exclude_patterns = tuple(config.exclude_patterns)
|
|
84
89
|
root_str = str(config.root)
|
|
85
90
|
|
|
86
91
|
for dirpath, dirnames, filenames in os.walk(root_str, topdown=True):
|
|
87
|
-
|
|
92
|
+
kept = []
|
|
93
|
+
for d in dirnames:
|
|
94
|
+
if d.startswith("."):
|
|
95
|
+
continue
|
|
96
|
+
relative_dir = _project_relative_path(Path(os.path.join(dirpath, d)), config.root)
|
|
97
|
+
if _should_exclude(relative_dir, exclude_patterns):
|
|
98
|
+
continue
|
|
99
|
+
kept.append(d)
|
|
100
|
+
dirnames[:] = kept
|
|
88
101
|
|
|
89
102
|
for filename in filenames:
|
|
90
103
|
file_path = Path(os.path.join(dirpath, filename))
|
|
@@ -96,6 +109,18 @@ def _collect_files(config: ScanConfig) -> list[Path]:
|
|
|
96
109
|
continue
|
|
97
110
|
if not config.include_tests and _is_test_file(relative_path):
|
|
98
111
|
continue
|
|
112
|
+
# Symlinks (common for sharing one canonical file across
|
|
113
|
+
# multiple deploy targets, e.g. per-board firmware entry
|
|
114
|
+
# points) resolve to the same real file. Without this,
|
|
115
|
+
# each symlink is read and hashed independently, reporting
|
|
116
|
+
# a single shared file as duplicated across every alias.
|
|
117
|
+
try:
|
|
118
|
+
real_path = file_path.resolve()
|
|
119
|
+
except OSError:
|
|
120
|
+
continue
|
|
121
|
+
if real_path in seen_real_paths:
|
|
122
|
+
continue
|
|
123
|
+
seen_real_paths.add(real_path)
|
|
99
124
|
try:
|
|
100
125
|
if file_path.stat().st_size > config.max_file_size_kb * 1024:
|
|
101
126
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redup
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.35
|
|
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
|
|
@@ -94,16 +94,18 @@ Dynamic: license-file
|
|
|
94
94
|
[](https://pypi.org/project/redup/)
|
|
95
95
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
96
96
|
[](https://python.org)
|
|
97
|
-
[](https://pypi.org/project/redup/)
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
## AI Cost Tracking
|
|
101
101
|
|
|
102
|
-
   
|
|
103
|
+
  
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
- 🤖 **LLM usage:** $10.5256 (81 commits)
|
|
106
|
+
- 👤 **Human dev:** ~$3164 (31.6h @ $100/h, 30min dedup)
|
|
105
107
|
|
|
106
|
-
Generated on 2026-
|
|
108
|
+
Generated on 2026-07-05 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
|
|
107
109
|
|
|
108
110
|
---
|
|
109
111
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|