From e2626249eecfd9e78f2a2652fa573c1384ad8fe3 Mon Sep 17 00:00:00 2001 From: SunneV Date: Sun, 31 Aug 2025 12:28:09 +0200 Subject: [PATCH 1/5] ci: add GitHub Actions for testing and releases feat(cli): add --version and -v flags feat(config): allow --config flag to accept pyproject.toml fix(config): refine default exclusion list --- .github/workflows/ci.yml | 27 ++++++++++++ .github/workflows/release.yml | 26 ++++++++++++ CHANGELOG.md | 27 ++++++++++++ README.md | 79 ++++++++++++++++++++++++----------- pyproject.toml | 2 +- src/scriber/cli.py | 68 ++++++++++++++++++------------ src/scriber/core.py | 62 +++++++++++++++------------ tests/test_suite.py | 26 ++++++++++++ 8 files changed, 238 insertions(+), 79 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 CHANGELOG.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..26360b5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: Continuous Integration + +on: + push: + branches: + - develop + +jobs: + run_tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + pip install --upgrade pip + pip install -e .[dev] + + - name: Run tests + run: pytest \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..82f2165 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,26 @@ +name: Publish to TestPyPI + +on: + push: + tags: + - 'v*' # Triggers on any tag starting with v, like v0.0.3 + +jobs: + build_and_publish: + runs-on: ubuntu-latest + permissions: + id-token: write # Required for trusted publishing + contents: read # Required to read the repository content + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install uv + run: pipx install uv + + - name: Build distributions + run: uv build + + - name: Publish to PyPI + run: uv publish \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7247081 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog + +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). + +## [1.0.1] - 2025-08-30 + +### Added +- Configured a GitHub Actions pipeline for automated testing and releases. +- `-v` and `--version` to scriber app +- The `--config` flag now accepts a path to a `pyproject.toml` file, providing more flexibility for monorepo configurations. + +### Fixed +- Refined the default exclusion list in `DEFAULT_CONFIG`. + +## [1.0.0] - 2025-08-30 + +### Initial Release +- **Project Structure Mapping**: Implemented smart file and folder structure mapping. +- **Gitignore Support**: Added logic to respect `.gitignore` files, automatically excluding specified files and directories from the mapping process. +- **Code Analysis**: Included functionality to analyze Python source code. +- **Clipboard Integration**: Enabled copying the generated project structure to the clipboard. +- **Command-Line Interface**: Created a command-line tool with a configurable `init` command for saving settings to `pyproject.toml`. +- **Configuration**: Introduced `pyproject.toml` as the single source of truth for project metadata and configuration. +- **Testing**: Added a test suite using `pytest` to ensure core functionality and CLI commands work as expected. \ No newline at end of file diff --git a/README.md b/README.md index 3cb326e..477f6ac 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Introduction +[![latest version](https://img.shields.io/github/v/release/SunneV/ProjectScriber?style=flat&label=latest%20version)](https://github.com/SunneV/ProjectScriber/releases) +[![PyPI version](https://img.shields.io/pypi/v/project-scriber?style=flat)](https://pypi.org/project/project-scriber/)

ProjectScriber Logo

@@ -8,46 +10,66 @@

