diff-code-change-range 0.0.1__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 (30) hide show
  1. diff_code_change_range-0.0.1/PKG-INFO +386 -0
  2. diff_code_change_range-0.0.1/README.md +360 -0
  3. diff_code_change_range-0.0.1/pyproject.toml +48 -0
  4. diff_code_change_range-0.0.1/setup.cfg +4 -0
  5. diff_code_change_range-0.0.1/src/diff_code_change_range/__init__.py +17 -0
  6. diff_code_change_range-0.0.1/src/diff_code_change_range/__main__.py +7 -0
  7. diff_code_change_range-0.0.1/src/diff_code_change_range/affected_marker.py +173 -0
  8. diff_code_change_range-0.0.1/src/diff_code_change_range/cli.py +167 -0
  9. diff_code_change_range-0.0.1/src/diff_code_change_range/diff_parser.py +218 -0
  10. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/__init__.py +59 -0
  11. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/analyzer.py +555 -0
  12. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/code_slicer.py +58 -0
  13. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/differ.py +80 -0
  14. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/extractor.py +130 -0
  15. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/models.py +85 -0
  16. diff_code_change_range-0.0.1/src/diff_code_change_range/reference/scope_parser.py +79 -0
  17. diff_code_change_range-0.0.1/src/diff_code_change_range/structure_extractor.py +750 -0
  18. diff_code_change_range-0.0.1/src/diff_code_change_range/yaml_reporter.py +89 -0
  19. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/PKG-INFO +386 -0
  20. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/SOURCES.txt +28 -0
  21. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/dependency_links.txt +1 -0
  22. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/entry_points.txt +2 -0
  23. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/requires.txt +10 -0
  24. diff_code_change_range-0.0.1/src/diff_code_change_range.egg-info/top_level.txt +1 -0
  25. diff_code_change_range-0.0.1/tests/test_affected_marker.py +199 -0
  26. diff_code_change_range-0.0.1/tests/test_diff_parser.py +216 -0
  27. diff_code_change_range-0.0.1/tests/test_e2e.py +322 -0
  28. diff_code_change_range-0.0.1/tests/test_reference_extractor.py +564 -0
  29. diff_code_change_range-0.0.1/tests/test_structure_extractor.py +469 -0
  30. diff_code_change_range-0.0.1/tests/test_yaml_reporter.py +182 -0
