dotx 2.1.0__tar.gz → 2.2.0__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.
- {dotx-2.1.0/src/dotx.egg-info → dotx-2.2.0}/PKG-INFO +106 -51
- {dotx-2.1.0 → dotx-2.2.0}/README.md +105 -50
- {dotx-2.1.0 → dotx-2.2.0}/pyproject.toml +1 -1
- dotx-2.2.0/src/dotx/cli.py +119 -0
- dotx-2.2.0/src/dotx/commands/__init__.py +1 -0
- dotx-2.2.0/src/dotx/commands/database.py +430 -0
- dotx-2.2.0/src/dotx/commands/install_cmd.py +117 -0
- dotx-2.2.0/src/dotx/commands/uninstall_cmd.py +90 -0
- {dotx-2.1.0 → dotx-2.2.0/src/dotx.egg-info}/PKG-INFO +106 -51
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx.egg-info/SOURCES.txt +4 -0
- dotx-2.2.0/tests/test_cli.py +248 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_cli_database.py +126 -0
- dotx-2.1.0/src/dotx/cli.py +0 -622
- dotx-2.1.0/tests/test_cli.py +0 -30
- {dotx-2.1.0 → dotx-2.2.0}/LICENSE +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/MANIFEST.in +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/setup.cfg +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/__init__.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/database.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/ignore.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/install.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/installed-schema.sql +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/options.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/plan.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx/uninstall.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx.egg-info/dependency_links.txt +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx.egg-info/entry_points.txt +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx.egg-info/requires.txt +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/src/dotx.egg-info/top_level.txt +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_ignore.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_ignore_rules.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_install.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_options.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_plan.py +0 -0
- {dotx-2.1.0 → dotx-2.2.0}/tests/test_uninstall.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotx
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A command-line tool to install a link-farm to your dotfiles
|
|
5
5
|
Author-email: Wolf <Wolf@zv.cx>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -241,15 +241,78 @@ Installations:
|
|
|
241
241
|
|
|
242
242
|
#### Rebuild database from filesystem
|
|
243
243
|
|
|
244
|
-
If you have existing dotfile installations and an empty or missing database, use `sync` to rebuild it
|
|
244
|
+
If you have existing dotfile installations and an empty or missing database, use `sync` to rebuild it.
|
|
245
245
|
|
|
246
|
+
##### The Problem: Unwanted Symlinks
|
|
247
|
+
|
|
248
|
+
By default, `sync` scans your home directory and `~/.config` for **all** symlinks. This can discover symlinks you don't want to track as dotfiles packages, such as:
|
|
249
|
+
- System symlinks in `~/Library/` (macOS)
|
|
250
|
+
- Application symlinks in `/Applications/`
|
|
251
|
+
- IDE or tool-generated symlinks
|
|
252
|
+
- Homebrew-managed symlinks
|
|
253
|
+
|
|
254
|
+
For example, without filtering you might see:
|
|
246
255
|
```bash
|
|
247
|
-
# Preview what would be added to database
|
|
248
256
|
+$ dotx sync --dry-run
|
|
257
|
+
✓ Found 44 symlink(s)
|
|
258
|
+
|
|
259
|
+
Discovered 25 potential package(s):
|
|
260
|
+
/Users/wolf/dotfiles/bash # ✓ Want this
|
|
261
|
+
5 symlink(s)
|
|
262
|
+
/Users/wolf/dotfiles/vim # ✓ Want this
|
|
263
|
+
8 symlink(s)
|
|
264
|
+
/Users/wolf/Library # ✗ Don't want this!
|
|
265
|
+
1 symlink(s)
|
|
266
|
+
/Applications/Raycast.app/... # ✗ Don't want this!
|
|
267
|
+
1 symlink(s)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
##### The Solution: `--package-root`
|
|
249
271
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
272
|
+
Use `--package-root` to filter packages to **only** those under specific directories. This is **strongly recommended** to avoid tracking unwanted symlinks:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Filter to only your dotfiles directory
|
|
276
|
+
+$ dotx sync --dry-run --package-root ~/dotfiles
|
|
277
|
+
✓ Found 44 symlink(s)
|
|
278
|
+
Filtered out 6 symlink(s) not under --package-root
|
|
279
|
+
|
|
280
|
+
Discovered 3 potential package(s):
|
|
281
|
+
/Users/wolf/dotfiles/bash
|
|
282
|
+
5 symlink(s)
|
|
283
|
+
/Users/wolf/dotfiles/vim
|
|
284
|
+
8 symlink(s)
|
|
285
|
+
/Users/wolf/dotfiles/git
|
|
286
|
+
2 symlink(s)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
You can specify multiple roots if your packages are in different locations:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
+$ dotx sync --package-root ~/dotfiles --package-root ~/work/configs
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
##### Safety Warning
|
|
296
|
+
|
|
297
|
+
If you run `sync` without `--package-root` and have an empty database, you'll see a warning:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
+$ dotx sync --dry-run
|
|
301
|
+
✓ Found 44 symlink(s)
|
|
302
|
+
⚠ Warning: No --package-root specified and database is empty.
|
|
303
|
+
Consider using --package-root to filter packages (e.g., --package-root ~/dotfiles)
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
##### Complete Example
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Preview what will be synced (recommended first step)
|
|
310
|
+
+$ dotx sync --dry-run --package-root ~/dotfiles
|
|
311
|
+
|
|
312
|
+
# After reviewing, sync for real
|
|
313
|
+
+$ dotx sync --package-root ~/dotfiles
|
|
314
|
+
✓ Found 15 symlink(s)
|
|
315
|
+
Filtered out 0 symlink(s) not under --package-root
|
|
253
316
|
|
|
254
317
|
Discovered 3 potential package(s):
|
|
255
318
|
/Users/wolf/dotfiles/bash
|
|
@@ -265,66 +328,58 @@ Continue? [y/N]: y
|
|
|
265
328
|
✓ Recorded 15 installation(s) in database.
|
|
266
329
|
```
|
|
267
330
|
|
|
268
|
-
The `sync` command
|
|
331
|
+
**Note:** The `sync` command is **additive** - it updates existing entries and adds new ones, but doesn't delete entries for packages not found. This means running sync with `--package-root` won't remove other packages from your database.
|
|
269
332
|
|
|
270
|
-
|
|
333
|
+
##### Cleaning Orphaned Entries with `--clean`
|
|
271
334
|
|
|
272
|
-
|
|
335
|
+
Over time, your database may accumulate **orphaned entries** - records for symlinks that no longer exist on the filesystem. Use `--clean` to remove these automatically, similar to `git fetch --prune`:
|
|
273
336
|
|
|
274
|
-
|
|
337
|
+
```bash
|
|
338
|
+
# Preview what would be cleaned
|
|
339
|
+
+$ dotx sync --dry-run --clean --package-root ~/dotfiles
|
|
340
|
+
✓ Found 15 symlink(s)
|
|
275
341
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
- **Bug fix**: Database now correctly stores symlink paths instead of resolved paths
|
|
342
|
+
Would clean orphaned entries:
|
|
343
|
+
bash: 2 orphaned entry(ies)
|
|
344
|
+
vim: 1 orphaned entry(ies)
|
|
345
|
+
Would remove 3 orphaned entry(ies).
|
|
281
346
|
|
|
282
|
-
|
|
283
|
-
- Added Development section with testing, pre-commit hooks, and integration testing docs
|
|
284
|
-
- Added clean-up instructions for development artifacts
|
|
285
|
-
- Coverage reports available via `open htmlcov/index.html`
|
|
347
|
+
Dry run - no database changes made.
|
|
286
348
|
|
|
287
|
-
|
|
349
|
+
# Clean for real
|
|
350
|
+
+$ dotx sync --clean --package-root ~/dotfiles
|
|
351
|
+
✓ Found 15 symlink(s)
|
|
352
|
+
Filtered out 0 symlink(s) not under --package-root
|
|
288
353
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
- Export reinstall commands with `dotx list --as-commands` for easy migration
|
|
354
|
+
Discovered 3 potential package(s):
|
|
355
|
+
/Users/wolf/dotfiles/bash
|
|
356
|
+
5 symlink(s)
|
|
357
|
+
...
|
|
294
358
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- Full gitignore-style pattern syntax support
|
|
298
|
-
- Nested `.dotxignore` files in subdirectories
|
|
299
|
-
- Global ignore file at `~/.config/dotx/ignore`
|
|
300
|
-
- Negation patterns (`!important.conf`)
|
|
359
|
+
This will rebuild the database with the discovered installations.
|
|
360
|
+
Continue? [y/N]: y
|
|
301
361
|
|
|
302
|
-
|
|
303
|
-
- Pre-commit hooks with ruff, pyrefly, pytest
|
|
304
|
-
- Modern Python type annotations throughout
|
|
305
|
-
- Better logging with loguru
|
|
306
|
-
- Comprehensive code documentation and comments
|
|
362
|
+
✓ Recorded 15 installation(s) in database.
|
|
307
363
|
|
|
308
|
-
|
|
364
|
+
Cleaning orphaned entries...
|
|
365
|
+
✓ Removed 3 orphaned entry(ies).
|
|
366
|
+
```
|
|
309
367
|
|
|
310
|
-
**
|
|
368
|
+
**When to use `--clean`:**
|
|
369
|
+
- After manually removing symlinks
|
|
370
|
+
- After uninstalling packages without using `dotx uninstall`
|
|
371
|
+
- During regular maintenance to keep database accurate
|
|
372
|
+
- When migrating or reorganizing dotfiles
|
|
311
373
|
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
dotx --ignore=README.* --ignore=.mypy_cache install bash
|
|
315
|
-
```
|
|
374
|
+
**Important:** `--clean` removes database entries for files that don't exist. Always preview with `--dry-run` first to ensure you're not removing entries you want to keep.
|
|
316
375
|
|
|
317
|
-
|
|
318
|
-
```bash
|
|
319
|
-
+$ cat > bash/.dotxignore <<EOF
|
|
320
|
-
README.*
|
|
321
|
-
.mypy_cache
|
|
322
|
-
EOF
|
|
376
|
+
### How it works
|
|
323
377
|
|
|
324
|
-
|
|
325
|
-
|
|
378
|
+
*Documentation to be expanded*
|
|
379
|
+
|
|
380
|
+
### Changelog
|
|
326
381
|
|
|
327
|
-
|
|
382
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history and release notes.
|
|
328
383
|
|
|
329
384
|
## Development
|
|
330
385
|
|
|
@@ -213,15 +213,78 @@ Installations:
|
|
|
213
213
|
|
|
214
214
|
#### Rebuild database from filesystem
|
|
215
215
|
|
|
216
|
-
If you have existing dotfile installations and an empty or missing database, use `sync` to rebuild it
|
|
216
|
+
If you have existing dotfile installations and an empty or missing database, use `sync` to rebuild it.
|
|
217
217
|
|
|
218
|
+
##### The Problem: Unwanted Symlinks
|
|
219
|
+
|
|
220
|
+
By default, `sync` scans your home directory and `~/.config` for **all** symlinks. This can discover symlinks you don't want to track as dotfiles packages, such as:
|
|
221
|
+
- System symlinks in `~/Library/` (macOS)
|
|
222
|
+
- Application symlinks in `/Applications/`
|
|
223
|
+
- IDE or tool-generated symlinks
|
|
224
|
+
- Homebrew-managed symlinks
|
|
225
|
+
|
|
226
|
+
For example, without filtering you might see:
|
|
218
227
|
```bash
|
|
219
|
-
# Preview what would be added to database
|
|
220
228
|
+$ dotx sync --dry-run
|
|
229
|
+
✓ Found 44 symlink(s)
|
|
230
|
+
|
|
231
|
+
Discovered 25 potential package(s):
|
|
232
|
+
/Users/wolf/dotfiles/bash # ✓ Want this
|
|
233
|
+
5 symlink(s)
|
|
234
|
+
/Users/wolf/dotfiles/vim # ✓ Want this
|
|
235
|
+
8 symlink(s)
|
|
236
|
+
/Users/wolf/Library # ✗ Don't want this!
|
|
237
|
+
1 symlink(s)
|
|
238
|
+
/Applications/Raycast.app/... # ✗ Don't want this!
|
|
239
|
+
1 symlink(s)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
##### The Solution: `--package-root`
|
|
221
243
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
244
|
+
Use `--package-root` to filter packages to **only** those under specific directories. This is **strongly recommended** to avoid tracking unwanted symlinks:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Filter to only your dotfiles directory
|
|
248
|
+
+$ dotx sync --dry-run --package-root ~/dotfiles
|
|
249
|
+
✓ Found 44 symlink(s)
|
|
250
|
+
Filtered out 6 symlink(s) not under --package-root
|
|
251
|
+
|
|
252
|
+
Discovered 3 potential package(s):
|
|
253
|
+
/Users/wolf/dotfiles/bash
|
|
254
|
+
5 symlink(s)
|
|
255
|
+
/Users/wolf/dotfiles/vim
|
|
256
|
+
8 symlink(s)
|
|
257
|
+
/Users/wolf/dotfiles/git
|
|
258
|
+
2 symlink(s)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
You can specify multiple roots if your packages are in different locations:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
+$ dotx sync --package-root ~/dotfiles --package-root ~/work/configs
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
##### Safety Warning
|
|
268
|
+
|
|
269
|
+
If you run `sync` without `--package-root` and have an empty database, you'll see a warning:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
+$ dotx sync --dry-run
|
|
273
|
+
✓ Found 44 symlink(s)
|
|
274
|
+
⚠ Warning: No --package-root specified and database is empty.
|
|
275
|
+
Consider using --package-root to filter packages (e.g., --package-root ~/dotfiles)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
##### Complete Example
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Preview what will be synced (recommended first step)
|
|
282
|
+
+$ dotx sync --dry-run --package-root ~/dotfiles
|
|
283
|
+
|
|
284
|
+
# After reviewing, sync for real
|
|
285
|
+
+$ dotx sync --package-root ~/dotfiles
|
|
286
|
+
✓ Found 15 symlink(s)
|
|
287
|
+
Filtered out 0 symlink(s) not under --package-root
|
|
225
288
|
|
|
226
289
|
Discovered 3 potential package(s):
|
|
227
290
|
/Users/wolf/dotfiles/bash
|
|
@@ -237,66 +300,58 @@ Continue? [y/N]: y
|
|
|
237
300
|
✓ Recorded 15 installation(s) in database.
|
|
238
301
|
```
|
|
239
302
|
|
|
240
|
-
The `sync` command
|
|
303
|
+
**Note:** The `sync` command is **additive** - it updates existing entries and adds new ones, but doesn't delete entries for packages not found. This means running sync with `--package-root` won't remove other packages from your database.
|
|
241
304
|
|
|
242
|
-
|
|
305
|
+
##### Cleaning Orphaned Entries with `--clean`
|
|
243
306
|
|
|
244
|
-
|
|
307
|
+
Over time, your database may accumulate **orphaned entries** - records for symlinks that no longer exist on the filesystem. Use `--clean` to remove these automatically, similar to `git fetch --prune`:
|
|
245
308
|
|
|
246
|
-
|
|
309
|
+
```bash
|
|
310
|
+
# Preview what would be cleaned
|
|
311
|
+
+$ dotx sync --dry-run --clean --package-root ~/dotfiles
|
|
312
|
+
✓ Found 15 symlink(s)
|
|
247
313
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
- **Bug fix**: Database now correctly stores symlink paths instead of resolved paths
|
|
314
|
+
Would clean orphaned entries:
|
|
315
|
+
bash: 2 orphaned entry(ies)
|
|
316
|
+
vim: 1 orphaned entry(ies)
|
|
317
|
+
Would remove 3 orphaned entry(ies).
|
|
253
318
|
|
|
254
|
-
|
|
255
|
-
- Added Development section with testing, pre-commit hooks, and integration testing docs
|
|
256
|
-
- Added clean-up instructions for development artifacts
|
|
257
|
-
- Coverage reports available via `open htmlcov/index.html`
|
|
319
|
+
Dry run - no database changes made.
|
|
258
320
|
|
|
259
|
-
|
|
321
|
+
# Clean for real
|
|
322
|
+
+$ dotx sync --clean --package-root ~/dotfiles
|
|
323
|
+
✓ Found 15 symlink(s)
|
|
324
|
+
Filtered out 0 symlink(s) not under --package-root
|
|
260
325
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
- Export reinstall commands with `dotx list --as-commands` for easy migration
|
|
326
|
+
Discovered 3 potential package(s):
|
|
327
|
+
/Users/wolf/dotfiles/bash
|
|
328
|
+
5 symlink(s)
|
|
329
|
+
...
|
|
266
330
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- Full gitignore-style pattern syntax support
|
|
270
|
-
- Nested `.dotxignore` files in subdirectories
|
|
271
|
-
- Global ignore file at `~/.config/dotx/ignore`
|
|
272
|
-
- Negation patterns (`!important.conf`)
|
|
331
|
+
This will rebuild the database with the discovered installations.
|
|
332
|
+
Continue? [y/N]: y
|
|
273
333
|
|
|
274
|
-
|
|
275
|
-
- Pre-commit hooks with ruff, pyrefly, pytest
|
|
276
|
-
- Modern Python type annotations throughout
|
|
277
|
-
- Better logging with loguru
|
|
278
|
-
- Comprehensive code documentation and comments
|
|
334
|
+
✓ Recorded 15 installation(s) in database.
|
|
279
335
|
|
|
280
|
-
|
|
336
|
+
Cleaning orphaned entries...
|
|
337
|
+
✓ Removed 3 orphaned entry(ies).
|
|
338
|
+
```
|
|
281
339
|
|
|
282
|
-
**
|
|
340
|
+
**When to use `--clean`:**
|
|
341
|
+
- After manually removing symlinks
|
|
342
|
+
- After uninstalling packages without using `dotx uninstall`
|
|
343
|
+
- During regular maintenance to keep database accurate
|
|
344
|
+
- When migrating or reorganizing dotfiles
|
|
283
345
|
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
dotx --ignore=README.* --ignore=.mypy_cache install bash
|
|
287
|
-
```
|
|
346
|
+
**Important:** `--clean` removes database entries for files that don't exist. Always preview with `--dry-run` first to ensure you're not removing entries you want to keep.
|
|
288
347
|
|
|
289
|
-
|
|
290
|
-
```bash
|
|
291
|
-
+$ cat > bash/.dotxignore <<EOF
|
|
292
|
-
README.*
|
|
293
|
-
.mypy_cache
|
|
294
|
-
EOF
|
|
348
|
+
### How it works
|
|
295
349
|
|
|
296
|
-
|
|
297
|
-
|
|
350
|
+
*Documentation to be expanded*
|
|
351
|
+
|
|
352
|
+
### Changelog
|
|
298
353
|
|
|
299
|
-
|
|
354
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history and release notes.
|
|
300
355
|
|
|
301
356
|
## Development
|
|
302
357
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for dotx.
|
|
3
|
+
|
|
4
|
+
This module defines the CLI app structure and global options. Individual commands
|
|
5
|
+
are defined in the commands subpackage.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Annotated, Optional
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
import typer
|
|
14
|
+
from loguru import logger
|
|
15
|
+
|
|
16
|
+
from dotx import __version__, __homepage__
|
|
17
|
+
from dotx.options import set_option
|
|
18
|
+
|
|
19
|
+
# Create the Typer app
|
|
20
|
+
app = typer.Typer(
|
|
21
|
+
help="Manage a link farm: (un)install groups of links from source packages.",
|
|
22
|
+
no_args_is_help=True,
|
|
23
|
+
epilog=f"dotx version {__version__} | {__homepage__}",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def version_callback(value: bool):
|
|
28
|
+
"""Handle --version flag."""
|
|
29
|
+
if value:
|
|
30
|
+
typer.echo(f"dotx version {__version__}")
|
|
31
|
+
raise typer.Exit()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def configure_logging(debug: bool, verbose: bool, log: Optional[Path]):
|
|
35
|
+
"""Configure logging based on CLI options."""
|
|
36
|
+
logger.remove() # Remove default handler
|
|
37
|
+
|
|
38
|
+
# Determine log level
|
|
39
|
+
if debug:
|
|
40
|
+
level = "DEBUG"
|
|
41
|
+
elif verbose:
|
|
42
|
+
level = "INFO"
|
|
43
|
+
else:
|
|
44
|
+
level = "WARNING"
|
|
45
|
+
|
|
46
|
+
# Add handler
|
|
47
|
+
if log:
|
|
48
|
+
logger.add(log, level=level)
|
|
49
|
+
else:
|
|
50
|
+
logger.add(sys.stderr, level=level)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@app.callback()
|
|
54
|
+
def main(
|
|
55
|
+
ctx: click.Context,
|
|
56
|
+
debug: Annotated[
|
|
57
|
+
bool,
|
|
58
|
+
typer.Option("--debug/--no-debug", help="Enable debug logging"),
|
|
59
|
+
] = False,
|
|
60
|
+
verbose: Annotated[
|
|
61
|
+
bool,
|
|
62
|
+
typer.Option("--verbose/--quiet", help="Enable verbose output / suppress output"),
|
|
63
|
+
] = False,
|
|
64
|
+
log: Annotated[
|
|
65
|
+
Optional[Path],
|
|
66
|
+
typer.Option(help="Where to write the log (defaults to stderr)"),
|
|
67
|
+
] = None,
|
|
68
|
+
target: Annotated[
|
|
69
|
+
Optional[Path],
|
|
70
|
+
typer.Option(
|
|
71
|
+
help="Where to install (defaults to $HOME)",
|
|
72
|
+
exists=True,
|
|
73
|
+
file_okay=False,
|
|
74
|
+
dir_okay=True,
|
|
75
|
+
writable=True,
|
|
76
|
+
),
|
|
77
|
+
] = None,
|
|
78
|
+
dry_run: Annotated[
|
|
79
|
+
bool,
|
|
80
|
+
typer.Option("--dry-run/--no-dry-run", help="Just echo; don't actually (un)install"),
|
|
81
|
+
] = False,
|
|
82
|
+
version: Annotated[
|
|
83
|
+
Optional[bool],
|
|
84
|
+
typer.Option("--version", "-V", callback=version_callback, is_eager=True, help="Show version and exit."),
|
|
85
|
+
] = None,
|
|
86
|
+
):
|
|
87
|
+
"""
|
|
88
|
+
Manage a link farm: (un)install groups of links from source packages.
|
|
89
|
+
|
|
90
|
+
Global options like --debug, --verbose, and --target apply to all commands.
|
|
91
|
+
"""
|
|
92
|
+
configure_logging(debug, verbose, log)
|
|
93
|
+
|
|
94
|
+
# Store options in context for commands to access
|
|
95
|
+
ctx.ensure_object(dict)
|
|
96
|
+
if target:
|
|
97
|
+
ctx.obj["TARGET"] = target
|
|
98
|
+
set_option("TARGET", target, ctx)
|
|
99
|
+
|
|
100
|
+
# Set global options
|
|
101
|
+
set_option("DEBUG", debug, ctx)
|
|
102
|
+
set_option("VERBOSE", verbose, ctx)
|
|
103
|
+
set_option("DRYRUN", dry_run, ctx)
|
|
104
|
+
|
|
105
|
+
if log:
|
|
106
|
+
set_option("LOG", log, ctx)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# Register commands from submodules
|
|
110
|
+
from dotx.commands import install_cmd, uninstall_cmd, database
|
|
111
|
+
|
|
112
|
+
install_cmd.register_command(app)
|
|
113
|
+
uninstall_cmd.register_command(app)
|
|
114
|
+
database.register_commands(app)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def cli():
|
|
118
|
+
"""Entry point for the CLI."""
|
|
119
|
+
app()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI commands for dotx."""
|