A command-line tool to intelligently map and compile your entire project's source code into a single, context-optimized -text file for Large Language Models (LLMs). +text file for Large Language Models (LLMs). ProjectScriber scans your project directory, respects `.gitignore` rules, +applies custom filters, and bundles all relevant code into a clean, readable format. It's the perfect way to provide a +complete codebase to an AI for analysis, documentation, or refactoring. -ProjectScriber scans your project directory, respects `.gitignore` rules, applies custom filters, and bundles all -relevant code into a clean, readable format. It's the perfect way to provide a complete codebase to an AI for analysis, -documentation, or refactoring. - ------ +*** ## Key Features -- **🌳 Smart Project Mapping:** Generates a clear and intuitive tree view of your project's structure. -- **βš™οΈ Intelligent Filtering:** Automatically respects `.gitignore` rules and supports custom `include` and `exclude` +* **🌳 Smart Project Mapping:** Generates a clear and intuitive tree view of your project's structure. +* **βš™οΈ Intelligent Filtering:** Automatically respects `.gitignore` rules and supports custom `include` and `exclude` patterns via a `.scriber.json` file for fine-grained control. -- **πŸ“Š In-depth Code Analysis:** Provides a summary with total file size, estimated token count (using `cl100k_base`), +* **πŸ“Š In-depth Code Analysis:** Provides a summary with total file size, estimated token count (using `cl100k_base`), and a language breakdown for a quick overview of your codebase. -- **✨ Interactive Setup:** A simple `scriber init` command walks you through creating a configuration file tailored to +* **✨ Interactive Setup:** A simple `scriber init` command walks you through creating a configuration file tailored to your project. -- **πŸ“‹ Clipboard Integration:** Use the `--copy` flag to automatically copy the entire consolidated output to your +* **πŸ“‹ Clipboard Integration:** Use the `--copy` flag to automatically copy the entire consolidated output to your clipboard, ready to be pasted into any application. -- **πŸ”§ Flexible Configuration:** Manage your settings globally in a `pyproject.toml` file or per-project with a +* **πŸ”§ Flexible Configuration:** Manage your settings globally in a `pyproject.toml` file or per-project with a `.scriber.json` file. ------ +*** ## Getting Started +### Install using pip + +Install the package directly from the official Python Package Index (PyPI). + +```shell +pip install project-scriber +```` + +----- + +## For Developers + ### Prerequisites -- Python 3.10 or higher. +* Python 3.10 or higher. ### Installation -Install the package from the source using pip. For development, include the optional dependencies. +Clone the repository and install it in an editable (development) mode with all optional dependencies. ```shell -# Navigate to the project root directory -pip install .[dev] +# Clone the repository +git clone [https://github.com/SunneV/ProjectScriber.git](https://github.com/SunneV/ProjectScriber.git) +cd ProjectScriber + +# Install for development +pip install -e .[dev] ``` -This will install `ProjectScriber` and make the `scriber` command available in your terminal. +### Run Tests + +Run the test suite using `pytest`. + +```shell +pytest +``` ----- @@ -95,17 +117,26 @@ You can customize ProjectScriber's behavior with the following commands and opti |:----------------------|:-----:|:-------------------------------------------------------------------------------| | `scriber [path]` | | Targets a specific directory. Defaults to the current working directory. | | `init` | | Starts the interactive process to create a `.scriber.json` configuration file. | +| `--version` | `-v` | Displays the current version of ProjectScriber. | | | `--output [filename]` | `-o` | Specifies a custom name for the output file. | | `--copy` | `-c` | Copies the final output directly to the clipboard. | | `--tree-only` | | Generates only the folder structure map, excluding all file contents. | -| `--config [path]` | | Specifies the path to a custom configuration file. | +| `--config [path]` | | Specifies a path to a custom `.json` or `pyproject.toml` configuration file. | ----- ## Configuration -You can control ProjectScriber's behavior by placing a `.scriber.json` file in your project's root, which can be easily -created with the `scriber init` command. +ProjectScriber uses the following order of precedence for loading configurations: + +1. **`--config [path]` flag**: Highest priority. If you provide a path to a `.json` or `pyproject.toml` file, its + settings will be used. This is ideal for monorepos where a central configuration is needed. +2. **`.scriber.json`**: If no `--config` flag is used, Scriber looks for a `.scriber.json` file in the project's root + directory. This file's settings will override any found in `pyproject.toml`. +3. **`pyproject.toml`**: If neither of the above is found, it looks for a `[tool.scriber]` section in a `pyproject.toml` + file in the project's root. +4. **Default Config**: If no configuration file is found, `scriber` will prompt you to create a default `.scriber.json` + on its first run in a directory. **Example `.scriber.json`:** @@ -140,9 +171,9 @@ include = [ ] ``` -- **`use_gitignore`**: If `true`, all patterns in your `.gitignore` file will be used for exclusion. -- **`exclude`**: A list of file or folder name patterns to explicitly ignore. -- **`include`**: If provided, *only* files matching these patterns will be included in the output, overriding other +* **`use_gitignore`**: If `true`, all patterns in your `.gitignore` file will be used for exclusion. +* **`exclude`**: A list of file or folder name patterns to explicitly ignore. +* **`include`**: If provided, *only* files matching these patterns will be included in the output, overriding other rules. Settings can also be placed in your `pyproject.toml` file under the `[tool.scriber]` section. If a `.scriber.json` file diff --git a/pyproject.toml b/pyproject.toml index aed06ce..d46c7b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "project-scriber" -version = "1.0.0" +version = "1.0.1" authors = [ { name="SunneV (Wojciech Mariusz CichoΕ„)", email="wojciech.m.cichon@gmail.com" }, ] diff --git a/src/scriber/cli.py b/src/scriber/cli.py index d18be1d..85606da 100644 --- a/src/scriber/cli.py +++ b/src/scriber/cli.py @@ -66,7 +66,7 @@ def save_to_toml(console: Console, config: dict[str, Any]): console.print(f"\n❌ [bold red]Error updating `pyproject.toml`:[/] {e}") -def handle_init(console: Console): +def handle_init(args: argparse.Namespace, console: Console): """Handles the interactive initialization of a config file.""" console.print(Panel("[bold cyan]Scriber Configuration Setup[/]", expand=False)) console.print("This utility will help you create a configuration file.\n") @@ -106,13 +106,8 @@ def handle_init(console: Console): save_to_toml(console, config) -def run_scriber(args: argparse.Namespace, console: Console): +def run_scriber(args: argparse.Namespace, console: Console, version: str): """Handles the main logic of mapping and generating the project output.""" - try: - version = metadata.version("project-scriber") - except metadata.PackageNotFoundError: - version = "1.0.0 (local)" - title_text = Text(f"Scriber v{version}", justify="center", style="bold magenta") subtitle_text = Text("An intelligent tool to map, analyze, and compile project source code for LLM context.", justify="center", style="cyan") console.print(Panel(Text.assemble(title_text, "\n", subtitle_text), expand=False, border_style="blue")) @@ -169,7 +164,7 @@ def run_scriber(args: argparse.Namespace, console: Console): else: console.print(Panel("[yellow]No files were mapped based on the current configuration.[/]", expand=False)) - output_location = args.root_path.resolve() / output_filename + output_location = Path(args.root_path).resolve() / output_filename console.print("\nβœ… [green]Success! Output saved to:[/green]") try: @@ -191,44 +186,55 @@ def run_scriber(args: argparse.Namespace, console: Console): def main() -> None: """Parses arguments and runs the appropriate command.""" console = Console() + + try: + version = metadata.version("project-scriber") + except metadata.PackageNotFoundError: + version = "1.0.0 (local)" + parser = argparse.ArgumentParser( description="Scriber: An intelligent tool to map, analyze, and compile project source code for LLM context." ) + parser.add_argument( + "-v", "--version", + action="version", + version=f"%(prog)s v{version}", + help="Show the version number and exit." + ) + subparsers = parser.add_subparsers(dest="command", title="Commands") - init_parser = subparsers.add_parser("init", help="Create a new .scriber.json configuration file interactively.") - init_parser.set_defaults(func=lambda args: handle_init(console)) + # `init` command subparser + init_parser = subparsers.add_parser("init", help="Create a new configuration file interactively.") + init_parser.set_defaults(func=lambda args: handle_init(args, console)) - run_parser = argparse.ArgumentParser(add_help=False) + # `run` command subparser + run_parser = subparsers.add_parser("run", help="Map the project structure (default command).") exec_mode = os.environ.get('SCRIBER_EXEC_MODE') + default_path = Path.cwd().parent if exec_mode == 'RUN_PY' else Path.cwd() if exec_mode == 'RUN_PY': - default_path = Path.cwd().parent del os.environ['SCRIBER_EXEC_MODE'] - else: - default_path = Path.cwd() run_parser.add_argument( "root_path", nargs="?", default=os.environ.get("PROJECT_SCRIBER_ROOT", default_path), type=Path, - help="The root directory of the project to map.", + help="The root directory of the project to map. Defaults to the current directory.", ) run_parser.add_argument( - "-o", - "--output", + "-o", "--output", help="The name of the output file. Overrides config file settings.", ) run_parser.add_argument( "--config", default=os.environ.get("PROJECT_SCRIBER_CONFIG"), type=Path, - help="Path to a custom configuration file. Overrides default .scriber.json" + help="Path to a custom configuration file." ) run_parser.add_argument( - "--copy", - "-c", + "-c", "--copy", action="store_true", help="Copy the final output to the clipboard.", ) @@ -237,15 +243,23 @@ def main() -> None: action="store_true", help="Generate only the file tree structure without file content.", ) - run_parser.set_defaults(func=lambda args: run_scriber(args, console)) + run_parser.set_defaults(func=lambda args: run_scriber(args, console, version)) - # Make the 'run' command the default action if no subcommand is provided. - if len(sys.argv) == 1 or sys.argv[1] not in subparsers.choices: - args = run_parser.parse_args() - else: - args = parser.parse_args() + # Pre-process args to insert 'run' as the default command + args_to_parse = sys.argv[1:] + global_flags = ['-h', '--help', '-v', '--version'] + + if not args_to_parse or args_to_parse[0] not in list(subparsers.choices) + global_flags: + args_to_parse.insert(0, 'run') - args.func(args) + args = parser.parse_args(args_to_parse) + + if hasattr(args, 'func'): + args.func(args) + else: + # This branch is hit for global flags like -h, --help, -v, --version + # which are handled by argparse and exit, or if no func is set. + parser.print_help() if __name__ == "__main__": diff --git a/src/scriber/core.py b/src/scriber/core.py index 374b3d6..93b1420 100644 --- a/src/scriber/core.py +++ b/src/scriber/core.py @@ -19,8 +19,8 @@ "use_gitignore": True, "exclude": [ # Common - "LICENSE" - + "LICENSE", + # Version Control ".git", @@ -117,34 +117,42 @@ def _create_default_config_file(self) -> None: self._console.print(f"❌ [bold red]Could not create default config file:[/] {e}") def _load_config(self) -> None: + """Loads configuration with a clear precedence: --config, .scriber.json, pyproject.toml.""" config = DEFAULT_CONFIG.copy() - toml_config_found = False - toml_path = self.root_path / "pyproject.toml" - - if toml_path.is_file(): - try: - with toml_path.open("rb") as f: - toml_data = tomllib.load(f) - if "tool" in toml_data and "scriber" in toml_data["tool"]: - config.update(toml_data["tool"]["scriber"]) - toml_config_found = True - except tomllib.TOMLDecodeError: - self._console.print(f"Warning: Invalid pyproject.toml format in {toml_path}") - - config_path_to_use = self._user_config_path or (self.root_path / self._CONFIG_FILE_NAME) - - if not toml_config_found and not config_path_to_use.is_file() and not self._user_config_path: - self._create_default_config_file() - - if config_path_to_use.is_file(): + config_path_to_use = None + config_loaded = False + + if self._user_config_path: + if self._user_config_path.is_file(): + config_path_to_use = self._user_config_path + else: + self._console.print(f"Warning: Config file specified by --config not found at {self._user_config_path}") + else: + json_path = self.root_path / self._CONFIG_FILE_NAME + toml_path = self.root_path / "pyproject.toml" + if json_path.is_file(): + config_path_to_use = json_path + elif toml_path.is_file(): + config_path_to_use = toml_path + + if config_path_to_use: self.config_path_used = config_path_to_use try: - with config_path_to_use.open("r", encoding="utf-8") as f: - config.update(json.load(f)) - except json.JSONDecodeError as e: - self._console.print(f"Error: Invalid JSON in {config_path_to_use}. Details: {e}") - except IOError: - pass + if config_path_to_use.suffix == ".toml": + with config_path_to_use.open("rb") as f: + toml_data = tomllib.load(f) + if "tool" in toml_data and "scriber" in toml_data["tool"]: + config.update(toml_data["tool"]["scriber"]) + config_loaded = True + else: + with config_path_to_use.open("r", encoding="utf-8") as f: + config.update(json.load(f)) + config_loaded = True + except (json.JSONDecodeError, tomllib.TOMLDecodeError, IOError) as e: + self._console.print(f"Error parsing config file {self.config_path_used}: {e}") + + if not config_loaded and not self._user_config_path: + self._create_default_config_file() self.config = config self.include_patterns: List[str] = self.config.get("include", []) diff --git a/tests/test_suite.py b/tests/test_suite.py index 2e02f85..56c4eb5 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -86,6 +86,32 @@ def test_include_patterns(self, tmp_path: Path): paths = {p.name for p in scriber.mapped_files} assert paths == {"main.py", "script.js"} + def test_core_loads_external_toml_config(self, tmp_path: Path): + """Tests core logic loads config from an external pyproject.toml via config_path.""" + config_dir = tmp_path / "config" + config_dir.mkdir() + toml_path = config_dir / "pyproject.toml" + toml_path.write_text("[tool.scriber]\ninclude = ['*.py']") + + project_dir = tmp_path / "project" + project_dir.mkdir() + (project_dir / "app.py").touch() + (project_dir / "data.json").touch() + + scriber = Scriber(root_path=project_dir, config_path=toml_path) + scriber.map_project() + + paths = {p.name for p in scriber.mapped_files} + assert paths == {"app.py"} + assert scriber.config_path_used == toml_path + + def test_core_handles_nonexistent_config_path(self, tmp_path: Path, capsys): + """Tests that a warning is printed for a non-existent --config path.""" + non_existent_path = tmp_path / "nonexistent.json" + Scriber(root_path=tmp_path, config_path=non_existent_path) + captured = capsys.readouterr() + assert "Warning: Config file specified by --config not found" in captured.err + def test_tree_representation(self, tmp_path: Path): """Checks if the folder tree string is formatted correctly.""" (tmp_path / "src").mkdir() From dc4770f7165b2bba83532e027d4d8b3119e02afb Mon Sep 17 00:00:00 2001 From: SunneV Date: Sun, 31 Aug 2025 12:32:21 +0200 Subject: [PATCH 2/5] update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 477f6ac..b5d1733 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ProjectScriber Name

