Skip to content

Commit

Permalink
refactor: improve code quality and documentation (v0.1.6)
Browse files Browse the repository at this point in the history
- Add comprehensive docstrings with Examples sections

- Add proper type hints for all functions and classes

- Add Raises sections in docstrings for error handling

- Improve error handling with custom exceptions

- Enhance code organization and module structure

- Update project structure to use flat directory layout

- Improve README with current project structure and standards
  • Loading branch information
mikewcasale committed Dec 17, 2024
1 parent 7147eda commit 4aa69db
Show file tree
Hide file tree
Showing 19 changed files with 1,363 additions and 858 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.6] - 2024-12-15

### Changed
- Improved code quality and documentation:
- Added comprehensive docstrings with Examples sections
- Added proper type hints for all functions and classes
- Added Raises sections in docstrings for error handling
- Improved error handling with custom exceptions
- Enhanced code organization and module structure
- Updated project structure to use flat directory layout
- Improved README with current project structure and standards

### Fixed
- Function and method signatures in docstrings
- Error handling in dependency management
- Type hints in graph building and analysis
- Code formatting and consistency

## [0.1.5] - 2024-12-14

### Added
Expand Down Expand Up @@ -68,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Restructured project to use src/ directory layout
- Updated package metadata and documentation

[0.1.6]: https://github.com/mikewcasale/repominify/compare/v0.1.5...v0.1.6
[0.1.5]: https://github.com/mikewcasale/repominify/compare/v0.1.4...v0.1.5
[0.1.4]: https://github.com/mikewcasale/repominify/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/mikewcasale/repominify/compare/v0.1.2...v0.1.3
Expand Down
71 changes: 27 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,46 +163,37 @@ When you run repominify, it generates several files in your output directory:

```
repominify/
├── src/ # Source code
│ ├── core/ # Core functionality
│ │ ├── graph.py # Graph building and analysis
│ │ ├── parser.py # Repomix file parsing
│ │ └── types.py # Shared types and data structures
│ ├── io/ # Input/Output operations
│ │ ├── exporters.py # Graph export functionality
│ │ └── formatters.py # Text representation formatting
│ ├── utils/ # Utility modules
│ │ ├── dependency_checker.py # Dependency management
│ │ ├── logging.py # Logging configuration
│ │ └── stats.py # Statistics and comparison
│ ├── cli.py # Command-line interface
│ └── __init__.py # Package initialization
├── tests/ # Test suite
│ ├── test_end2end.py # End-to-end tests
├── repominify/ # Source code
│ ├── graph.py # Graph building and analysis
│ ├── parser.py # Repomix file parsing
│ ├── types.py # Core types and data structures
│ ├── exporters.py # Graph export functionality
│ ├── formatters.py # Text representation formatting
│ ├── dependencies.py # Dependency management
│ ├── logging.py # Logging configuration
│ ├── stats.py # Statistics and comparison
│ ├── constants.py # Shared constants
│ ├── exceptions.py # Custom exceptions
│ ├── cli.py # Command-line interface
│ └── __init__.py # Package initialization
├── tests/ # Test suite
│ ├── test_end2end.py # End-to-end tests
│ └── data/ # Test data files
├── setup.py # Package configuration
├── pyproject.toml # Build system requirements
├── LICENSE # MIT License
└── README.md # This file
├── setup.py # Package configuration
├── LICENSE # MIT License
└── README.md # This file
```

## Performance
## Code Style

repominify is designed to handle large codebases efficiently:
The project follows these coding standards for consistency and maintainability:

- Memory usage scales linearly with codebase size
- File I/O is buffered for efficiency
- Graph operations are optimized
- Performance statistics available in debug mode

## Error Handling

The package provides detailed error messages and proper error boundaries:

- Dependency errors (Node.js, npm, Repomix)
- File parsing errors
- Graph building errors
- Export errors
- Comprehensive docstrings with Examples sections for all public APIs
- Type hints for all functions, methods, and class attributes
- Custom exceptions for proper error handling and reporting
- Clear separation of concerns between modules
- Consistent code formatting and naming conventions
- Detailed logging with configurable debug support

## Development

Expand All @@ -224,7 +215,7 @@ pytest tests/

Contributions are welcome! Please feel free to submit a Pull Request. By contributing to this project, you agree to abide by its terms.

