Metadata-Version: 2.4
Name: stouputils
Version: 26.3.1
Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
Keywords: utilities,tools,helpers,development,typed,pyright,python
Author: Stoupy51
Author-email: Stoupy51 <stoupy51@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Dist: tqdm>=4.0.0
Requires-Dist: requests>=2.20.0
Requires-Dist: msgspec[toml,yaml]>=0.20.0
Requires-Dist: pillow>=12.0.0
Requires-Dist: python-box>=7.0.0
Requires-Dist: argcomplete>=3.0.0
Requires-Dist: psutil>=7.2.2
Requires-Dist: redis[hiredis]
Requires-Dist: setproctitle
Requires-Dist: numpy
Requires-Dist: mypy ; extra == 'all'
Requires-Dist: myst-parser ; extra == 'all'
Requires-Dist: sphinx ; extra == 'all'
Requires-Dist: sphinx-copybutton ; extra == 'all'
Requires-Dist: sphinx-design ; extra == 'all'
Requires-Dist: sphinx-treeview ; extra == 'all'
Requires-Dist: sphinx-breeze-theme ; extra == 'all'
Requires-Dist: pydata-sphinx-theme ; extra == 'all'
Requires-Dist: zensical ; extra == 'all'
Requires-Dist: mkdocstrings-python ; extra == 'all'
Requires-Dist: opencv-python ; extra == 'all'
Requires-Dist: scikit-image ; extra == 'all'
Requires-Dist: simpleitk ; extra == 'all'
Requires-Dist: mlflow ; extra == 'all'
Requires-Dist: scikit-learn ; extra == 'all'
Requires-Dist: pywavelets ; extra == 'all'
Requires-Dist: mlflow ; extra == 'all'
Requires-Dist: polars ; extra == 'all'
Requires-Dist: mypy ; extra == 'all'
Requires-Dist: uv ; extra == 'all'
Requires-Dist: opencv-python ; extra == 'data-science'
Requires-Dist: scikit-image ; extra == 'data-science'
Requires-Dist: simpleitk ; extra == 'data-science'
Requires-Dist: mlflow ; extra == 'data-science'
Requires-Dist: scikit-learn ; extra == 'data-science'
Requires-Dist: pywavelets ; extra == 'data-science'
Requires-Dist: mypy ; extra == 'docs'
Requires-Dist: myst-parser ; extra == 'docs'
Requires-Dist: sphinx ; extra == 'docs'
Requires-Dist: sphinx-copybutton ; extra == 'docs'
Requires-Dist: sphinx-design ; extra == 'docs'
Requires-Dist: sphinx-treeview ; extra == 'docs'
Requires-Dist: sphinx-breeze-theme ; extra == 'docs'
Requires-Dist: pydata-sphinx-theme ; extra == 'docs'
Requires-Dist: zensical ; extra == 'docs'
Requires-Dist: mkdocstrings-python ; extra == 'docs'
Requires-Dist: mlflow ; extra == 'optional'
Requires-Dist: polars ; extra == 'optional'
Requires-Dist: mypy ; extra == 'optional'
Requires-Dist: uv ; extra == 'optional'
Requires-Python: >=3.12
Project-URL: Homepage, https://stoupy51.github.io/stouputils
Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
Project-URL: Repository, https://github.com/Stoupy51/stouputils
Provides-Extra: all
Provides-Extra: data-science
Provides-Extra: docs
Provides-Extra: optional
Description-Content-Type: text/markdown


# 🛠️ stouputils

<div align="center">

*Every utility you rewrite in each project, already written: colored logging, decorators, parallel maps, archives, backups, a CLI, and more.*