-A command-line tool to intelligently map and compile your entire project's source code into a single, context-optimized +A simple command-line tool to intelligently map and compile your entire project's source code into a single, context-optimized text file for Large Language Models (LLMs). ProjectScriber scans your project directory, respects `.gitignore` rules, applies custom filters, and bundles all relevant code into a clean, readable format. It's the perfect way to provide a complete codebase to an AI for analysis, documentation, or refactoring. @@ -117,6 +117,7 @@ You can customize ProjectScriber's behavior with the following commands and opti |:----------------------|:-----:|:-------------------------------------------------------------------------------| | `scriber [path]` | | Targets a specific directory. Defaults to the current working directory. | | `init` | | Starts the interactive process to create a `.scriber.json` configuration file. | +| `--help` | `-h` | Displays this help message. | | | | `--version` | `-v` | Displays the current version of ProjectScriber. | | | `--output [filename]` | `-o` | Specifies a custom name for the output file. | | `--copy` | `-c` | Copies the final output directly to the clipboard. | @@ -177,4 +178,10 @@ include = [ rules. Settings can also be placed in your `pyproject.toml` file under the `[tool.scriber]` section. If a `.scriber.json` file -is present, it will take precedence over the `pyproject.toml` configuration. \ No newline at end of file +is present, it will take precedence over the `pyproject.toml` configuration. + +----- + +## Contributing + +Contributions are welcome! If you have a suggestion or find a bug, please open an issue to discuss it. From 6ccfd604c35259b85adb7b266962c71f0f1673ca Mon Sep 17 00:00:00 2001 From: SunneV Date: Sun, 31 Aug 2025 12:36:17 +0200 Subject: [PATCH 3/5] update README.md --- README.md | 155 ++++++++++++++++++++++++------------------------------ 1 file changed, 70 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index b5d1733..21bf7de 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,42 @@ -# Introduction - -[![latest version](https://img.shields.io/github/v/release/SunneV/ProjectScriber?style=flat&label=latest%20version)](https://github.com/SunneV/ProjectScriber/releases) -[![PyPI version](https://img.shields.io/pypi/v/project-scriber?style=flat)](https://pypi.org/project/project-scriber/)

- ProjectScriber Logo + ProjectScriber Logo +
+ ProjectScriber Name

- ProjectScriber Name + Latest Version + PyPI Version

-A simple command-line tool to intelligently map and compile your entire project's source code into a single, context-optimized -text file for Large Language Models (LLMs). ProjectScriber scans your project directory, respects `.gitignore` rules, -applies custom filters, and bundles all relevant code into a clean, readable format. It's the perfect way to provide a -complete codebase to an AI for analysis, documentation, or refactoring. +A command-line tool to intelligently map and compile your project's source code into a single, context-optimized text +file for Large Language Models (LLMs). + +--- -*** +## Why ProjectScriber? + +When working with LLMs, providing the full context of a codebase is crucial for getting accurate analysis, +documentation, or refactoring suggestions. Manually copying and pasting files is tedious and error-prone. * +*ProjectScriber** automates this process. It scans your project, respects `.gitignore` rules, applies custom filters, +and bundles all relevant code into a clean, readable format perfect for any AI model. ## Key Features * **🌳 Smart Project Mapping:** Generates a clear and intuitive tree view of your project's structure. * **βš™οΈ Intelligent Filtering:** Automatically respects `.gitignore` rules and supports custom `include` and `exclude` - patterns via a `.scriber.json` file for fine-grained control. + patterns for fine-grained control. * **πŸ“Š In-depth Code Analysis:** Provides a summary with total file size, estimated token count (using `cl100k_base`), - and a language breakdown for a quick overview of your codebase. + and a language breakdown. * **✨ Interactive Setup:** A simple `scriber init` command walks you through creating a configuration file tailored to your project. -* **πŸ“‹ Clipboard Integration:** Use the `--copy` flag to automatically copy the entire consolidated output to your - clipboard, ready to be pasted into any application. -* **πŸ”§ Flexible Configuration:** Manage your settings globally in a `pyproject.toml` file or per-project with a - `.scriber.json` file. +* **πŸ“‹ Clipboard Integration:** Use the `--copy` flag to automatically copy the entire output to your clipboard. +* **πŸ”§ Flexible Configuration:** Manage settings in a `pyproject.toml` or a project-specific `.scriber.json` file. -*** +--- ## Getting Started -### Install using pip - -Install the package directly from the official Python Package Index (PyPI). +Install the package directly from the [Python Package Index (PyPI)](https://pypi.org/project/project-scriber/). ```shell pip install project-scriber @@ -44,64 +44,33 @@ pip install project-scriber ----- -## For Developers - -### Prerequisites - -* Python 3.10 or higher. - -### Installation - -Clone the repository and install it in an editable (development) mode with all optional dependencies. - -```shell -# Clone the repository -git clone [https://github.com/SunneV/ProjectScriber.git](https://github.com/SunneV/ProjectScriber.git) -cd ProjectScriber - -# Install for development -pip install -e .[dev] -``` - -### Run Tests - -Run the test suite using `pytest`. - -```shell -pytest -``` - ------ - ## Usage -### 1\. Basic Scan +#### 1\. Basic Scan -To run ProjectScriber on the current directory, simply execute the `scriber` command. This will generate a -`scriber_output.txt` file in the same directory. +Run `scriber` in your project's root directory. It will generate a `scriber_output.txt` file. ```shell scriber ``` -To target a different project directory: +To target a different directory: ```shell scriber /path/to/your/project ``` -### 2\. First-Time Configuration +#### 2\. First-Time Configuration -For a new project, run the interactive `init` command to create a `.scriber.json` configuration file. This will guide -you through setting up rules for ignoring files and respecting `.gitignore`. +For a new project, run the interactive `init` command to create a `.scriber.json` configuration file. ```shell scriber init ``` -### 3\. Advanced Example +#### 3\. Advanced Example -Scan a different project, specify a custom output file, and copy the result to the clipboard all in one command. +Scan another project, specify a custom output file, and copy the result to the clipboard in one command. ```shell scriber ../my-other-project --output custom_map.txt --copy @@ -111,18 +80,16 @@ scriber ../my-other-project --output custom_map.txt --copy ## Commands and Options -You can customize ProjectScriber's behavior with the following commands and options. - -| Command/Option | Alias | Description | -|:----------------------|:-----:|:-------------------------------------------------------------------------------| -| `scriber [path]` | | Targets a specific directory. Defaults to the current working directory. | -| `init` | | Starts the interactive process to create a `.scriber.json` configuration file. | -| `--help` | `-h` | Displays this help message. | | | -| `--version` | `-v` | Displays the current version of ProjectScriber. | | -| `--output [filename]` | `-o` | Specifies a custom name for the output file. | -| `--copy` | `-c` | Copies the final output directly to the clipboard. | -| `--tree-only` | | Generates only the folder structure map, excluding all file contents. | -| `--config [path]` | | Specifies a path to a custom `.json` or `pyproject.toml` configuration file. | +| Command/Option | Alias | Description | +|:----------------------|:-----:|:-----------------------------------------------------------------------------| +| `scriber [path]` | | Targets a specific directory. Defaults to the current working directory. | +| `init` | | Starts the interactive process to create a configuration file. | +| `--help` | `-h` | Displays the help message. | +| `--version` | `-v` | Displays the current version of ProjectScriber. | +| `--output [filename]` | `-o` | Specifies a custom name for the output file. | +| `--copy` | `-c` | Copies the final output directly to the clipboard. | +| `--tree-only` | | Generates only the folder structure map, excluding all file contents. | +| `--config [path]` | | Specifies a path to a custom `.json` or `pyproject.toml` configuration file. | ----- @@ -131,13 +98,13 @@ You can customize ProjectScriber's behavior with the following commands and opti ProjectScriber uses the following order of precedence for loading configurations: 1. **`--config [path]` flag**: Highest priority. If you provide a path to a `.json` or `pyproject.toml` file, its - settings will be used. This is ideal for monorepos where a central configuration is needed. -2. **`.scriber.json`**: If no `--config` flag is used, Scriber looks for a `.scriber.json` file in the project's root - directory. This file's settings will override any found in `pyproject.toml`. + settings will be used. +2. **`.scriber.json`**: If no `--config` flag is used, Scriber looks for a `.scriber.json` file in the project's root. + This file's settings will override any found in `pyproject.toml`. 3. **`pyproject.toml`**: If neither of the above is found, it looks for a `[tool.scriber]` section in a `pyproject.toml` file in the project's root. -4. **Default Config**: If no configuration file is found, `scriber` will prompt you to create a default `.scriber.json` - on its first run in a directory. +4. **Default Config**: If no configuration is found, `scriber` will create a default `.scriber.json` on its first run in + a directory. **Example `.scriber.json`:** @@ -164,24 +131,42 @@ use_gitignore = true exclude = [ "__pycache__", "node_modules", - "*.log", + "*.log" ] include = [ "*.py", - "*.js", + "*.js" ] ``` -* **`use_gitignore`**: If `true`, all patterns in your `.gitignore` file will be used for exclusion. -* **`exclude`**: A list of file or folder name patterns to explicitly ignore. -* **`include`**: If provided, *only* files matching these patterns will be included in the output, overriding other - rules. +----- + +## For Developers + +### Prerequisites + +* Python 3.10 or higher. + +### Development Installation + +Clone the repository and install it in editable mode with all development dependencies. + +```shell +git clone [https://github.com/SunneV/ProjectScriber.git](https://github.com/SunneV/ProjectScriber.git) +cd ProjectScriber +pip install -e .[dev] +``` + +### Running Tests + +Run the test suite using `pytest`. -Settings can also be placed in your `pyproject.toml` file under the `[tool.scriber]` section. If a `.scriber.json` file -is present, it will take precedence over the `pyproject.toml` configuration. +```shell +pytest +``` ----- ## Contributing -Contributions are welcome! If you have a suggestion or find a bug, please open an issue to discuss it. +Contributions are welcome\! If you have a suggestion or find a bug, please open an issue to discuss it. From 76e3ca8ea2380806b77e777fb5a556437326f198 Mon Sep 17 00:00:00 2001 From: SunneV Date: Sun, 31 Aug 2025 12:39:47 +0200 Subject: [PATCH 4/5] update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7247081..3c18169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Refined the default exclusion list in `DEFAULT_CONFIG`. -## [1.0.0] - 2025-08-30 +## [1.0.0] - 2025-08-28 ### Initial Release - **Project Structure Mapping**: Implemented smart file and folder structure mapping. From 6dd00be67b6e881b9af8e574f32ef05f1c2d2731 Mon Sep 17 00:00:00 2001 From: SunneV Date: Sun, 31 Aug 2025 12:41:38 +0200 Subject: [PATCH 5/5] update pyproject.toml --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d46c7b0..2427298 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,4 +44,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["src/scriber"] \ No newline at end of file +packages = ["src/scriber"] + +[tool.pytest.ini_options] +pythonpath = [ + "." +] \ No newline at end of file