├── .gitignore ├── LICENSE ├── README.md ├── codemapper ├── __init__.py ├── cli.py ├── parser.py ├── traverser.py └── utils.py ├── newmap.txt ├── prompt.txt ├── setup.py └── tests ├── __init__.py └── test_codemapper.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 110 | .pdm.toml 111 | .pdm-python 112 | .pdm-build/ 113 | 114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 115 | __pypackages__/ 116 | 117 | # Celery stuff 118 | celerybeat-schedule 119 | celerybeat.pid 120 | 121 | # SageMath parsed files 122 | *.sage.py 123 | 124 | # Environments 125 | .env 126 | .venv 127 | env/ 128 | venv/ 129 | ENV/ 130 | env.bak/ 131 | venv.bak/ 132 | 133 | # Spyder project settings 134 | .spyderproject 135 | .spyproject 136 | 137 | # Rope project settings 138 | .ropeproject 139 | 140 | # mkdocs documentation 141 | /site 142 | 143 | # mypy 144 | .mypy_cache/ 145 | .dmypy.json 146 | dmypy.json 147 | 148 | # Pyre type checker 149 | .pyre/ 150 | 151 | # pytype static type analyzer 152 | .pytype/ 153 | 154 | # Cython debug symbols 155 | cython_debug/ 156 | 157 | # PyCharm 158 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 159 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 160 | # and can be added to the global gitignore or merged into this file. For a more nuclear 161 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 162 | #.idea/ 163 | .envrc 164 | output.json 165 | .DS_Store 166 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Mike Bee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeMapper 2 | 3 | CodeMapper is a tool designed to map code repositories for Large Language Model (LLM) editing. It traverses your codebase, extracts key information, and creates a JSON representation that can be easily consumed by LLMs for various code analysis and modification tasks. 4 | 5 | ## Features 6 | 7 | - Traverse entire code repositories 8 | - Extract information from Python files, including: 9 | - Docstrings 10 | - Function definitions and signatures 11 | - Class definitions and methods 12 | - Import statements 13 | - Handle non-Python files by providing basic file information 14 | - Respect `.gitignore` patterns to exclude irrelevant files 15 | - Automatically exclude `.git` directories and `.DS_Store` files 16 | - Generate a comprehensive JSON map of the repository 17 | 18 | Note: You can exclude more directories by adding them to .gitignore or adding them to the 19 | traverser.py file. 20 | 21 | ## Installation 22 | 23 | You can install CodeMapper directly from GitHub using pip: 24 | 25 | ```sh 26 | pip install git+https://github.com/MikeyBeez/codemapper.git 27 | ``` 28 | 29 | ## Usage 30 | 31 | To use CodeMapper, run the following command in your terminal: 32 | 33 | ```sh 34 | codemapper /path/to/repo /path/to/.gitignore output.json 35 | ``` 36 | 37 | - `/path/to/repo`: The root directory of the repository you want to map 38 | - `/path/to/.gitignore`: The path to the .gitignore file to use for excluding files 39 | - `output.json`: The name of the output file where the JSON map will be saved 40 | 41 | ### Example 42 | 43 | ```sh 44 | codemapper /Users/username/Projects/my-project /Users/username/Projects/my-project/.gitignore my-project-map.json 45 | ``` 46 | 47 | This command will analyze the `my-project` repository, respect the rules in its `.gitignore` file, and save the resulting map to `my-project-map.json`. 48 | 49 | ### Output 50 | 51 | The tool generates a JSON file containing: 52 | 53 | - File paths and types 54 | - For Python files: 55 | - Docstrings 56 | - Function definitions and signatures 57 | - Class definitions and methods 58 | - Import statements 59 | - For non-Python files: 60 | - Basic file information (path, type, size) 61 | 62 | Note: `.git` directories and `.DS_Store` files are automatically excluded from the output. 63 | 64 | ## Project Structure 65 | 66 | - `src/codemapper/`: Main package directory 67 | - `cli.py`: Command-line interface implementation 68 | - `parser.py`: Code for parsing Python files and extracting information 69 | - `traverser.py`: Repository traversal logic 70 | - `utils.py`: Utility functions for creating the code map 71 | - `tests/`: Directory containing test files 72 | - `setup.py`: Package and distribution management 73 | - `LICENSE`: MIT License file 74 | 75 | ## Contributing 76 | 77 | Contributions to CodeMapper are welcome! Here's how you can contribute: 78 | 79 | 1. Fork the repository 80 | 2. Create a new branch (`git checkout -b feature/amazing-feature`) 81 | 3. Make your changes 82 | 4. Commit your changes (`git commit -m 'Add some amazing feature'`) 83 | 5. Push to the branch (`git push origin feature/amazing-feature`) 84 | 6. Open a Pull Request 85 | 86 | Please make sure to update tests as appropriate and adhere to the project's coding standards. 87 | 88 | ## License 89 | 90 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. 91 | 92 | ## Contact 93 | 94 | If you have any questions or feedback, please open an issue on the GitHub repository. 95 | 96 | Thank you for using or contributing to CodeMapper! 97 | -------------------------------------------------------------------------------- /codemapper/__init__.py: -------------------------------------------------------------------------------- 1 | from . import cli, parser, traverser, utils 2 | 3 | __all__ = ['cli', 'parser', 'traverser', 'utils'] 4 | 5 | -------------------------------------------------------------------------------- /codemapper/cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | from .utils import create_map 4 | 5 | def main(): 6 | parser = argparse.ArgumentParser(description='Map a code repository for LLM editing.') 7 | parser.add_argument('root_dir', help='The root directory of the repository.') 8 | parser.add_argument('ignore_file', help='The .ignore file to use.') 9 | parser.add_argument('output_file', help='The output file to save the map.') 10 | 11 | args = parser.parse_args() 12 | 13 | try: 14 | code_map = create_map(args.root_dir, args.ignore_file) 15 | 16 | with open(args.output_file, 'w') as f: 17 | json.dump(code_map, f, indent=4) 18 | 19 | print(f"Code map successfully written to {args.output_file}") 20 | print("\nVersion Information:") 21 | print(f"Python: {code_map['version_info']['python']}") 22 | print(f"CodeMapper: {code_map['version_info']['codemapper']}") 23 | print("\nDependencies:") 24 | for dep, version in code_map['version_info']['dependencies'].items(): 25 | print(f"{dep}: {version}") 26 | 27 | print(f"\nTotal files processed: {len(code_map['files'])}") 28 | print("Files with content included:") 29 | for file_info in code_map['files']: 30 | if 'content' in file_info: 31 | print(f"- {file_info['path']}") 32 | 33 | except Exception as e: 34 | print(f"An error occurred: {str(e)}") 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /codemapper/parser.py: -------------------------------------------------------------------------------- 1 | import ast 2 | import os 3 | 4 | def extract_info(file_path): 5 | """ 6 | Extracts information from a file. For Python files, it includes docstrings, function signatures, 7 | class names, and import statements. For non-Python files, it includes basic file information. 8 | 9 | Args: 10 | file_path (str): The path to the file. 11 | 12 | Returns: 13 | dict: A dictionary containing the extracted information. 14 | """ 15 | file_info = { 16 | "path": file_path, 17 | "type": "unknown", 18 | "size": os.path.getsize(file_path) 19 | } 20 | 21 | # If it's a Python file, extract detailed information 22 | if file_path.endswith('.py'): 23 | file_info["type"] = "python" 24 | try: 25 | with open(file_path, 'r', encoding='utf-8') as f: 26 | file_content = f.read() 27 | 28 | tree = ast.parse(file_content) 29 | file_info["docstring"] = ast.get_docstring(tree) 30 | file_info["functions"] = [] 31 | file_info["classes"] = [] 32 | file_info["imports"] = [] 33 | 34 | for node in ast.walk(tree): 35 | if isinstance(node, ast.FunctionDef): 36 | file_info["functions"].append({ 37 | "name": node.name, 38 | "signature": ast.dump(node), 39 | "docstring": ast.get_docstring(node) 40 | }) 41 | elif isinstance(node, ast.ClassDef): 42 | class_info = { 43 | "name": node.name, 44 | "docstring": ast.get_docstring(node), 45 | "methods": [] 46 | } 47 | for method in node.body: 48 | if isinstance(method, ast.FunctionDef): 49 | class_info["methods"].append({ 50 | "name": method.name, 51 | "signature": ast.dump(method), 52 | "docstring": ast.get_docstring(method) 53 | }) 54 | file_info["classes"].append(class_info) 55 | elif isinstance(node, (ast.Import, ast.ImportFrom)): 56 | file_info["imports"].append(ast.dump(node)) 57 | 58 | except Exception as e: 59 | print(f"Error processing Python file {file_path}: {str(e)}") 60 | else: 61 | # For non-Python files, just include the file extension as the type 62 | file_info["type"] = os.path.splitext(file_path)[1][1:] or "unknown" 63 | 64 | return file_info 65 | -------------------------------------------------------------------------------- /codemapper/traverser.py: -------------------------------------------------------------------------------- 1 | import os 2 | import fnmatch 3 | 4 | def read_ignore_file(ignore_file): 5 | """ 6 | Reads and parses the .ignore file to get a list of patterns to ignore. 7 | 8 | Args: 9 | ignore_file (str): The path to the .ignore file. 10 | 11 | Returns: 12 | list: A list of ignore patterns. 13 | """ 14 | with open(ignore_file, 'r') as f: 15 | ignore_patterns = f.readlines() 16 | 17 | ignore_patterns = [pattern.strip() for pattern in ignore_patterns 18 | if pattern.strip() and not pattern.strip().startswith('#')] 19 | 20 | return ignore_patterns 21 | 22 | def should_ignore(file_path, ignore_patterns, root_dir): 23 | """ 24 | Checks if a file should be ignored based on the ignore patterns. 25 | 26 | Args: 27 | file_path (str): The path to the file. 28 | ignore_patterns (list): A list of ignore patterns. 29 | root_dir (str): The root directory of the repository. 30 | 31 | Returns: 32 | bool: True if the file should be ignored, False otherwise. 33 | """ 34 | relative_path = os.path.relpath(file_path, root_dir) 35 | 36 | # Always ignore .git directory, .DS_Store files, output.json, and .gitignore 37 | if '.git' in relative_path.split(os.sep) or \ 38 | os.path.basename(file_path) in ['.DS_Store', 'output.json', '.gitignore']: 39 | return True 40 | 41 | for pattern in ignore_patterns: 42 | if pattern.endswith('/'): 43 | if fnmatch.fnmatch(relative_path + '/', pattern) or \ 44 | fnmatch.fnmatch(relative_path, pattern[:-1] + '/*'): 45 | return True 46 | elif fnmatch.fnmatch(relative_path, pattern): 47 | return True 48 | return False 49 | 50 | def traverse_repository(root_dir, ignore_patterns): 51 | """ 52 | Recursively traverses the repository directory, excluding files and directories 53 | mentioned in the ignore patterns. 54 | 55 | Args: 56 | root_dir (str): The root directory of the repository. 57 | ignore_patterns (list): A list of ignore patterns. 58 | 59 | Yields: 60 | str: The path to each file that should not be ignored. 61 | """ 62 | for dirpath, dirnames, filenames in os.walk(root_dir): 63 | # Remove .git directory from dirnames to prevent recursing into it 64 | if '.git' in dirnames: 65 | dirnames.remove('.git') 66 | 67 | # Remove .DS_Store and .gitignore from filenames 68 | filenames = [f for f in filenames if f not in ['.DS_Store', '.gitignore']] 69 | 70 | dirnames[:] = [d for d in dirnames if not should_ignore(os.path.join(dirpath, d), ignore_patterns, root_dir)] 71 | 72 | for filename in filenames: 73 | file_path = os.path.join(dirpath, filename) 74 | if not should_ignore(file_path, ignore_patterns, root_dir): 75 | yield file_path 76 | -------------------------------------------------------------------------------- /codemapper/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import pkg_resources 4 | from .traverser import read_ignore_file, traverse_repository 5 | from .parser import extract_info 6 | 7 | def get_file_content(file_path, max_size=100 * 1024): # 100 KB 8 | """ 9 | Get the content of a file if it's smaller than max_size. 10 | 11 | Args: 12 | file_path (str): Path to the file. 13 | max_size (int): Maximum file size in bytes to read. 14 | 15 | Returns: 16 | str or None: File content if file is small enough, else None. 17 | """ 18 | if os.path.getsize(file_path) <= max_size: 19 | with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: 20 | return f.read() 21 | return None 22 | 23 | def get_version_info(): 24 | """ 25 | Get version information for the project and its dependencies. 26 | 27 | Returns: 28 | dict: Version information. 29 | """ 30 | version_info = { 31 | 'python': sys.version, 32 | 'codemapper': pkg_resources.get_distribution('codemapper').version, 33 | 'dependencies': {} 34 | } 35 | for dist in pkg_resources.working_set: 36 | version_info['dependencies'][dist.key] = dist.version 37 | return version_info 38 | 39 | def is_config_file(file_path): 40 | """ 41 | Check if a file is a configuration file. 42 | 43 | Args: 44 | file_path (str): Path to the file. 45 | 46 | Returns: 47 | bool: True if it's a config file, False otherwise. 48 | """ 49 | config_extensions = ['.ini', '.cfg', '.conf', '.json', '.yaml', '.yml', '.toml'] 50 | config_names = ['setup.py', 'requirements.txt', 'Pipfile', 'pyproject.toml'] 51 | return (os.path.splitext(file_path)[1] in config_extensions or 52 | os.path.basename(file_path) in config_names) 53 | 54 | def create_map(root_dir, ignore_file): 55 | """ 56 | Creates a map of the code repository, including information about each file. 57 | 58 | Args: 59 | root_dir (str): The root directory of the repository. 60 | ignore_file (str): The path to the .ignore file. 61 | 62 | Returns: 63 | dict: A dictionary containing the map of the code repository. 64 | """ 65 | ignore_patterns = read_ignore_file(ignore_file) 66 | file_paths = traverse_repository(root_dir, ignore_patterns) 67 | code_map = { 68 | "files": [], 69 | "version_info": get_version_info() 70 | } 71 | 72 | for file_path in file_paths: 73 | # Skip .gitignore file 74 | if os.path.basename(file_path) == '.gitignore': 75 | continue 76 | 77 | file_info = extract_info(file_path) 78 | if file_info is not None: 79 | # Include file content for README.md 80 | if os.path.basename(file_path).lower() == 'readme.md': 81 | file_info['content'] = get_file_content(file_path) 82 | 83 | # Include full content for configuration files 84 | elif is_config_file(file_path): 85 | file_info['content'] = get_file_content(file_path) 86 | 87 | # For other files, include content if they're small 88 | else: 89 | file_content = get_file_content(file_path) 90 | if file_content is not None: 91 | file_info['content'] = file_content 92 | 93 | code_map["files"].append(file_info) 94 | 95 | return code_map 96 | -------------------------------------------------------------------------------- /newmap.txt: -------------------------------------------------------------------------------- 1 | # Comprehensive CodeMapper Project Map 2 | 3 | ## 1. Project Structure 4 | 5 | ``` 6 | /Users/bard/Code/codemapper/ 7 | ├── LICENSE 8 | ├── README.md 9 | ├── setup.py 10 | ├── tests/ 11 | │ ├── __init__.py 12 | │ └── test_codemapper.py 13 | └── codemapper/ 14 | ├── __init__.py 15 | ├── cli.py 16 | ├── parser.py 17 | ├── traverser.py 18 | └── utils.py 19 | ``` 20 | 21 | Key configuration files: 22 | - setup.py 23 | - LICENSE (MIT License) 24 | 25 | ## 2. Module Breakdown 26 | 27 | ### codemapper/__init__.py 28 | - Imports: cli, parser, traverser, utils 29 | - Purpose: Initializes the package and defines __all__ 30 | 31 | ### codemapper/cli.py 32 | - Imports: argparse, json, create_map (from .utils) 33 | - Functions: 34 | - main(): Implements the command-line interface 35 | - Purpose: Provides the command-line interface for the CodeMapper tool 36 | 37 | ### codemapper/parser.py 38 | - Imports: ast, os 39 | - Functions: 40 | - extract_info(file_path: str) -> dict 41 | - Docstring: "Extracts information from a file. For Python files, it includes docstrings, function signatures, class names, and import statements. For non-Python files, it includes basic file information." 42 | - Purpose: Extracts detailed information from Python files and basic info from non-Python files 43 | 44 | ### codemapper/traverser.py 45 | - Imports: os, fnmatch 46 | - Functions: 47 | - read_ignore_file(ignore_file: str) -> list 48 | - should_ignore(file_path: str, ignore_patterns: list, root_dir: str) -> bool 49 | - traverse_repository(root_dir: str, ignore_patterns: list) -> Generator[str, None, None] 50 | - Purpose: Handles repository traversal and file ignoring logic 51 | 52 | ### codemapper/utils.py 53 | - Imports: os, sys, pkg_resources, read_ignore_file and traverse_repository (from .traverser), extract_info (from .parser) 54 | - Functions: 55 | - get_file_content(file_path: str, max_size: int = 100 * 1024) -> str or None 56 | - get_version_info() -> dict 57 | - is_config_file(file_path: str) -> bool 58 | - create_map(root_dir: str, ignore_file: str) -> dict 59 | - Purpose: Provides utility functions for creating the code map and handling file content 60 | 61 | ### tests/test_codemapper.py 62 | - Imports: unittest, tempfile, os, create_map (from codemapper.utils) 63 | - Classes: 64 | - TestCodeMapper(unittest.TestCase) 65 | - Methods: setUp, tearDown, test_create_map 66 | - Purpose: Contains unit tests for the CodeMapper module 67 | 68 | ## 3. Dependencies 69 | 70 | Core dependencies: 71 | - setuptools 72 | - ast 73 | - os 74 | - sys 75 | - pkg_resources 76 | - fnmatch 77 | - argparse 78 | - json 79 | 80 | Development dependencies: 81 | - unittest 82 | - tempfile 83 | 84 | ## 4. Configuration 85 | 86 | setup.py content summary: 87 | - Name: codemapper 88 | - Version: 0.1.0 89 | - Author: MikeyBeez 90 | - Description: A tool to map a code repository for LLM editing 91 | - Python requirement: >=3.6 92 | - Entry point: codemapper.cli:main 93 | 94 | No environment variables or external configuration noted. 95 | 96 | ## 5. Entry Points 97 | 98 | Main entry point: codemapper.cli:main 99 | Typical invocation: `codemapper /path/to/repo /path/to/.gitignore output.json` 100 | 101 | ## 6. Data Flow 102 | 103 | 1. User invokes the command-line interface (cli.py) 104 | 2. CLI parses arguments and calls create_map (utils.py) 105 | 3. create_map reads ignore patterns (traverser.py) and traverses the repository 106 | 4. For each file, extract_info (parser.py) is called to gather file information 107 | 5. File content is optionally included based on file type and size (utils.py) 108 | 6. The resulting map is written to a JSON file 109 | 110 | Key data structures: 111 | - code_map (dict): Contains 'files' (list of file info) and 'version_info' 112 | - file_info (dict): Contains details about each file (path, type, size, content, etc.) 113 | 114 | ## 7. External Interactions 115 | 116 | No external APIs, databases, or services noted in the provided code. 117 | 118 | ## 8. Testing 119 | 120 | Testing strategy: Unit tests using unittest framework 121 | Test file: tests/test_codemapper.py 122 | Corresponding production code: codemapper/utils.py (create_map function) 123 | 124 | ## 9. Documentation 125 | 126 | README.md content summary: 127 | - Project description and features 128 | - Installation instructions 129 | - Usage examples 130 | - Project structure overview 131 | - Contributing guidelines 132 | - License information (MIT) 133 | 134 | ## 10. Code Patterns and Style 135 | 136 | - Use of generator functions (e.g., traverse_repository) 137 | - Separation of concerns (cli, parser, traverser, utils) 138 | - Use of context managers for file operations 139 | - Consistent use of docstrings for functions 140 | 141 | ## 11. Performance Considerations 142 | 143 | - File size limit (100KB) for including content in the map 144 | - Use of generators for memory-efficient file traversal 145 | 146 | ## 12. Error Handling and Logging 147 | 148 | - Basic error handling in extract_info function (catches and prints exceptions) 149 | - No specific logging mechanism noted 150 | 151 | ## 13. Security 152 | 153 | - Respects .gitignore patterns 154 | - Automatically excludes .git directories and .DS_Store files 155 | 156 | ## 14. TODOs and FIXMEs 157 | 158 | No TODOs or FIXMEs noted in the provided code snippets. 159 | 160 | ## 15. Version Control 161 | 162 | Version control system: Git (inferred from .gitignore handling) 163 | Branch structure: Not apparent from the provided code 164 | 165 | ## 16. Build and Deployment 166 | 167 | Build process: Uses setuptools (setup.py) 168 | Deployment: Can be installed via pip from GitHub 169 | 170 | Note: This map is based on the provided code snippets and may not reflect the entire codebase if there are additional files or features not included in the given information. 171 | -------------------------------------------------------------------------------- /prompt.txt: -------------------------------------------------------------------------------- 1 | # Comprehensive Code Mapping Prompt 2 | 3 | Create a detailed map of the given codebase, focusing on the following aspects: 4 | 5 | 1. Project Structure: 6 | - Provide a complete directory tree, including all subdirectories and files 7 | - Highlight key configuration files (e.g., setup.py, requirements.txt, .gitignore) 8 | 9 | 2. Module Breakdown: 10 | - For each Python file: 11 | - List all functions, methods, and classes with their signatures 12 | - Include docstrings for modules, classes, and functions 13 | - Summarize the purpose of each module 14 | - List all imports, both standard library and third-party 15 | 16 | 3. Dependencies: 17 | - List all project dependencies and their versions 18 | - Identify core dependencies vs. development dependencies 19 | 20 | 4. Configuration: 21 | - Summarize the content of configuration files (e.g., setup.py, pyproject.toml) 22 | - List any environment variables or external configuration needed 23 | 24 | 5. Entry Points: 25 | - Identify the main entry point(s) of the application 26 | - Describe how the application is typically run or invoked 27 | 28 | 6. Data Flow: 29 | - Provide a high-level overview of how data flows through the application 30 | - Identify key data structures and their purposes 31 | 32 | 7. External Interactions: 33 | - List any external APIs, databases, or services the code interacts with 34 | - Describe the nature of these interactions (e.g., read, write, authenticate) 35 | 36 | 8. Testing: 37 | - Summarize the testing strategy (e.g., unit tests, integration tests) 38 | - List test files and their corresponding production code files 39 | 40 | 9. Documentation: 41 | - Summarize README content and any other documentation files 42 | - Note any missing or outdated documentation 43 | 44 | 10. Code Patterns and Style: 45 | - Identify common design patterns used in the code 46 | - Note any consistent coding styles or conventions 47 | 48 | 11. Performance Considerations: 49 | - Highlight any obvious performance optimizations or bottlenecks 50 | - Note usage of concurrency, caching, or other performance-related features 51 | 52 | 12. Error Handling and Logging: 53 | - Describe the overall approach to error handling 54 | - Identify logging mechanisms and their usage 55 | 56 | 13. Security: 57 | - Note any security-related features (e.g., input validation, authentication) 58 | - Identify potential security concerns if any are apparent 59 | 60 | 14. TODOs and FIXMEs: 61 | - List any TODO or FIXME comments in the code 62 | 63 | 15. Version Control: 64 | - Note the version control system used (e.g., Git) 65 | - Summarize the branch structure if apparent from the codebase 66 | 67 | 16. Build and Deployment: 68 | - Describe any build processes or scripts 69 | - Note any deployment-related files or configurations 70 | 71 | For each of these aspects, provide as much detail as possible based on the available code and file content. The goal is to create a comprehensive map that would allow someone to understand the structure, functionality, and key characteristics of the codebase without having direct access to all of the code. 72 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='codemapper', 5 | version='0.1.0', 6 | packages=find_packages(exclude=['tests']), 7 | install_requires=[ 8 | # Add any dependencies here 9 | ], 10 | entry_points={ 11 | 'console_scripts': [ 12 | 'codemapper=codemapper.cli:main', 13 | ], 14 | }, 15 | author='MikeyBeez', 16 | author_email='mbonsign@gmail.com', 17 | description='A tool to map a code repository for LLM editing', 18 | long_description=open('README.md').read(), 19 | long_description_content_type='text/markdown', 20 | url='https://github.com/MikeyBeez/codemapper', 21 | classifiers=[ 22 | 'Programming Language :: Python :: 3', 23 | 'License :: OSI Approved :: MIT License', 24 | 'Operating System :: OS Independent', 25 | ], 26 | python_requires='>=3.6', 27 | ) 28 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikeyBeez/codemapper/ed3131076ec61f1c3905b07d7fa342e63bd6ecf1/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_codemapper.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import tempfile 3 | import os 4 | from codemapper.utils import create_map 5 | 6 | class TestCodeMapper(unittest.TestCase): 7 | """ 8 | Unit tests for the CodeMapper module. 9 | """ 10 | def setUp(self): 11 | # Create a temporary directory 12 | self.test_dir = tempfile.mkdtemp() 13 | 14 | # Create a mock .gitignore file 15 | self.ignore_file = os.path.join(self.test_dir, '.gitignore') 16 | with open(self.ignore_file, 'w') as f: 17 | f.write("*.pyc\n__pycache__\n") 18 | 19 | # Create a mock Python file 20 | test_file = os.path.join(self.test_dir, 'test_file.py') 21 | with open(test_file, 'w') as f: 22 | f.write("def test_function():\n pass\n") 23 | 24 | def tearDown(self): 25 | # Clean up the temporary directory 26 | for root, dirs, files in os.walk(self.test_dir, topdown=False): 27 | for name in files: 28 | os.remove(os.path.join(root, name)) 29 | for name in dirs: 30 | os.rmdir(os.path.join(root, name)) 31 | os.rmdir(self.test_dir) 32 | 33 | def test_create_map(self): 34 | """ 35 | Test the create_map function to ensure it correctly maps a repository. 36 | """ 37 | code_map = create_map(self.test_dir, self.ignore_file) 38 | self.assertIsNotNone(code_map) 39 | self.assertTrue(len(code_map['files']) > 0) 40 | 41 | # Check if the test file is in the map 42 | test_file_found = any(file_info['path'].endswith('test_file.py') for file_info in code_map['files']) 43 | self.assertTrue(test_file_found, "Test file not found in the code map") 44 | 45 | if __name__ == '__main__': 46 | unittest.main() 47 | --------------------------------------------------------------------------------