dazzlelink 0.8.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.
- dazzlelink-0.8.0/CHANGELOG.md +166 -0
- dazzlelink-0.8.0/CONTRIBUTING.md +77 -0
- dazzlelink-0.8.0/LICENSE +674 -0
- dazzlelink-0.8.0/MANIFEST.in +16 -0
- dazzlelink-0.8.0/PKG-INFO +316 -0
- dazzlelink-0.8.0/README.md +276 -0
- dazzlelink-0.8.0/SECURITY.md +50 -0
- dazzlelink-0.8.0/docs/COMMAND_REFERENCE.md +0 -0
- dazzlelink-0.8.0/docs/DAZZLE_DOCS.md +0 -0
- dazzlelink-0.8.0/docs/MODULE-README.md +91 -0
- dazzlelink-0.8.0/docs/RELINKER.md +0 -0
- dazzlelink-0.8.0/docs/ROADMAP.md +0 -0
- dazzlelink-0.8.0/docs/dev/Current Issues and Considerations.md +72 -0
- dazzlelink-0.8.0/docs/dev/UNC-lib Integration Plan.md +104 -0
- dazzlelink-0.8.0/examples/Roddenberry-Saturn.lnk.png.dazzlelink +64 -0
- dazzlelink-0.8.0/examples/Roddenberry-Saturn.png +0 -0
- dazzlelink-0.8.0/examples/workflow.png +0 -0
- dazzlelink-0.8.0/pyproject.toml +96 -0
- dazzlelink-0.8.0/setup.cfg +4 -0
- dazzlelink-0.8.0/src/dazzlelink/__init__.py +306 -0
- dazzlelink-0.8.0/src/dazzlelink/__main__.py +10 -0
- dazzlelink-0.8.0/src/dazzlelink/_version.py +83 -0
- dazzlelink-0.8.0/src/dazzlelink/cli.py +649 -0
- dazzlelink-0.8.0/src/dazzlelink/config.py +143 -0
- dazzlelink-0.8.0/src/dazzlelink/data.py +390 -0
- dazzlelink-0.8.0/src/dazzlelink/exceptions.py +7 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/__init__.py +71 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/batch.py +1100 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/core.py +519 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/links.py +618 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/recreate.py +307 -0
- dazzlelink-0.8.0/src/dazzlelink/operations/timestamps.py +665 -0
- dazzlelink-0.8.0/src/dazzlelink/path.py +188 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/PKG-INFO +316 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/SOURCES.txt +54 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/dependency_links.txt +1 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/entry_points.txt +2 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/requires.txt +13 -0
- dazzlelink-0.8.0/src/dazzlelink.egg-info/top_level.txt +1 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.7.0__Refactor__pypi-src-layout-migration__2026-06-11__results.md +215 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.7.2__Refactor__executable-generation-and-mode-precedence__2026-06-11__results-v2-postfix.md +172 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.7.2__Refactor__executable-generation-and-mode-precedence__2026-06-11__results.md +211 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.7.2__forkbomb-fix-verification__2026-06-11__results.md +209 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.7.5__rebase-and-info__2026-06-12__results.md +87 -0
- dazzlelink-0.8.0/tests/checklists/results/v0.8.0__release-gate__2026-06-12__results.md +202 -0
- dazzlelink-0.8.0/tests/checklists/v0.7.0__Refactor__pypi-src-layout-migration.md +378 -0
- dazzlelink-0.8.0/tests/checklists/v0.7.2__Refactor__executable-generation-and-mode-precedence.md +311 -0
- dazzlelink-0.8.0/tests/checklists/v0.7.4__Feature__copy-update-config-commands-and-exit-codes.md +181 -0
- dazzlelink-0.8.0/tests/checklists/v0.7.5__Feature__rebase-dazzlelink-files-and-info-display.md +168 -0
- dazzlelink-0.8.0/tests/checklists/v0.8.0__Epic__release-gate-full-regression.md +129 -0
- dazzlelink-0.8.0/tests/one-offs/verify_commit1_fixes.py +59 -0
- dazzlelink-0.8.0/tests/one-offs/verify_executable_runs.py +37 -0
- dazzlelink-0.8.0/tests/test_cli_commands.py +138 -0
- dazzlelink-0.8.0/tests/test_executable_and_mode_precedence.py +223 -0
- dazzlelink-0.8.0/tests/test_rebase_dazzlelinks_and_info.py +110 -0
- dazzlelink-0.8.0/tests/test_version.py +32 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# 📜 CHANGELOG.md - Dazzlelink
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [0.8.0] - 2026-06-12
|
|
8
|
+
|
|
9
|
+
**Milestone:** the installable `dazzlelink` package now has full capability parity with the legacy monolith (completed across 0.7.2-0.7.5), the monolith is deprecated, and the package is validated for PyPI.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- The legacy monolith (`legacy/dazzlelink_monolith.py`) prints a deprecation notice on invocation and is frozen -- all features and fixes land in the `dazzlelink` package, not the monolith (Refs #18).
|
|
13
|
+
- `.dazzlelink` and config-file reads now tolerate a leading UTF-8 BOM (`utf-8-sig`), so files hand-edited in BOM-writing tools (e.g. PowerShell `Set-Content -Encoding UTF8`) parse correctly instead of erroring.
|
|
14
|
+
|
|
15
|
+
### Notes
|
|
16
|
+
- Verified PyPI-ready: `python -m build` + `twine check` pass for both the wheel and sdist; the wheel includes the `dazzlelink.operations` subpackage. CLI subprocess test suite expanded (40 tests total).
|
|
17
|
+
|
|
18
|
+
## [0.7.5] - 2026-06-12
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `rebase` now also rebases `.dazzlelink` files (Refs #15): a second pass synchronizes the absolute and relative target paths stored *inside* each `.dazzlelink` JSON -- recompute the relative from a valid absolute, or the absolute from a valid relative; report files where both are broken (and leave those untouched). Previously `rebase` only rewrote live OS symlinks. The `rebase_dazzlelinks()` function is exported from the package.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `execute --mode info` now shows a richer display (Refs #18): the portable relative path, and a LIVE on-disk Exists/Size/Type check, falling back to the metadata stored at creation when the target is gone (previously it showed only the stored snapshot).
|
|
25
|
+
|
|
26
|
+
## [0.7.4] - 2026-06-12
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- `copy` command: copy symlinks to another location -- expands directories into their symlinks, preserves structure (`--preserve-structure`/`--base-dir`), converts relative/absolute (`--relative`/`--absolute`), verifies (`--no-verify`). Restores the monolith command the modular CLI never exposed (Refs #18).
|
|
30
|
+
- `update-config` command: batch-edit the embedded config of many `.dazzlelink` files (`--mode`, `--pattern`, `--recursive`, `--dry-run`, `--make-executable`, `--config-level`). Likewise restored (Refs #18).
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- `python -m dazzlelink` now propagates the command's exit code. The `__main__` entry called `main()` without `sys.exit()`, so every invocation exited 0 -- even on error -- which hid failures from scripts and CI.
|
|
34
|
+
- The top-level package now re-exports `update_config_batch` (previously only in `operations/`); an internal import depended on it.
|
|
35
|
+
|
|
36
|
+
## [0.7.3] - 2026-06-12
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- POSIX executable dazzlelink generation raised `NameError: name 'stat' is not defined` -- `links.py` used `stat` in the Unix chmod path without importing it (the Windows path never reached that branch, so it surfaced only on Linux CI). Added the missing import.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- CI (`python.yml`): added a lint step that fails on undefined names / syntax errors only (flake8 `E9,F63,F7,F82`, scoped to the package). Catches the missing-import class (a `NameError` that only fires on one platform) before the test run, without failing on style.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- `release.yml`: PyPI publish workflow using GitHub OIDC trusted publishing (no stored token), triggered when a GitHub Release is marked as the active, non-prerelease release (`release: [released]`), plus a manual `workflow_dispatch` for dry runs.
|
|
46
|
+
|
|
47
|
+
## [0.7.2] - 2026-06-11
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- **Fork bomb on `execute` of an executable dazzlelink (Refs #18).** `execute` ran a script-format `.dazzlelink` via `subprocess.run(..., shell=True)`, which on Windows re-invokes the `.dazzlelink` file association (itself `dazzlelink execute`) -- unbounded recursion that spawns processes until the machine is overwhelmed. `execute` now reads the embedded JSON and opens the target directly for both plain and executable dazzlelinks; the marker is matched as an exact line (the literal also appears in the script's own source). This path became easy to hit once executable generation was fixed (below), so the two ship together.
|
|
51
|
+
- Executable dazzlelink generation no longer crashes and now produces a runnable script (Refs #18). Four bugs, all present since the first release and masked by the first one:
|
|
52
|
+
- `serialize_link(make_executable=True)` raised `AttributeError` — `core.py` called `self._make_dazzlelink_executable`, which became the module function `links.make_dazzlelink_executable` during modularization; the call site now delegates correctly
|
|
53
|
+
- `links.py` and `batch.py` used `json` without importing it (latent `NameError`; batch's affected the `update-config` path)
|
|
54
|
+
- the generated script embedded a raw Windows path into a Python block, causing a `\U` `SyntaxError` — now embedded with forward slashes (ShellExecute-compatible; canonical backslash path preserved in the embedded JSON)
|
|
55
|
+
- the trailing JSON data block was executed as Python (`false`/`true`/`null` → `NameError`) — now guarded by `sys.exit(0)` after `main()`
|
|
56
|
+
- the same fixes are applied to the legacy monolith
|
|
57
|
+
- Execute mode precedence is now CLI > file-embedded > global > "info" (file-beats-global, matching the monolith): a file's embedded mode is no longer overridden by the global config default (Refs #19)
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
- `convert`/`mirror` now honor `--executable` and `--mode` (the CLI config is forwarded to the operation); `execute` now honors `--config-level` (the loaded config is passed through as the fallback)
|
|
61
|
+
|
|
62
|
+
### Notes
|
|
63
|
+
- Generated-script path representation uses forward slashes for now (tool-mode pragmatism); canonical runtime-read is tracked for the eventual library-mode transition (#23)
|
|
64
|
+
|
|
65
|
+
## [0.7.1] - 2026-06-11
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
- Relocate the git-repokit-common subtree to `scripts/repokit-common/` (disambiguating it from dazzlelink's own `scripts/` helpers) and update it to v0.2.7
|
|
69
|
+
|
|
70
|
+
## [0.7.0] - 2026-06-11
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
- Relative path support for portable dazzlelinks across synced machines (Refs #13)
|
|
74
|
+
- `target_representations.relative_path` computed during `create`
|
|
75
|
+
- `execute` fallback chain: absolute -> relative -> path_representations
|
|
76
|
+
- Enables dazzlelinks to work when library mount points differ between machines
|
|
77
|
+
- git-repokit-common subtree at `scripts/` for shared hooks and tools
|
|
78
|
+
- File association scripts for Windows `.dazzlelink` extension
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- **Layout**: package moved from `dazzlelink/` to `src/dazzlelink/` (PyPA src layout); editable installs must be re-run (`pip install -e .`)
|
|
82
|
+
- Monolith `dazzlelink.py` moved to `legacy/dazzlelink_monolith.py` and deprecated in favor of `python -m dazzlelink` (Refs #18)
|
|
83
|
+
- `pyproject.toml` is now the single source of packaging truth: `requires-python>=3.10`, pywin32 as a core dependency on Windows, license `GPL-3.0-or-later`, URLs point to the DazzleTools org (Refs #2)
|
|
84
|
+
- File association scripts prefer the pip-installed module, falling back to the legacy monolith
|
|
85
|
+
- CI matrix updated to Python 3.10/3.12/3.13
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
- `dazzlelink.operations` subpackage was missing from built wheels (`packages.find` with `where=["src"]`); installs from the previous packaging config would fail at import
|
|
89
|
+
- File association scripts' monolith fallback pointed at the removed root `dazzlelink.py`
|
|
90
|
+
- Renamed `pyproject-toml.py` to `pyproject.toml` for PyPI compatibility
|
|
91
|
+
|
|
92
|
+
### Removed
|
|
93
|
+
- `setup.py` (broken version read), `setup.cfg` (flake8 config migrated to pyproject), `requirements.txt` (deps live in pyproject)
|
|
94
|
+
|
|
95
|
+
## [0.6.0] - 2025-03-28
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- Complete modularization of codebase for better maintainability and extensibility
|
|
100
|
+
- New package structure with separate modules for core functionality
|
|
101
|
+
- Initial integration with UNC-lib for improved network path handling
|
|
102
|
+
- Clearer separation between platform-specific and cross-platform code
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- Refactored UNCAdapter to leverage specialized UNC-lib functionality
|
|
107
|
+
|
|
108
|
+
## [0.5.0] - 2025-03-28
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
- Initial public release candidate
|
|
112
|
+
- `import` command: recreates symlinks from `.dazzlelink` files with support for timestamp strategies
|
|
113
|
+
- `export` command: serializes existing symlinks into `.dazzlelink` format
|
|
114
|
+
- `create` command: allows creation of `.dazzlelink` files directly from source
|
|
115
|
+
- `convert` command: bulk conversion of symlinks into dazzlelinks
|
|
116
|
+
- `mirror` command: mirrors entire directory structures using symbolic links
|
|
117
|
+
- `scan` command: scans and reports existing symlinks in a directory
|
|
118
|
+
- `check` command: checks for broken links and optionally fixes them
|
|
119
|
+
- `config` command: manage global, directory, and inline configuration options
|
|
120
|
+
- `copy` command: copies symlinks to new destinations, preserving structure and optionally rebasing
|
|
121
|
+
- `rebase` command: transforms absolute to relative paths and vice versa, with powerful path-rewrite controls
|
|
122
|
+
- `execute` command: opens or executes symlink targets with optional modes
|
|
123
|
+
- Enhanced timestamp preservation for symlinks across platforms
|
|
124
|
+
- Improved batch operation performance for large directory processing
|
|
125
|
+
|
|
126
|
+
### Improved
|
|
127
|
+
- Basic test framework with `--keep-all` support
|
|
128
|
+
- Path resolution and UNC handling through experimental `unc_converter` integration
|
|
129
|
+
- Early work toward platform-agnostic symlink representation
|
|
130
|
+
- Drafted v2 JSON config structure
|
|
131
|
+
- Improved configuration management with clearer hierarchy (global, directory, file)
|
|
132
|
+
- Enhanced error handling and reporting throughout the codebase
|
|
133
|
+
- Optimized performance for batch operations by reducing verification overhead
|
|
134
|
+
- Better path handling for UNC paths and network shares
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
- Initial symlink resolution bugs during serialization
|
|
139
|
+
- Test directory cleanup issues
|
|
140
|
+
- Resolved directory path handling issues in `import` command
|
|
141
|
+
- Fixed timestamp preservation on Windows by using proper API flags
|
|
142
|
+
- Work on file attribute restoration for hidden, system, and read-only files
|
|
143
|
+
- Improved error detection and recovery during batch operations
|
|
144
|
+
- More work on path normalization issues for complex UNC paths
|
|
145
|
+
|
|
146
|
+
### Known Issues
|
|
147
|
+
- Broken link detection occasionally misses edge cases
|
|
148
|
+
- UNC-to-local path mapping still under refinement for complex networks
|
|
149
|
+
- Test harness and logging need stabilization
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## [0.1.0] - 2025-03-21
|
|
154
|
+
### Initial Development
|
|
155
|
+
- Created foundational `DazzleLink` class
|
|
156
|
+
- Designed `.dazzlelink` file format to support symlink serialization
|
|
157
|
+
- Drafted CLI structure using `argparse` with support for multiple subcommands
|
|
158
|
+
- Early experiments with Windows symlinks and path encoding
|
|
159
|
+
- Added UNC path normalization scaffolding
|
|
160
|
+
- Basic v1 JSON-based config loading introduced
|
|
161
|
+
- Placeholder support for future `find-best-images` integration
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
> For older historical context or dev discussions, see `/docs/roadmap.md`, [issues](https://github.com/djdarcy/dazzlelink/issues), and forums.
|
|
166
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Contributing to Dazzlelink
|
|
2
|
+
|
|
3
|
+
Thank you for considering contributing to **Dazzlelink**, the symbolic link preservation tool. This document outlines guidelines to help you contribute effectively and respectfully.
|
|
4
|
+
|
|
5
|
+
## Code of Conduct
|
|
6
|
+
|
|
7
|
+
By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md) to foster a respectful environment.
|
|
8
|
+
|
|
9
|
+
## How You Can Contribute
|
|
10
|
+
|
|
11
|
+
### 🔧 Reporting Bugs
|
|
12
|
+
|
|
13
|
+
1. Check the [Issues page](https://github.com/djdarcy/dazzlelink/issues) to see if your bug is already reported.
|
|
14
|
+
2. If not, open a new issue using the bug report template.
|
|
15
|
+
3. Include as much detail as possible:
|
|
16
|
+
- Steps to reproduce
|
|
17
|
+
- Expected vs. actual behavior
|
|
18
|
+
- Error messages or logs
|
|
19
|
+
- Environment (OS, Python version, etc.)
|
|
20
|
+
|
|
21
|
+
### ✨ Suggesting Features
|
|
22
|
+
|
|
23
|
+
1. Browse existing issues and pull requests to avoid duplication.
|
|
24
|
+
2. Create a new issue using the feature request template.
|
|
25
|
+
3. Clearly describe your feature and its use case.
|
|
26
|
+
|
|
27
|
+
### 🔀 Submitting Pull Requests
|
|
28
|
+
|
|
29
|
+
1. Fork the repository
|
|
30
|
+
2. Create a feature branch (`git checkout -b feature/your-feature`)
|
|
31
|
+
3. Make your changes and follow coding guidelines
|
|
32
|
+
4. Run and verify all tests
|
|
33
|
+
5. Commit with a clear message
|
|
34
|
+
6. Push your branch (`git push origin feature/your-feature`)
|
|
35
|
+
7. Open a pull request against the `main` branch
|
|
36
|
+
|
|
37
|
+
## Development Setup
|
|
38
|
+
|
|
39
|
+
### ⚙️ CLI Version
|
|
40
|
+
|
|
41
|
+
1. Clone the repository
|
|
42
|
+
2. Install in editable mode with dev dependencies:
|
|
43
|
+
```bash
|
|
44
|
+
pip install -e ".[dev]"
|
|
45
|
+
```
|
|
46
|
+
3. Make changes to the package under `src/dazzlelink/`
|
|
47
|
+
4. Run tests (`python -m pytest tests/`) or scripts as needed
|
|
48
|
+
5. Ensure code works on your target OS
|
|
49
|
+
|
|
50
|
+
## Coding Guidelines
|
|
51
|
+
|
|
52
|
+
- Follow Pythonic conventions (PEP8)
|
|
53
|
+
- Use `black`, `flake8`, or `pylint` for formatting/linting
|
|
54
|
+
- Comment non-obvious logic
|
|
55
|
+
- Include docstrings where appropriate
|
|
56
|
+
- Add/update tests when adding features or fixing bugs
|
|
57
|
+
- Keep commit messages clear and concise
|
|
58
|
+
|
|
59
|
+
## Versioning
|
|
60
|
+
|
|
61
|
+
We follow [Semantic Versioning](https://semver.org/):
|
|
62
|
+
- **MAJOR**: Incompatible API changes
|
|
63
|
+
- **MINOR**: Backward-compatible new features
|
|
64
|
+
- **PATCH**: Backward-compatible bug fixes
|
|
65
|
+
|
|
66
|
+
## Documentation
|
|
67
|
+
|
|
68
|
+
Please update the following when relevant:
|
|
69
|
+
- `README.md` for usage and setup
|
|
70
|
+
- `CHANGELOG.md` for user-facing changes
|
|
71
|
+
- Inline comments or docstrings for maintainability
|
|
72
|
+
|
|
73
|
+
## License Agreement
|
|
74
|
+
|
|
75
|
+
By submitting a contribution, you agree that your code will be licensed under the existing license of the project.
|
|
76
|
+
|
|
77
|
+
Thank you for helping improve Dazzlelink!
|