This project has adopted the [Python Style Guide](STYLEGUIDE.md) for consistency and maintainability.
Please ensure your code follows the project's coding standards, including proper docstrings, type hints, and error handling.

## Authors

Expand All @@ -246,17 +237,9 @@ This project makes use of or was influenced by several excellent open source pro
- [PyYAML](https://pyyaml.org/) - YAML file handling
- [GraphRAG Accelerator](https://github.com/Azure-Samples/graphrag-accelerator) - Graph-based code analysis patterns and implementation concepts

## Disclaimer

This project is not an officially supported product. It is provided as-is, without warranty or support. Users should evaluate its suitability for their use case and understand the implications of deep code analysis on their systems.

## How to Get Help

- For bugs and feature requests, please [open an issue](https://github.com/mikewcasale/repominify/issues)
- For usage questions, please [start a discussion](https://github.com/mikewcasale/repominify/discussions)
- For security concerns, please email [email protected] directly

## Trademarks

Any trademarks or registered trademarks mentioned in this project are the property of their respective owners.

12 changes: 8 additions & 4 deletions repominify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""
repominify - Optimize codebase representations for LLMs
Author: Mike Casale
Email: [email protected]
GitHub: https://github.com/mikewcasale
"""

__version__ = "0.1.5"
__version__ = "0.1.6"
__author__ = "Mike Casale"
__email__ = "[email protected]"

from .core.graph import CodeGraphBuilder
from .utils.dependency_checker import ensure_dependencies
from .utils.logging import configure_logging
from .graph import CodeGraphBuilder
from .dependencies import ensure_dependencies
from .logging import configure_logging

__all__ = ["CodeGraphBuilder", "ensure_dependencies", "configure_logging"]
118 changes: 55 additions & 63 deletions repominify/cli.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
"""Command-line interface for repo-minify.
This module provides the main entry point for the repo-minify command-line tool.
Author: Mike Casale
Email: [email protected]
GitHub: https://github.com/mikewcasale
Error Handling:
- Dependency errors are reported with clear instructions
- File access errors include path information
- Graph building errors show detailed context
- All errors are logged with debug info when --debug is enabled
Performance:
- Memory usage scales with input file size
- Progress feedback for long operations
- Graceful handling of large files
Version Compatibility:
- Python 3.7+: Full support
- Type hints: Required for static analysis
"""

from __future__ import annotations
Expand All @@ -28,24 +9,23 @@
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import NoReturn, Optional, Final

from .core.graph import CodeGraphBuilder
from .utils.logging import configure_logging, get_logger
from .utils.dependency_checker import ensure_dependencies
from .core.types import GraphBuildError, FileParseError, ValidationError
from typing import NoReturn, Optional

from .graph import CodeGraphBuilder
from .logging import configure_logging, get_logger
from .dependencies import ensure_dependencies
from .exceptions import GraphBuildError, FileParseError, ValidationError
from .constants import (
EXIT_SUCCESS,
EXIT_GENERAL_ERROR,
EXIT_FILE_NOT_FOUND,
EXIT_PERMISSION_ERROR,
EXIT_PARSE_ERROR,
EXIT_GRAPH_ERROR,
)

# Configure logging
logger = get_logger(__name__)

# Exit codes
EXIT_SUCCESS: Final[int] = 0
EXIT_GENERAL_ERROR: Final[int] = 1
EXIT_FILE_NOT_FOUND: Final[int] = 2
EXIT_PERMISSION_ERROR: Final[int] = 3
EXIT_PARSE_ERROR: Final[int] = 4
EXIT_GRAPH_ERROR: Final[int] = 5


@dataclass
class CliOptions:
Expand All @@ -56,33 +36,46 @@ class CliOptions:
output_dir: Directory for analysis output files
debug: Whether to enable debug logging
Example:
Raises:
ValueError: If input_file or output_dir is empty
Examples::
>>> opts = CliOptions(Path("input.txt"), Path("output"), debug=True)
>>> print(opts.input_file)
input.txt
>>> str(opts.input_file)
'input.txt'
"""

# Required fields
input_file: Path
output_dir: Path

# Optional fields with defaults
debug: bool = False

def __post_init__(self) -> None:
"""Validate CLI options.
Raises:
ValueError: If input_file or output_dir is empty
"""
if not str(self.input_file).strip():
raise ValueError("Input file path cannot be empty")
if not str(self.output_dir).strip():
raise ValueError("Output directory path cannot be empty")


def parse_args() -> CliOptions:
"""Parse command-line arguments.
Returns:
CliOptions containing validated arguments
Example:
>>> args = parse_args()
>>> print(f"Processing {args.input_file}")
Processing repomix-output.txt
Raises:
SystemExit: If invalid arguments are provided
Note:
Uses argparse's built-in help and error handling
Examples::
>>> import sys
>>> sys.argv = ["repo-minify", "input.txt", "-o", "output"]
>>> args = parse_args()
>>> str(args.input_file)
'input.txt'
"""
parser = argparse.ArgumentParser(
description="Analyze and minify code repository structure using Repomix.",
Expand Down Expand Up @@ -122,15 +115,15 @@ def handle_error(error: Exception, debug: bool) -> NoReturn:
error: The exception to handle
debug: Whether debug mode is enabled
Note:
Always exits the program with an appropriate status code
Raises:
Exception: Re-raises the original error if in debug mode
Exit Codes:
1: General error
2: File not found
3: Permission denied
4: Parse error
5: Graph build error
Examples::
>>> try:
... raise FileNotFoundError("test.txt")
... except Exception as e:
... handle_error(e, debug=False)
Error: File not found: test.txt
"""
if isinstance(error, FileNotFoundError):
print(f"Error: File not found: {error.filename}", file=sys.stderr)
Expand All @@ -157,16 +150,15 @@ def main() -> int:
Returns:
Exit code (0 for success, non-zero for error)
Exit Codes:
0: Success
1: General error
2: File not found
3: Permission denied
4: Parse error
5: Graph build error
Raises:
SystemExit: With appropriate exit code on error
Exception: Any unhandled exceptions in debug mode
Example:
>>> sys.exit(main()) # Run the CLI
Examples::
>>> import sys
>>> sys.argv = ["repo-minify", "--help"]
>>> main() # doctest: +SKIP
0
"""
try:
# Parse arguments
Expand Down
61 changes: 61 additions & 0 deletions repominify/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Constants used throughout the repo-minify package.
This module centralizes all constant values used across different modules.
Attributes:
EXIT_SUCCESS: Exit code for successful execution (0)
EXIT_GENERAL_ERROR: Exit code for general errors (1)
EXIT_FILE_NOT_FOUND: Exit code for file not found errors (2)
EXIT_PERMISSION_ERROR: Exit code for permission errors (3)
EXIT_PARSE_ERROR: Exit code for parsing errors (4)
EXIT_GRAPH_ERROR: Exit code for graph building errors (5)
NODE_TYPES: Mapping of node types to their display colors
CONSTANT_PATTERNS: Regular expressions for identifying constants
SUSPICIOUS_PATTERNS: Set of security-sensitive pattern strings
Examples::
>>> from repominify.constants import NODE_TYPES
>>> NODE_TYPES["module"]
'#A5D6A7'
"""

from __future__ import annotations

from typing import Dict, List, Set, Final

# Exit codes
EXIT_SUCCESS: Final[int] = 0
EXIT_GENERAL_ERROR: Final[int] = 1
EXIT_FILE_NOT_FOUND: Final[int] = 2
EXIT_PERMISSION_ERROR: Final[int] = 3
EXIT_PARSE_ERROR: Final[int] = 4
EXIT_GRAPH_ERROR: Final[int] = 5

# Node type constants with color codes
NODE_TYPES: Final[Dict[str, str]] = {
"module": "#A5D6A7", # Light green
"class": "#90CAF9", # Light blue
"function": "#FFCC80", # Light orange
"import": "#CE93D8", # Light purple
"constant": "#FFB74D", # Orange
"env_var": "#81C784", # Green
}

# Regular expression patterns for identifying constants
CONSTANT_PATTERNS: Final[List[str]] = [
r"^[A-Z][A-Z0-9_]*$", # All caps with underscores
r"__[a-zA-Z0-9_]+__", # Dunder names
r"Final\[[^]]+\]", # Type hints with Final
]

# Security-sensitive patterns to detect
SUSPICIOUS_PATTERNS: Final[Set[str]] = {
"password",
"secret",
"token",
"api_key",
"private_key",
"ssh_key",
"credentials",
"auth",
}
Loading

0 comments on commit 4aa69db

Please sign in to comment.