Metadata-Version: 2.4
Name: yd-cli
Version: 0.11
Summary: CLI tool to synchronize directories using rsync.
Author: Christian Heinze
License-Expression: MIT
License-File: LICENSES/MIT.txt
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: System :: Archiving
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Dist: msgspec>=0.20
Requires-Dist: rich>=14.3
Requires-Dist: typer>=0.24
Requires-Python: >=3.14
Project-URL: Repository, https://codeberg.org/christianheinze/yd-cli
Description-Content-Type: text/markdown

# Directory synchronization tool `yd`

Build and execute `rsync` commands from *TOML* configuration files.

## (Un)Install

To install, run

```bash
uv tool install yd-cli
```

Then run

```bash
yd --install-completion
```

to install auto-completion in your shell.

In `bash`, the completion code is stored in `~/.bash_completions/yd.sh` and that file is sourced from `~/.bashrc`.
Remove both and call `uv tool uninstall yd-cli` to remove this tool.
The below mentioned configuration files need to be removed separately.

## Create a config

Create a new configuration called `photos` with:

```bash
yd edit --new photos
```

This command

- creates `~/.config/yd/photos.toml` (or under `$XDG_CONFIG_HOME/yd` if set; relative paths are resolved from your home directory), and
- opens it in the editor selected via `EDITOR`.

Reopen an existing configuration with:

```bash
yd edit photos
```

## Configuration format

### Example

```toml
# Phone backup
src_home = "/home/alice"
target_home = "/mnt/backup"
backup = "deleted/%Y-%m-%d"
exclude = [".venv/", "__pycache__/"]

[[commands]]
src = "Documents"
exclude = ["*.log"]

[[commands]]
src = "Pictures"
target = "pics-%Y-%m-%d"
delete_extra = false
```

Leading comment lines directly at the top of the file are treated as the configuration description and are shown by `yd ls`.

### Top-level options

| Key | Meaning |
| --- | --- |
| `src_home` | Base directory for all `src` paths. Relative paths are resolved from your home directory. |
| `target_home` | Base directory for all target paths. Relative paths are resolved from your home directory. |
| `mtp_target` | Use in-place syncing for MTP targets. |
| `backup` | Backup directory for replaced or deleted files. Relative paths are resolved from `target_home`. `strftime` placeholders are supported. |
| `exclude` | Exclude patterns applied to every command. |

`mtp_target` matters because `rsync` normally copies to a temporary file and renames it afterward, but that is not possible when syncing via *MTP*.

### Command options

| Key | Meaning |
| --- | --- |
| `src` | Relative source directory below `src_home`. |
| `target` | Relative target directory below `target_home`; defaults to `src`. `strftime` placeholders (`%Y`, `%m`, and `%d` only!) are supported. |
| `delete_extra` | Delete files in the target that do not exist in the source. Defaults to `true`. |
| `exclude` | Extra exclude patterns for this command only. |

### Notes

- `src` and `target` must stay within `src_home` and `target_home` after path resolution.
- `src_home` or `target_home` may be omitted from the configuration, but every missing value must then be supplied when running (via CLI parameters).
- Exactly one of `--src-home -` and `--target-home -` may read from standard input in a single run.
- If `backup` is omitted, `yd` creates a timestamped backup directory automatically unless `--no-backup` is specified.
- If a configured source directory exists but is empty, `yd` reports that no synchronization was performed for that command. E.g., forgetting to mount an external drive does not delete all corresponding copies on harddrive).
- If `strftime` placeholders are included in the `target`, then the `target_home` is scanned for directories that may have been created by this rule in the past. All matches are included as additional references in the synchronization: if a file in `src` is included in one of those reference directories, then it will not be copied to `target`.
- If the `target` directory did not exist before and no files are transferred into it, then it will be removed again.

## Run a config

Run a saved configuration by name:

```bash
yd run photos
```

### Options

| Option | Meaning |
| --- | --- |
| `--dry-run` | Show what would happen without changing files. |
| `--no-backup` | Disable backup handling for this run. |
| `--keep-newer` | Skip updates when the target file is newer. |
| `--rename-speedup` | Enable `rsync` options tuned for rename-heavy targets. This may require more disk space on the target. |
| `--src-home PATH` | Override `src_home` from the config. Use `-` to read the value from standard input. |
| `--target-home PATH` | Override `target_home` from the config. Use `-` to read the value from standard input. |

## List configs

List available configurations with:

```bash
yd ls
```

This shows the configuration name together with the optional leading-comment description.

## Why `yd`?

- Has one character from `synchronize` and one from `directory`.
- Easy to type with both *QWERTZ* and *QUERTY* keyboards.
- Name was still available on *PyPI*.