[![GitHub](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=github&label=GitHub)](https://github.com/Stoupy51/stouputils/releases/latest)
[![PyPI - Downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Fpypi_downloads.json&logo=python)](https://pypi.org/project/stouputils/)
[![Documentation](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=sphinx&label=Documentation&color=purple)](https://stoupy51.github.io/stouputils/latest/)
[![Lint](https://github.com/Stoupy51/stouputils/actions/workflows/lint.yml/badge.svg)](https://github.com/Stoupy51/stouputils/actions/workflows/lint.yml)<br>
[![Complexipy](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Fcomplexipy.json)](https://github.com/Stoupy51/stouputils/actions/workflows/complexipy.yml)
[![Generated by github-dependents-info](https://img.shields.io/static/v1?label=Used%20by%20(stars)&message=56&color=informational&logo=slickpic)](https://github.com/Stoupy51/stouputils/network/dependents)

[![Tests 3.12](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_12.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_12.yml)
[![Tests 3.13](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_13.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_13.yml)
[![Tests 3.14](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_14.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_14.yml)
[![Tests 3.15](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_15.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_15.yml)<br>
[![Tests 3.13t](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_13t.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_13t.yml)
[![Tests 3.14t](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_14t.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_14t.yml)
[![Tests 3.15t](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FStoupy51%2Fstouputils%2Fbadges%2Fbadges%2Ftests_3_15t.json&logo=python)](https://github.com/Stoupy51/stouputils/actions/workflows/tests_3_15t.yml)

[Installation](#-installation) | [Quick start](#-quick-start) | [Modules](#-modules) | [CLI](#-extensive-cli-documentation) | [Documentation](https://stoupy51.github.io/stouputils/latest/)

[![Run every example in Google Colab](https://img.shields.io/badge/Run%20every%20example-in%20Google%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&logoColor=white&labelColor=4F4F4F)](https://colab.research.google.com/drive/1mJ-KL-zXzIk1oKDxO6FC1SFfm-BVKG-P?usp=sharing)

</div>

## 📚 What is it?

One import gives you the utilities every project ends up rewriting.
Logs are colored and timestamped, repeated lines collapse into `(x3)`, decorators time and retry your functions, and `multiprocessing` gets a progress bar for free, and many more.
Everything is **strongly** typed, doctested on Python 3.12 to 3.15 including the free threaded builds, and every submodule is declared lazy (PEP 810) so `import stouputils` costs almost nothing on Python 3.15.

## 🔧 Installation

```bash
pip install stouputils
```

<details>
<summary><b>✨ Enable tab completion on Linux (optional)</b></summary>

For a better CLI experience, enable bash tab completion:

```bash
# Option 1: Using argcomplete's global activation
activate-global-python-argcomplete --user

# Option 2: Manual setup for bash
register-python-argcomplete stouputils >> ~/.bashrc
source ~/.bashrc
```

After enabling completion, you can use `<TAB>` to autocomplete commands:
```bash
stouputils <TAB>        # Shows: --version, -v, all_doctests, backup
stouputils all_<TAB>    # Completes to: all_doctests
```

**Note:** Tab completion works best in bash, zsh, Git Bash, or WSL on Windows.

</details>

## 🚀 Quick start

```python
import stouputils as stp

@stp.measure_time()
@stp.handle_error(message="Doubling failed")
def double(value: int) -> int:
	return value * 2

stp.info("Starting", 3, "jobs")
stp.info("Starting", 3, "jobs")	# A repeated line collapses instead of scrolling away
results: list[int] = stp.multithreading(double, [1, 2, 3], desc="Doubling")
stp.whatisit(results)
stp.warning("Two files were skipped")
```

```text
[INFO  11:32:19] (x2) Starting 3 jobs
[PROGRESS 11:32:19] Execution time of double(): 0.003ms (2904ns)
[PROGRESS 11:32:19] Execution time of double(): 0.001ms (1031ns)
[PROGRESS 11:32:19] Execution time of double(): 0.003ms (2613ns)
Doubling: 100%|██████████| 3/3 [19358.33it/s, 00:00<00:00]
[What is it? 11:32:19] <class 'list'>, <id 127047922343936>: (length: 3, min: 2, max: 6) [2, 4, 6]
[WARNING 11:32:19] Two files were skipped
```

Colors, timestamps and the progress bar come from the defaults, they are configurable.
Send the same logs to a file with `with stp.LogToFile("run.log"):`, silence a noisy library with `with stp.Muffle():`, and swap `multithreading` for `multiprocessing` when the work is CPU bound.

### 💻 From the command line

The same toolbox is available as a CLI, one example per subcommand:

```bash
# Show version information of polars with dependency tree of depth 3
stouputils --version polars -t 3

# Run all doctests in a directory with pattern filter (fnmatch)
stouputils all_doctests "./src" "*_test"

# Repair a corrupted/obstructed zip archive
stouputils archive repair "./input.zip" "./output.zip"

# Create a delta backup
stouputils backup delta "./source" "./backups"

# Build and publish to PyPI (with minor version bump and no stubs)
stouputils build minor --no_stubs

# Generate changelog from git history (since a specific date, with commit URLs from origin remote, output to file)
stouputils changelog date "2026-01-01" -r origin -o "CHANGELOG.md"

# Redirect (move) a folder and create a junction/symlink at the original location
stouputils redirect "C:/Games/MyGame" "D:/Games/" --hardlink
```

> 📖 See the [Extensive CLI Documentation](#-extensive-cli-documentation) section below for detailed usage and all available options.

## 🧰 Modules

Every name below links to its reference page.
<html>
<details style="display: none;">
<summary></summary>
<style>
.code-tree {
	border-radius: 6px; 
	padding: 16px; 
	font-family: monospace; 
	line-height: 1.45; 
	overflow: auto; 
	white-space: pre;
	background-color:rgb(43, 43, 43);
	color: #d4d4d4;
}
.code-tree a {
	color: #569cd6;
	text-decoration: none;
}
.code-tree a:hover {
	text-decoration: underline;
}
.code-tree .comment {
	color:rgb(231, 213, 48);
}
.code-tree .paren {
	color: orange;
}
</style>
</details>

<pre class="code-tree">stouputils/
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.print.html">print</a>         <span class="comment"># 🖨️ Utility functions for printing <span class="paren">(info, debug, warning, error, whatisit, breakpoint, progress_bar, ...)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.decorators.html">decorators</a>    <span class="comment"># 🎯 Decorators <span class="paren">(measure_time, handle_error, timeout, retry, simple_cache, abstract, deprecated, silent)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.ctx.html">ctx</a>           <span class="comment"># 🔇 Context managers <span class="paren">(LogToFile, MeasureTime, Muffle, DoNothing, SetMPStartMethod)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.io.html">io</a>            <span class="comment"># 💾 Utilities for file management <span class="paren">(json_dump, json_load, csv_dump, csv_load, read_file, super_copy, super_open, clean_path, redirect_folder, ...)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.parallel.html">parallel</a>      <span class="comment"># 🔀 Utility functions for parallel processing <span class="paren">(multiprocessing, multithreading, run_in_subprocess)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.image.html">image</a>         <span class="comment"># 🖼️ Little utilities for image processing <span class="paren">(image_resize, auto_crop, numpy_to_gif, numpy_to_obj)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.collections.html">collections</a>   <span class="comment"># 🧰 Utilities for collection manipulation <span class="paren">(unique_list, at_least_n, sort_dict_keys, upsert_in_dataframe, array_to_disk)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.typing.html">typing</a>        <span class="comment"># 📝 Utilities for typing enhancements <span class="paren">(IterAny, JsonDict, JsonList, ..., convert_to_serializable)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.all_doctests.html">all_doctests</a>  <span class="comment"># ✅ Run all doctests for all modules in a given directory <span class="paren">(launch_tests, test_module_with_progress)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.backup.html">backup</a>        <span class="comment"># 💾 Utilities for backup management <span class="paren">(delta backup, consolidate)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.lock.html">lock</a>          <span class="comment"># 🔒 Inter-process FIFO locks <span class="paren">(LockFifo, RLockFifo, RedisLockFifo)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.archive.html">archive</a>       <span class="comment"># 📦 Functions for creating and managing archives <span class="paren">(create, repair)</span></span>
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.config.html">config</a>        <span class="comment"># ⚙️ Global configuration <span class="paren">(StouputilsConfig: global options)</span></span>
│
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.html">applications/</a>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.automatic_docs.html">automatic_docs</a>    <span class="comment"># 📚 Documentation generation utilities <span class="paren">(used to create this documentation)</span></span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.upscaler.html">upscaler</a>          <span class="comment"># 🔎 Image & Video upscaler <span class="paren">(configurable)</span></span>
│   └── ...
│
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.html">continuous_delivery/</a>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.cd_utils.html">cd_utils</a>          <span class="comment"># 🔧 Utilities for continuous delivery</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.git.html">git</a>               <span class="comment"># 📜 Utilities for local git changelog generation</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.github.html">github</a>            <span class="comment"># 📦 Utilities for continuous delivery on GitHub <span class="paren">(upload_to_github)</span></span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.pypi.html">pypi</a>              <span class="comment"># 📦 Utilities for PyPI <span class="paren">(pypi_full_routine)</span></span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.pyproject.html">pyproject</a>         <span class="comment"># 📝 Utilities for reading, writing and managing pyproject.toml files</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.stubs.html">stubs</a>             <span class="comment"># 📝 Utilities for generating stub files using stubgen</span>
│   └── ...
│
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.mlflow.html">mlflow/</a>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.mlflow.process_metrics_monitor.html">process_metrics_monitor</a>    <span class="comment"># 📊 Monitor CPU, memory, I/O, and thread metrics for a specific process tree and log them to MLflow</span>
│   └── ...
│
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.html">installer/</a>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.common.html">common</a>            <span class="comment"># 🔧 Common functions used by the Linux and Windows installers modules</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.downloader.html">downloader</a>        <span class="comment"># ⬇️ Functions for downloading and installing programs from URLs</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.linux.html">linux</a>             <span class="comment"># 🐧 Linux/macOS specific implementations for installation</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.main.html">main</a>              <span class="comment"># 🚀 Core installation functions for installing programs from zip files or URLs</span>
│   ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.windows.html">windows</a>           <span class="comment"># 💻 Windows specific implementations for installation</span>
│   └── ...
└── ...
</pre>
</html>

## 📖 Extensive CLI Documentation

The `stouputils` CLI provides several powerful commands for common development tasks.

### ⚡ General Usage

```bash
stouputils <command> [options]
```

Running `stouputils` without arguments displays help with all available commands.

---

<details>
<summary><b>📌 <code>--version</code> / <code>-v</code> - Show Version Information</b></summary>

Display the version of stouputils and its dependencies, along with the used Python version.

```bash
# Basic usage - show stouputils version
stouputils --version
stouputils -v

# Show version for a specific package
stouputils --version numpy
stouputils -v requests

# Show dependency tree (depth 3+)
stouputils --version -t 3
stouputils -v stouputils --tree 4
```

**Options:**
| Option                 | Description                                                                    |
| ---------------------- | ------------------------------------------------------------------------------ |
| `[package]`            | Optional package name to show version for (default: stouputils)                |
| `-t`, `--tree <depth>` | Show dependency tree with specified depth (≤2 for flat list, ≥3 for tree view) |

</details>

<details>
<summary><b>✅ <code>all_doctests</code> - Run Doctests</b></summary>

Execute all doctests in Python files within a directory.

```bash
# Run doctests in current directory
stouputils all_doctests

# Run doctests in specific directory
stouputils all_doctests ./src

# Run doctests with file pattern filter
stouputils all_doctests ./src "*image/*.py"
stouputils all_doctests . "*utils*"
```

**Arguments:**
| Argument      | Description                                         |
| ------------- | --------------------------------------------------- |
| `[directory]` | Directory to search for Python files (default: `.`) |
| `[pattern]`   | Glob pattern to filter files (default: `*`)         |

**Exit codes:**
- `0`: All tests passed
- `1`: One or more tests failed

</details>

<details>
<summary><b>📦 <code>archive</code> - Archive Utilities</b></summary>

Create and repair ZIP archives.

```bash
# Show archive help
stouputils archive --help
```

<h4><code>archive make</code> - Create Archive</h4>

```bash
# Basic archive creation
stouputils archive make ./my_folder ./backup.zip

# Create archive with ignore patterns
stouputils archive make ./project ./project.zip --ignore "*.pyc,__pycache__,*.log"

# Create destination directory if needed
stouputils archive make ./source ./backups/archive.zip --create-dir
```

**Arguments & Options:**
| Argument/Option       | Description                                      |
| --------------------- | ------------------------------------------------ |
| `<source>`            | Source directory to archive                      |
| `<destination>`       | Destination zip file path                        |
| `--ignore <patterns>` | Comma-separated glob patterns to exclude         |
| `--create-dir`        | Create destination directory if it doesn't exist |

<h4><code>archive repair</code> - Repair Corrupted ZIP</h4>

```bash
# Repair with auto-generated output name
stouputils archive repair ./corrupted.zip

# Repair with custom output name
stouputils archive repair ./corrupted.zip ./fixed.zip
```

**Arguments:**
| Argument        | Description                                               |
| --------------- | --------------------------------------------------------- |
| `<input_file>`  | Path to the corrupted zip file                            |
| `[output_file]` | Path for repaired file (default: adds `_repaired` suffix) |

</details>

<details>
<summary><b>💾 <code>backup</code> - Backup Utilities</b></summary>

Create delta backups, consolidate existing backups, and manage backup retention.

```bash
# Show backup help
stouputils backup --help
```

<h4><code>backup delta</code> - Create Delta Backup</h4>

Create an incremental backup containing only new or modified files since the last backup.

```bash
# Basic delta backup
stouputils backup delta ./my_project ./backups

# Delta backup with exclusions
stouputils backup delta ./project ./backups -x "*.pyc" "__pycache__/*" "node_modules/*"
stouputils backup delta ./source ./backups --exclude "*.log" "temp/*"
```

**Arguments & Options:**
| Argument/Option              | Description                                |
| ---------------------------- | ------------------------------------------ |
| `<source>`                   | Source directory or file to back up        |
| `<destination>`              | Destination folder for backups             |
| `-x`, `--exclude <patterns>` | Glob patterns to exclude (space-separated) |

<h4><code>backup consolidate</code> - Consolidate Backups</h4>

Merge multiple delta backups into a single complete backup.

```bash
# Consolidate all backups up to latest.zip into one file
stouputils backup consolidate ./backups/latest.zip ./consolidated.zip
```

**Arguments:**
| Argument | Description |
|----------|-------------|
| `<backup_zip>` | Path to the latest backup ZIP file |
| `<destination_zip>` | Path for the consolidated output file |

<h4><code>backup limit</code> - Limit Backup Count</h4>

Limit the number of delta backups by consolidating the oldest ones.

```bash
# Keep only the 5 most recent backups
stouputils backup limit 5 ./backups

# Allow deletion of the oldest backup (not recommended)
stouputils backup limit 5 ./backups --no-keep-oldest
```

**Arguments & Options:**
| Argument/Option    | Description                                            |
| ------------------ | ------------------------------------------------------ |
| `<max_backups>`    | Maximum number of backups to keep                      |
| `<backup_folder>`  | Path to the folder containing backups                  |
| `--no-keep-oldest` | Allow deletion of the oldest backup (default: keep it) |

</details>

<details>
<summary><b>🏗️ <code>build</code> - Build and Publish to PyPI</b></summary>

Build and publish a Python package to PyPI using the `uv` tool. This runs a complete routine including version bumping, stub generation, building, and publishing.

```bash
# Standard build and publish (bumps patch by default)
stouputils build

# Build without generating stubs and without bumping version
stouputils build --no_stubs --no_bump

# Bump minor version before build
stouputils build minor

# Bump major version before build
stouputils build major
```

**Options:**
| Option       | Description                                |
| ------------ | ------------------------------------------ |
| `--no_stubs` | Skip stub file generation                  |
| `--no_bump`  | Skip version bumping (use current version) |
| `minor`      | Bump minor version (e.g., 1.2.0 -> 1.3.0)  |
| `major`      | Bump major version (e.g., 1.2.0 -> 2.0.0)  |

</details>

<details>
<summary><b>📜 <code>changelog</code> - Generate Changelog</b></summary>

Generate a formatted changelog from local git history.

```bash
# Show changelog help
stouputils changelog --help
```

```bash
# Generate changelog since latest tag (default)
stouputils changelog

# Generate changelog since a specific tag
stouputils changelog tag v1.9.0

# Generate changelog since a specific date
stouputils changelog date 2026/01/05
stouputils changelog date "2026-01-15 14:30:00"

# Generate changelog since a specific commit
stouputils changelog commit 847b27e

# Include commit URLs from a remote
stouputils changelog --remote origin
stouputils changelog tag v2.0.0 -r origin

# Output to a file
stouputils changelog -o CHANGELOG.md
stouputils changelog tag v1.0.0 --output docs/CHANGELOG.md
```

**Arguments & Options:**
| Argument/Option         | Description                                                             |
| ----------------------- | ----------------------------------------------------------------------- |
| `[mode]`                | Mode for selecting commits: `tag`, `date`, or `commit` (default: `tag`) |
| `[value]`               | Value for the mode (tag name, date, or commit SHA)                      |
| `-r`, `--remote <name>` | Remote name for commit URLs (e.g., `origin`)                            |
| `-o`, `--output <file>` | Output file path (default: stdout)                                      |

**Supported date formats:**
- `YYYY/MM/DD` or `YYYY-MM-DD`
- `DD/MM/YYYY` or `DD-MM-YYYY`
- `YYYY-MM-DD HH:MM:SS`
- ISO 8601: `YYYY-MM-DDTHH:MM:SS`

</details>

<details>
<summary><b>🔗 <code>redirect</code> - Redirect a Folder</b></summary>

Move a folder to a new location and create a junction or symlink at the original path. Useful for redirecting game installs, large data folders, etc. across drives.

```bash
# Show redirect help
stouputils redirect --help

# Redirect with auto-detected basename (destination ends with /)
stouputils redirect "C:/Games/MyGame" "D:/Games/" --hardlink

# Redirect with explicit destination name
stouputils redirect "C:/Games/MyGame" "D:/Storage/MyGame" --symlink

# Interactive mode (asks for link type)
stouputils redirect "./my_folder" "/mnt/external/"
```

**Arguments & Options:**
| Argument/Option             | Description                                                      |
| --------------------------- | ---------------------------------------------------------------- |
| `<source>`                  | Source folder to redirect                                        |
| `<destination>`             | Destination path (append `/` to auto-use source basename)        |
| `--hardlink` / `--junction` | Use NTFS junction (Windows) or fallback to symlink (Linux/macOS) |
| `--symlink`                 | Use a symbolic link (may need admin on Windows)                  |

**Notes:**
- If `--hardlink` fails (e.g., unsupported OS), it automatically falls back to symlink
- If the source is already a symlink or junction, the operation is skipped
- On Linux/macOS, junctions are not available so `--hardlink` uses a symlink instead

</details>

### 📋 Examples Summary

| Command                                                        | Description                             |
| -------------------------------------------------------------- | --------------------------------------- |
| `stouputils -v`                                                | Show version                            |
| `stouputils -v numpy -t 3`                                     | Show numpy version with dependency tree |
| `stouputils all_doctests ./src`                                | Run doctests in src directory           |
| `stouputils archive make ./proj ./proj.zip`                    | Create archive                          |
| `stouputils archive repair ./bad.zip`                          | Repair corrupted zip                    |
| `stouputils backup delta ./src ./bak -x "*.pyc"`               | Create delta backup                     |
| `stouputils backup consolidate ./bak/latest.zip ./full.zip`    | Consolidate backups                     |
| `stouputils backup limit 5 ./bak`                              | Keep only 5 backups                     |
| `stouputils build minor`                                       | Build with minor version bump           |
| `stouputils changelog tag v1.0.0 -r origin -o CHANGELOG.md`    | Generate changelog to file              |
| `stouputils redirect "C:/Games/MyGame" "D:/Games/" --hardlink` | Redirect folder with junction           |

## ⭐ Star History

<html>
	<a href="https://star-history.com/#Stoupy51/stouputils&Date">
		<picture>
			<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
			<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
			<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
		</picture>
	</a>
</html>