@@ -0,0 +1,386 @@
1
+ Metadata-Version: 2.4
2
+ Name: diff-code-change-range
3
+ Version: 0.0.1
4
+ Summary: Extract affected code structures from git diff output for Java and Kotlin files
5
+ Author-email: OpenSpec <openspec@example.com>
6
+ License: MIT
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: unidiff>=0.7.0
18
+ Requires-Dist: tree-sitter>=0.20.0
19
+ Requires-Dist: tree-sitter-java>=0.20.0
20
+ Requires-Dist: tree-sitter-kotlin>=0.3.0
21
+ Requires-Dist: tree-sitter-python>=0.21.0
22
+ Requires-Dist: pyyaml>=6.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
25
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
26
+
27
+ # diff-code-change-range
28
+
29
+ Extract affected code structures from git diff output for Java, Kotlin, and Python files.
30
+
31
+ ## Overview
32
+
33
+ This tool parses `git diff --full-index -U999999` output, extracts complete before/after source code, and identifies which code structures (classes, methods, functions, members) are affected by the changes. It outputs structured YAML showing affected code structures for both before and after versions.
34
+
35
+ Additionally, the tool can extract **reference relationships** between affected nodes (method calls, field accesses, type references, etc.) to support impact analysis and precise code review.
36
+
37
+ ## Installation
38
+
39
+ ### From PyPI
40
+
41
+ ```bash
42
+ pip install diff-code-change-range
43
+ ```
44
+
45
+ ### From Source
46
+
47
+ ```bash
48
+ git clone <repository>
49
+ cd diff-code-change-range
50
+ pip install -e .
51
+ ```
52
+
53
+ ### Requirements
54
+
55
+ - Python 3.9 or higher
56
+ - Dependencies:
57
+ - `unidiff>=0.7.0` - Parse unified diff format
58
+ - `tree-sitter>=0.20.0` - Parse source code
59
+ - `tree-sitter-java>=0.20.0` - Java grammar for tree-sitter
60
+ - `tree-sitter-kotlin>=0.3.0` - Kotlin grammar for tree-sitter
61
+ - `tree-sitter-python>=0.21.0` - Python grammar for tree-sitter
62
+ - `pyyaml>=6.0` - YAML output
63
+
64
+ ## Usage
65
+
66
+ ### Basic Usage
67
+
68
+ Read diff from stdin:
69
+
70
+ ```bash
71
+ git diff --full-index -U999999 | diff-code-change-range
72
+ ```
73
+
74
+ Read diff from file:
75
+
76
+ ```bash
77
+ diff-code-change-range path/to/diff.patch
78
+ ```
79
+
80
+ ### CLI Arguments
81
+
82
+ ```
83
+ diff-code-change-range [-h] [-v] [diff_file]
84
+
85
+ Positional Arguments:
86
+ diff_file Path to diff file (default: read from stdin)
87
+
88
+ Optional Arguments:
89
+ -h, --help Show help message and exit
90
+ -v, --version Show version and exit
91
+ ```
92
+
93
+ ### Example Usage
94
+
95
+ ```bash
96
+ # Generate diff with full context and pipe to tool
97
+ git diff --full-index -U999999 HEAD~1 | diff-code-change-range
98
+
99
+ # Save output to file
100
+ git diff --full-index -U999999 > changes.patch
101
+ diff-code-change-range changes.patch > analysis.yaml
102
+
103
+ # Use as Python module
104
+ python -m diff_code_change_range < changes.patch
105
+ ```
106
+
107
+ ### Python Example
108
+
109
+ Input Python file:
110
+ ```python
111
+ class Calculator:
112
+ def __init__(self):
113
+ self.result = 0
114
+
115
+ @classmethod
116
+ def create(cls):
117
+ return cls()
118
+
119
+ async def compute(self):
120
+ return self.result
121
+
122
+ def main():
123
+ calc = Calculator()
124
+ ```
125
+
126
+ Output structure:
127
+ ```yaml
128
+ before: []
129
+ after:
130
+ - name: calculator.py
131
+ type: file
132
+ line_range: [1, 13]
133
+ children:
134
+ - name: Calculator
135
+ type: class
136
+ line_range: [1, 10]
137
+ children:
138
+ - name: __init__
139
+ type: method
140
+ line_range: [2, 3]
141
+ children:
142
+ - name: result
143
+ type: member
144
+ line_range: [3, 3]
145
+ - name: "@classmethod create"
146
+ type: method
147
+ line_range: [5, 6]
148
+ - name: async compute
149
+ type: method
150
+ line_range: [8, 9]
151
+ - name: main
152
+ type: function
153
+ line_range: [12, 13]
154
+ ```
155
+
156
+ ### Reference Extraction
157
+
158
+ The `reference` module can extract relationships between affected code nodes:
159
+
160
+ ```python
161
+ from diff_code_change_range.reference import extract_references, AffectedScope, AffectedNode, NodeType
162
+
163
+ before_code = {
164
+ "com/example/Service.kt": '''
165
+ class Service {
166
+ fun process() {
167
+ validate()
168
+ }
169
+ fun validate(): Boolean {
170
+ return true
171
+ }
172
+ }
173
+ '''
174
+ }
175
+
176
+ after_code = {...} # After version
177
+
178
+ scope = AffectedScope(
179
+ before=[...], # AffectedNode tree
180
+ after=[...]
181
+ )
182
+
183
+ result = extract_references(before_code, after_code, scope)
184
+
185
+ # Access references
186
+ for ref in result.before_references:
187
+ print(f"{ref.source} -> {ref.target} ({ref.type.value})")
188
+
189
+ # See what changed
190
+ for ref in result.added_references:
191
+ print(f"Added: {ref.source} -> {ref.target}")
192
+ ```
193
+
194
+ Supported reference types:
195
+ - `method_call` - Method or function invocation
196
+ - `field_access` - Field or property access
197
+ - `type_reference` - Type usage in declarations
198
+ - `instantiation` - Object creation
199
+ - `annotation` - Annotation usage
200
+ - `inheritance` - Class extends another class
201
+ - `implementation` - Class implements interface
202
+
203
+ ## Output Format
204
+
205
+ The tool outputs YAML with `before` and `after` root keys:
206
+
207
+ ```yaml
208
+ before:
209
+ - name: src/Calculator.java
210
+ type: file
211
+ line_range: [1, 15]
212
+ children:
213
+ - name: Calculator
214
+ type: class
215
+ line_range: [1, 14]
216
+ children:
217
+ - name: add
218
+ type: method
219
+ line_range: [5, 7]
220
+
221
+ after:
222
+ - name: src/Calculator.java
223
+ type: file
224
+ line_range: [1, 15]
225
+ children:
226
+ - name: Calculator
227
+ type: class
228
+ line_range: [1, 14]
229
+ children:
230
+ - name: add
231
+ type: method
232
+ line_range: [5, 7]
233
+ ```
234
+
235
+ ### Node Types
236
+
237
+ - `file` - Source file
238
+ - `class` - Class declaration
239
+ - `interface` - Interface declaration
240
+ - `object` - Kotlin object declaration
241
+ - `enum` - Enum declaration
242
+ - `function` - Top-level function (Kotlin, Python)
243
+ - `method` - Class method
244
+ - `member` - Field/property, class variable, instance variable
245
+ - `variable` - Module-level variable (Python)
246
+
247
+ ### Node Fields
248
+
249
+ - `name` - The name of the code element
250
+ - `type` - The type of node (see above)
251
+ - `line_range` - Array of [start_line, end_line] (1-based, inclusive)
252
+ - `children` - List of child nodes (for container types)
253
+
254
+ ## Example
255
+
256
+ ### Input Diff
257
+
258
+ ```diff
259
+ diff --git a/src/Calculator.java b/src/Calculator.java
260
+ index abc123..def456 100644
261
+ --- a/src/Calculator.java
262
+ +++ b/src/Calculator.java
263
+ @@ -1,8 +1,8 @@
264
+ public class Calculator {
265
+ private int result;
266
+
267
+ - public void add(int a) {
268
+ - result += a;
269
+ + public void add(int a, int b) {
270
+ + result = a + b;
271
+ }
272
+
273
+ public int getResult() {
274
+ ```
275
+
276
+ ### Output
277
+
278
+ ```yaml
279
+ before:
280
+ - name: src/Calculator.java
281
+ type: file
282
+ line_range: [1, 8]
283
+ children:
284
+ - name: Calculator
285
+ type: class
286
+ line_range: [1, 8]
287
+ children:
288
+ - name: add
289
+ type: method
290
+ line_range: [4, 6]
291
+
292
+ after:
293
+ - name: src/Calculator.java
294
+ type: file
295
+ line_range: [1, 8]
296
+ children:
297
+ - name: Calculator
298
+ type: class
299
+ line_range: [1, 8]
300
+ children:
301
+ - name: add
302
+ type: method
303
+ line_range: [4, 6]
304
+ ```
305
+
306
+ ## Development
307
+
308
+ ### Setup Development Environment
309
+
310
+ ```bash
311
+ # Create virtual environment
312
+ python -m venv venv
313
+ source venv/bin/activate
314
+
315
+ # Install in development mode
316
+ pip install -e ".[dev]"
317
+ ```
318
+
319
+ ### Running Tests
320
+
321
+ ```bash
322
+ # Run all tests
323
+ pytest
324
+
325
+ # Run with coverage
326
+ pytest --cov=diff_code_change_range
327
+
328
+ # Run specific test file
329
+ pytest tests/test_diff_parser.py
330
+ ```
331
+
332
+ ### Project Structure
333
+
334
+ ```
335
+ .
336
+ ├── src/
337
+ │ └── diff_code_change_range/
338
+ │ ├── __init__.py # Package exports
339
+ │ ├── __main__.py # Module entry point
340
+ │ ├── cli.py # CLI implementation
341
+ │ ├── diff_parser.py # Diff parsing module
342
+ │ ├── structure_extractor.py # Tree-sitter code parsing
343
+ │ ├── affected_marker.py # Affected node detection
344
+ │ └── yaml_reporter.py # YAML output generation
345
+ ├── tests/
346
+ │ ├── fixtures/ # Test diff files
347
+ │ ├── test_diff_parser.py
348
+ │ ├── test_structure_extractor.py
349
+ │ ├── test_affected_marker.py
350
+ │ ├── test_yaml_reporter.py
351
+ │ └── test_e2e.py
352
+ ├── pyproject.toml
353
+ ├── requirements.txt
354
+ ├── requirements-dev.txt
355
+ └── README.md
356
+ ```
357
+
358
+ ## Supported Languages
359
+
360
+ - **Java** (`.java` files) - Full support for classes, interfaces, enums, methods, fields
361
+ - **Kotlin** (`.kt` files) - Full support for classes, objects, functions, properties
362
+ - **Python** (`.py` files) - Full support for classes, functions, methods, decorators, async functions, module-level and instance variables
363
+
364
+ Other file types are automatically skipped.
365
+
366
+ ## Error Handling
367
+
368
+ The tool handles various error conditions gracefully:
369
+
370
+ - **Parse errors** - Files that fail to parse are skipped with a warning to stderr
371
+ - **Binary files** - Automatically detected and skipped
372
+ - **Non-Java/Kotlin/Python files** - Silently skipped
373
+ - **Empty diffs** - Produce empty output
374
+
375
+ Exit codes:
376
+ - `0` - Success
377
+ - `1` - Error (file not found, parse error, etc.)
378
+ - `130` - Interrupted (Ctrl+C)
379
+
380
+ ## License
381
+
382
+ MIT License
383
+
384
+ ## Contributing
385
+
386
+ Contributions are welcome! Please ensure tests pass before submitting pull requests.