From e9f634044f80a22ff541a9b1ae84de931b4c5bc6 Mon Sep 17 00:00:00 2001 From: Raphael MANSUY Date: Sat, 29 Jun 2024 11:07:30 +0800 Subject: [PATCH] first version of config --- .code2promptrc | 5 +++ README.md | 15 ++++++++ code2prompt/main.py | 74 +++++++++++++++++++++++++++---------- code2prompt/utils/config.py | 47 +++++++++++++++++++++++ 4 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 .code2promptrc create mode 100644 code2prompt/utils/config.py diff --git a/.code2promptrc b/.code2promptrc new file mode 100644 index 0000000..02ca85b --- /dev/null +++ b/.code2promptrc @@ -0,0 +1,5 @@ +{ + "path": "code2prompt", + "suppress_comments": false, + "line_number": false +} \ No newline at end of file diff --git a/README.md b/README.md index 785b7eb..5c1d728 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,21 @@ jobs: This workflow will generate a code analysis report on every push to your repository. +## Configuration File + +Code2Prompt supports a configuration file named `.code2promptrc` for setting default options. You can place this file in your project directory or home directory. The file should be in JSON format. + +Example `.code2promptrc`: + +```json +{ + "suppress_comments": true, + "line_number": true, + "encoding": "cl100k_base", + "filter": "*.py,*.js", + "exclude": "tests/*,docs/*" +} + ## Troubleshooting 1. **Issue**: Code2Prompt is not recognizing my .gitignore file. diff --git a/code2prompt/main.py b/code2prompt/main.py index 5db16e4..2a611d6 100644 --- a/code2prompt/main.py +++ b/code2prompt/main.py @@ -5,53 +5,73 @@ from code2prompt.core.write_output import write_output from code2prompt.utils.create_template_directory import create_templates_directory from code2prompt.utils.logging_utils import log_token_count +from code2prompt.utils.config import load_config, merge_options VERSION = "0.6.4" # Define the version of the CLI tool +DEFAULT_OPTIONS = { + "path": [], + "output": None, + "gitignore": None, + "filter": None, + "exclude": None, + "case_sensitive": False, + "suppress_comments": False, + "line_number": False, + "no_codeblock": False, + "template": None, + "tokens": False, + "encoding": "cl100k_base", + "create_templates": False, +} + + @click.command() @click.version_option( VERSION, "-v", "--version", message="code2prompt version %(version)s" ) @click.option( - "--path", "-p", + "--path", + "-p", type=click.Path(exists=True), required=True, multiple=True, # Allow multiple paths help="Path(s) to the directory or file to process.", ) @click.option( - "--output", "-o", - type=click.Path(), - help="Name of the output Markdown file." + "--output", "-o", type=click.Path(), help="Name of the output Markdown file." ) @click.option( - "--gitignore", "-g", + "--gitignore", + "-g", type=click.Path(exists=True), help="Path to the .gitignore file.", ) @click.option( - "--filter", "-f", + "--filter", + "-f", type=str, help='Comma-separated filter patterns to include files (e.g., "*.py,*.js").', ) @click.option( - "--exclude", "-e", + "--exclude", + "-e", type=str, help='Comma-separated patterns to exclude files (e.g., "*.txt,*.md").', ) @click.option( - "--case-sensitive", - is_flag=True, - help="Perform case-sensitive pattern matching." + "--case-sensitive", is_flag=True, help="Perform case-sensitive pattern matching." ) @click.option( - "--suppress-comments", "-s", + "--suppress-comments", + "-s", is_flag=True, help="Strip comments from the code files.", default=False, ) @click.option( - "--line-number", "-ln", + "--line-number", + "-ln", is_flag=True, help="Add line numbers to source code blocks.", default=False, @@ -62,14 +82,13 @@ help="Disable wrapping code inside markdown code blocks.", ) @click.option( - "--template", "-t", + "--template", + "-t", type=click.Path(exists=True), help="Path to a Jinja2 template file for custom prompt generation.", ) @click.option( - "--tokens", - is_flag=True, - help="Display the token count of the generated prompt." + "--tokens", is_flag=True, help="Display the token count of the generated prompt." ) @click.option( "--encoding", @@ -82,7 +101,7 @@ is_flag=True, help="Create a templates directory with example templates.", ) -def create_markdown_file(**options): +def create_markdown_file(**cli_options): """ Creates a Markdown file based on the provided options. @@ -100,13 +119,27 @@ def create_markdown_file(**options): Returns: None """ + + ## Load configuration from .code2promptrc files + config = load_config(".") + + print(config) + + + # Merge options: CLI takes precedence over config, which takes precedence over defaults + # Merge options: CLI takes precedence over config, which takes precedence over defaults + options = merge_options(cli_options, config, DEFAULT_OPTIONS) + + + print(options) + if options["create_templates"]: create_templates_directory() return all_files_data = [] - for path in options['path']: - files_data = process_files({**options, 'path': path}) + for path in options["path"]: + files_data = process_files({**options, "path": path}) all_files_data.extend(files_data) content = generate_content(all_files_data, options) @@ -117,6 +150,7 @@ def create_markdown_file(**options): write_output(content, options["output"]) + if __name__ == "__main__": # pylint: disable=no-value-for-parameter - create_markdown_file() \ No newline at end of file + create_markdown_file() diff --git a/code2prompt/utils/config.py b/code2prompt/utils/config.py new file mode 100644 index 0000000..7858f4e --- /dev/null +++ b/code2prompt/utils/config.py @@ -0,0 +1,47 @@ +# code2prompt/config.py +import json +from pathlib import Path + +def load_config(current_dir): + """ + Load configuration from .code2promptrc files. + Searches in the current directory and all parent directories up to the home directory. + """ + config = {} + current_path = Path(current_dir).resolve() + home_path = Path.home() + + while current_path >= home_path: + rc_file = current_path / '.code2promptrc' + if rc_file.is_file(): + with open(rc_file, 'r', encoding='utf-8') as f: + config.update(json.load(f)) + if current_path == home_path: + break + current_path = current_path.parent + + return config + +def merge_options(cli_options: dict, config_options: dict, default_options: dict) -> dict: + """ + Merge CLI options, config options, and default options. + CLI options take precedence over config options, which take precedence over default options. + """ + merged = default_options.copy() + + # Update with config options + for key, value in config_options.items(): + if isinstance(value, dict) and isinstance(merged.get(key), dict): + merged[key] = merge_options({}, value, merged[key]) + else: + merged[key] = value + + # Update with CLI options, but only if they're different from the default + for key, value in cli_options.items(): + if value != default_options.get(key): + if isinstance(value, dict) and isinstance(merged.get(key), dict): + merged[key] = merge_options(value, {}, merged[key]) + else: + merged[key] = value + + return merged \ No newline at end of file