yd-cli 0.10__tar.gz → 0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {yd_cli-0.10 → yd_cli-0.12}/PKG-INFO +40 -9
- {yd_cli-0.10 → yd_cli-0.12}/README.md +36 -5
- {yd_cli-0.10 → yd_cli-0.12}/pyproject.toml +15 -17
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/__init__.py +0 -2
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/__main__.py +0 -2
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/cli.py +296 -126
- yd_cli-0.12/src/yd/commands.py +626 -0
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/echo.py +0 -2
- yd_cli-0.12/src/yd/execution.py +307 -0
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/io.py +155 -26
- yd_cli-0.12/src/yd/logger.py +29 -0
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/types.py +100 -43
- yd_cli-0.10/src/yd/commands.py +0 -258
- yd_cli-0.10/src/yd/execution.py +0 -153
- {yd_cli-0.10 → yd_cli-0.12}/LICENSES/MIT.txt +0 -0
- {yd_cli-0.10 → yd_cli-0.12}/src/yd/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yd-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12
|
|
4
4
|
Summary: CLI tool to synchronize directories using rsync.
|
|
5
5
|
Author: Christian Heinze
|
|
6
6
|
License-Expression: MIT
|
|
@@ -14,9 +14,9 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
14
14
|
Classifier: Topic :: System :: Archiving
|
|
15
15
|
Classifier: Topic :: Utilities
|
|
16
16
|
Classifier: Typing :: Typed
|
|
17
|
-
Requires-Dist: msgspec>=0.
|
|
18
|
-
Requires-Dist: rich>=
|
|
19
|
-
Requires-Dist: typer>=0.
|
|
17
|
+
Requires-Dist: msgspec>=0.21
|
|
18
|
+
Requires-Dist: rich>=15
|
|
19
|
+
Requires-Dist: typer>=0.26
|
|
20
20
|
Requires-Python: >=3.14
|
|
21
21
|
Project-URL: Repository, https://codeberg.org/christianheinze/yd-cli
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
@@ -25,6 +25,26 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
|
|
26
26
|
Build and execute `rsync` commands from *TOML* configuration files.
|
|
27
27
|
|
|
28
|
+
## (Un)Install
|
|
29
|
+
|
|
30
|
+
To install, run
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install yd-cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then run
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
yd --install-completion
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
to install auto-completion in your shell.
|
|
43
|
+
|
|
44
|
+
In `bash`, the completion code is stored in `~/.bash_completions/yd.sh` and that file is sourced from `~/.bashrc`.
|
|
45
|
+
Remove both and call `uv tool uninstall yd-cli` to remove this tool.
|
|
46
|
+
The below mentioned configuration files need to be removed separately.
|
|
47
|
+
|
|
28
48
|
## Create a config
|
|
29
49
|
|
|
30
50
|
Create a new configuration called `photos` with:
|
|
@@ -36,7 +56,7 @@ yd edit --new photos
|
|
|
36
56
|
This command
|
|
37
57
|
|
|
38
58
|
- creates `~/.config/yd/photos.toml` (or under `$XDG_CONFIG_HOME/yd` if set; relative paths are resolved from your home directory), and
|
|
39
|
-
- opens it
|
|
59
|
+
- opens it with the executable selected via `EDITOR`, or `nvim` when `EDITOR` is unset.
|
|
40
60
|
|
|
41
61
|
Reopen an existing configuration with:
|
|
42
62
|
|
|
@@ -72,7 +92,7 @@ Leading comment lines directly at the top of the file are treated as the configu
|
|
|
72
92
|
| Key | Meaning |
|
|
73
93
|
| --- | --- |
|
|
74
94
|
| `src_home` | Base directory for all `src` paths. Relative paths are resolved from your home directory. |
|
|
75
|
-
| `target_home` | Base directory for all target paths. Relative paths are resolved from your home directory.
|
|
95
|
+
| `target_home` | Base directory for all target paths. Relative paths are resolved from your home directory. |
|
|
76
96
|
| `mtp_target` | Use in-place syncing for MTP targets. |
|
|
77
97
|
| `backup` | Backup directory for replaced or deleted files. Relative paths are resolved from `target_home`. `strftime` placeholders are supported. |
|
|
78
98
|
| `exclude` | Exclude patterns applied to every command. |
|
|
@@ -84,17 +104,20 @@ Leading comment lines directly at the top of the file are treated as the configu
|
|
|
84
104
|
| Key | Meaning |
|
|
85
105
|
| --- | --- |
|
|
86
106
|
| `src` | Relative source directory below `src_home`. |
|
|
87
|
-
| `target` | Relative target directory below `target_home`; defaults to `src`. `strftime` placeholders are supported. |
|
|
107
|
+
| `target` | Relative target directory below `target_home`; defaults to `src`. `strftime` placeholders (`%Y`, `%m`, and `%d` only!) are supported. A newly created dated target is removed if it contains only directories after synchronization. |
|
|
88
108
|
| `delete_extra` | Delete files in the target that do not exist in the source. Defaults to `true`. |
|
|
89
109
|
| `exclude` | Extra exclude patterns for this command only. |
|
|
90
110
|
|
|
91
111
|
### Notes
|
|
92
112
|
|
|
93
113
|
- `src` and `target` must stay within `src_home` and `target_home` after path resolution.
|
|
114
|
+
- Literal targets are retained when they contain only empty directories. Dated targets serve as snapshots: if a dated target did not exist before synchronization and contains neither files nor symlinks afterward, `yd` removes its empty directory tree.
|
|
94
115
|
- `src_home` or `target_home` may be omitted from the configuration, but every missing value must then be supplied when running (via CLI parameters).
|
|
95
116
|
- Exactly one of `--src-home -` and `--target-home -` may read from standard input in a single run.
|
|
96
117
|
- If `backup` is omitted, `yd` creates a timestamped backup directory automatically unless `--no-backup` is specified.
|
|
97
|
-
- 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
|
|
118
|
+
- 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 hard-drive.
|
|
119
|
+
- If `strftime` placeholders are included in the `target`, then the `target_home` is scanned for matching directories (possibly) created by this rule before today.
|
|
120
|
+
The 20 most recent matches are included as additional comparison destinations in the synchronization: if a file in `src` is included in one of those reference directories, then it will not be copied to `target`.
|
|
98
121
|
|
|
99
122
|
## Run a config
|
|
100
123
|
|
|
@@ -115,6 +138,14 @@ yd run photos
|
|
|
115
138
|
| `--src-home PATH` | Override `src_home` from the config. Use `-` to read the value from standard input. |
|
|
116
139
|
| `--target-home PATH` | Override `target_home` from the config. Use `-` to read the value from standard input. |
|
|
117
140
|
|
|
141
|
+
## Logging
|
|
142
|
+
|
|
143
|
+
Set `YD_LOGLEVEL` to a numeric [Python logging level](https://docs.python.org/3/library/logging.html#logging-levels), such as `10` for debug, `20` for info, or `40` for errors.
|
|
144
|
+
When set, `yd` appends *JSON* Lines records to `.yd.jsonl` in the current working directory.
|
|
145
|
+
Records contain `time`, `level`, `logger`, and `message` fields, plus exception `type`, `message`, and `traceback` when applicable.
|
|
146
|
+
|
|
147
|
+
Logging is effectively disabled by default. Enable it when diagnosing a failed or interrupted run.
|
|
148
|
+
|
|
118
149
|
## List configs
|
|
119
150
|
|
|
120
151
|
List available configurations with:
|
|
@@ -128,5 +159,5 @@ This shows the configuration name together with the optional leading-comment des
|
|
|
128
159
|
## Why `yd`?
|
|
129
160
|
|
|
130
161
|
- Has one character from `synchronize` and one from `directory`.
|
|
131
|
-
- Easy to type with both *QWERTZ* and *
|
|
162
|
+
- Easy to type with both *QWERTZ* and *QWERTY* keyboards.
|
|
132
163
|
- Name was still available on *PyPI*.
|
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Build and execute `rsync` commands from *TOML* configuration files.
|
|
4
4
|
|
|
5
|
+
## (Un)Install
|
|
6
|
+
|
|
7
|
+
To install, run
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv tool install yd-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then run
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yd --install-completion
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
to install auto-completion in your shell.
|
|
20
|
+
|
|
21
|
+
In `bash`, the completion code is stored in `~/.bash_completions/yd.sh` and that file is sourced from `~/.bashrc`.
|
|
22
|
+
Remove both and call `uv tool uninstall yd-cli` to remove this tool.
|
|
23
|
+
The below mentioned configuration files need to be removed separately.
|
|
24
|
+
|
|
5
25
|
## Create a config
|
|
6
26
|
|
|
7
27
|
Create a new configuration called `photos` with:
|
|
@@ -13,7 +33,7 @@ yd edit --new photos
|
|
|
13
33
|
This command
|
|
14
34
|
|
|
15
35
|
- creates `~/.config/yd/photos.toml` (or under `$XDG_CONFIG_HOME/yd` if set; relative paths are resolved from your home directory), and
|
|
16
|
-
- opens it
|
|
36
|
+
- opens it with the executable selected via `EDITOR`, or `nvim` when `EDITOR` is unset.
|
|
17
37
|
|
|
18
38
|
Reopen an existing configuration with:
|
|
19
39
|
|
|
@@ -49,7 +69,7 @@ Leading comment lines directly at the top of the file are treated as the configu
|
|
|
49
69
|
| Key | Meaning |
|
|
50
70
|
| --- | --- |
|
|
51
71
|
| `src_home` | Base directory for all `src` paths. Relative paths are resolved from your home directory. |
|
|
52
|
-
| `target_home` | Base directory for all target paths. Relative paths are resolved from your home directory.
|
|
72
|
+
| `target_home` | Base directory for all target paths. Relative paths are resolved from your home directory. |
|
|
53
73
|
| `mtp_target` | Use in-place syncing for MTP targets. |
|
|
54
74
|
| `backup` | Backup directory for replaced or deleted files. Relative paths are resolved from `target_home`. `strftime` placeholders are supported. |
|
|
55
75
|
| `exclude` | Exclude patterns applied to every command. |
|
|
@@ -61,17 +81,20 @@ Leading comment lines directly at the top of the file are treated as the configu
|
|
|
61
81
|
| Key | Meaning |
|
|
62
82
|
| --- | --- |
|
|
63
83
|
| `src` | Relative source directory below `src_home`. |
|
|
64
|
-
| `target` | Relative target directory below `target_home`; defaults to `src`. `strftime` placeholders are supported. |
|
|
84
|
+
| `target` | Relative target directory below `target_home`; defaults to `src`. `strftime` placeholders (`%Y`, `%m`, and `%d` only!) are supported. A newly created dated target is removed if it contains only directories after synchronization. |
|
|
65
85
|
| `delete_extra` | Delete files in the target that do not exist in the source. Defaults to `true`. |
|
|
66
86
|
| `exclude` | Extra exclude patterns for this command only. |
|
|
67
87
|
|
|
68
88
|
### Notes
|
|
69
89
|
|
|
70
90
|
- `src` and `target` must stay within `src_home` and `target_home` after path resolution.
|
|
91
|
+
- Literal targets are retained when they contain only empty directories. Dated targets serve as snapshots: if a dated target did not exist before synchronization and contains neither files nor symlinks afterward, `yd` removes its empty directory tree.
|
|
71
92
|
- `src_home` or `target_home` may be omitted from the configuration, but every missing value must then be supplied when running (via CLI parameters).
|
|
72
93
|
- Exactly one of `--src-home -` and `--target-home -` may read from standard input in a single run.
|
|
73
94
|
- If `backup` is omitted, `yd` creates a timestamped backup directory automatically unless `--no-backup` is specified.
|
|
74
|
-
- 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
|
|
95
|
+
- 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 hard-drive.
|
|
96
|
+
- If `strftime` placeholders are included in the `target`, then the `target_home` is scanned for matching directories (possibly) created by this rule before today.
|
|
97
|
+
The 20 most recent matches are included as additional comparison destinations in the synchronization: if a file in `src` is included in one of those reference directories, then it will not be copied to `target`.
|
|
75
98
|
|
|
76
99
|
## Run a config
|
|
77
100
|
|
|
@@ -92,6 +115,14 @@ yd run photos
|
|
|
92
115
|
| `--src-home PATH` | Override `src_home` from the config. Use `-` to read the value from standard input. |
|
|
93
116
|
| `--target-home PATH` | Override `target_home` from the config. Use `-` to read the value from standard input. |
|
|
94
117
|
|
|
118
|
+
## Logging
|
|
119
|
+
|
|
120
|
+
Set `YD_LOGLEVEL` to a numeric [Python logging level](https://docs.python.org/3/library/logging.html#logging-levels), such as `10` for debug, `20` for info, or `40` for errors.
|
|
121
|
+
When set, `yd` appends *JSON* Lines records to `.yd.jsonl` in the current working directory.
|
|
122
|
+
Records contain `time`, `level`, `logger`, and `message` fields, plus exception `type`, `message`, and `traceback` when applicable.
|
|
123
|
+
|
|
124
|
+
Logging is effectively disabled by default. Enable it when diagnosing a failed or interrupted run.
|
|
125
|
+
|
|
95
126
|
## List configs
|
|
96
127
|
|
|
97
128
|
List available configurations with:
|
|
@@ -105,5 +136,5 @@ This shows the configuration name together with the optional leading-comment des
|
|
|
105
136
|
## Why `yd`?
|
|
106
137
|
|
|
107
138
|
- Has one character from `synchronize` and one from `directory`.
|
|
108
|
-
- Easy to type with both *QWERTZ* and *
|
|
139
|
+
- Easy to type with both *QWERTZ* and *QWERTY* keyboards.
|
|
109
140
|
- Name was still available on *PyPI*.
|
|
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.10,<0.12" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "yd-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12"
|
|
8
8
|
description = "CLI tool to synchronize directories using rsync."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -23,9 +23,9 @@ classifiers = [
|
|
|
23
23
|
"Typing :: Typed",
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
|
-
"msgspec>=0.
|
|
27
|
-
"rich>=
|
|
28
|
-
"typer>=0.
|
|
26
|
+
"msgspec>=0.21",
|
|
27
|
+
"rich>=15",
|
|
28
|
+
"typer>=0.26",
|
|
29
29
|
]
|
|
30
30
|
urls.Repository = "https://codeberg.org/christianheinze/yd-cli"
|
|
31
31
|
scripts.yd = "yd.cli:app"
|
|
@@ -38,9 +38,8 @@ dev = [
|
|
|
38
38
|
{ include-group = "test" },
|
|
39
39
|
]
|
|
40
40
|
test = [
|
|
41
|
-
|
|
41
|
+
"anyio>=4.12",
|
|
42
42
|
"pytest>=9",
|
|
43
|
-
"pytest-asyncio>=1.3",
|
|
44
43
|
"pytest-cov>=7",
|
|
45
44
|
"pytest-randomly>=4",
|
|
46
45
|
]
|
|
@@ -51,8 +50,8 @@ format = [
|
|
|
51
50
|
"ruff>=0.15.8",
|
|
52
51
|
]
|
|
53
52
|
lint = [
|
|
53
|
+
"pyrefly>=1",
|
|
54
54
|
"ruff>=0.15.8",
|
|
55
|
-
"ty>=0.0.27",
|
|
56
55
|
]
|
|
57
56
|
|
|
58
57
|
[tool.uv]
|
|
@@ -116,6 +115,7 @@ lint.select = [
|
|
|
116
115
|
lint.ignore = [
|
|
117
116
|
# Any allowed.
|
|
118
117
|
"ANN401",
|
|
118
|
+
# Using pathlib operations in coroutines is ok here.
|
|
119
119
|
"COM812",
|
|
120
120
|
"COM819",
|
|
121
121
|
# Missing documentation allowed.
|
|
@@ -173,28 +173,26 @@ lint.flake8-type-checking.runtime-evaluated-decorators = [
|
|
|
173
173
|
"pydantic.validate_call",
|
|
174
174
|
]
|
|
175
175
|
lint.flake8-unused-arguments.ignore-variadic-names = true
|
|
176
|
-
lint.isort.required-imports = [ "from __future__ import annotations" ]
|
|
177
176
|
|
|
178
177
|
[tool.pyproject-fmt]
|
|
179
178
|
column_width = 88
|
|
180
179
|
indent = 4
|
|
181
180
|
max_supported_python = "3.14"
|
|
182
181
|
|
|
183
|
-
[tool.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
182
|
+
[tool.pyrefly]
|
|
183
|
+
min-severity = "info"
|
|
184
|
+
preset = "strict"
|
|
185
|
+
project-includes = [ "src/**/*.py", "tests/**/*.py", "scripts/*.py" ]
|
|
186
|
+
use-ignore-files = false
|
|
188
187
|
|
|
189
188
|
[tool.pytest]
|
|
190
|
-
minversion = "9.0"
|
|
191
189
|
addopts = [
|
|
192
190
|
"--import-mode=importlib",
|
|
193
191
|
"--strict-markers",
|
|
194
192
|
"--cov=yd",
|
|
195
193
|
"--cov=tests",
|
|
196
194
|
]
|
|
197
|
-
testpaths = [ "tests" ]
|
|
198
|
-
python_files = [ "test_*.py" ]
|
|
199
195
|
filterwarnings = [ "error" ]
|
|
200
|
-
|
|
196
|
+
minversion = "9.0"
|
|
197
|
+
python_files = [ "test_*.py" ]
|
|
198
|
+
testpaths = [ "tests" ]
|