dazzle-linklib 0.1.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.
- dazzle_linklib-0.1.0/LICENSE +21 -0
- dazzle_linklib-0.1.0/PKG-INFO +106 -0
- dazzle_linklib-0.1.0/README.md +76 -0
- dazzle_linklib-0.1.0/dazzle_linklib/__init__.py +30 -0
- dazzle_linklib-0.1.0/dazzle_linklib/__main__.py +16 -0
- dazzle_linklib-0.1.0/dazzle_linklib/_version.py +92 -0
- dazzle_linklib-0.1.0/dazzle_linklib.egg-info/PKG-INFO +106 -0
- dazzle_linklib-0.1.0/dazzle_linklib.egg-info/SOURCES.txt +13 -0
- dazzle_linklib-0.1.0/dazzle_linklib.egg-info/dependency_links.txt +1 -0
- dazzle_linklib-0.1.0/dazzle_linklib.egg-info/requires.txt +4 -0
- dazzle_linklib-0.1.0/dazzle_linklib.egg-info/top_level.txt +1 -0
- dazzle_linklib-0.1.0/pyproject.toml +65 -0
- dazzle_linklib-0.1.0/setup.cfg +4 -0
- dazzle_linklib-0.1.0/tests/test_import_stability.py +41 -0
- dazzle_linklib-0.1.0/tests/test_version.py +50 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dustin Darcy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dazzle-linklib
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Content-addressable link-record library -- the DazzleLib stack's L2 serialization layer (typed locators, content_id, export/import/rebase/scan).
|
|
5
|
+
Author-email: djdarcy <djdarcy@users.noreply.github.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/DazzleLib/dazzle-linklib
|
|
8
|
+
Project-URL: Repository, https://github.com/DazzleLib/dazzle-linklib
|
|
9
|
+
Project-URL: Issues, https://github.com/DazzleLib/dazzle-linklib/issues
|
|
10
|
+
Keywords: dazzlelib,links,symlink,junction,serialization,content-addressable,anti-link-rot,relinker,stack
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: System :: Filesystems
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# dazzle-linklib
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/dazzle-linklib/)
|
|
34
|
+
[](https://github.com/DazzleLib/dazzle-linklib/releases)
|
|
35
|
+
[](https://www.python.org/downloads/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
[](docs/platform-support.md)
|
|
38
|
+
|
|
39
|
+
**Content-addressable link-record library** -- the **L2** serialization layer of
|
|
40
|
+
the [DazzleLib stack](https://github.com/DazzleLib/.github/blob/main/docs/STACK-MAP.md).
|
|
41
|
+
|
|
42
|
+
A link record maps an **identity** to a **typed list of locators** plus
|
|
43
|
+
metadata, and knows how to serialize, find, and resolve itself. One model
|
|
44
|
+
serves three consumers:
|
|
45
|
+
|
|
46
|
+
- the **dazzlelink** filesystem CLI (the `.dazzlelink` file format),
|
|
47
|
+
- **preserve**'s content-hash manifest (L3), and
|
|
48
|
+
- **Relinker** -- a hash-addressed, decentralized anti-link-rot resolver
|
|
49
|
+
(`rln.kr/{hash}` -> a multi-protocol location set).
|
|
50
|
+
|
|
51
|
+
## What this owns (and what it doesn't)
|
|
52
|
+
|
|
53
|
+
`dazzle-linklib` owns the link **record**: its schema, JSON I/O, the locator
|
|
54
|
+
list, `content_id`, relation edges, and the injectable target resolver. It
|
|
55
|
+
**delegates** the rest down the stack:
|
|
56
|
+
|
|
57
|
+
| Concern | Layer |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Link record, locators, `content_id`, relations, resolve | **dazzle-linklib (L2, this lib)** |
|
|
60
|
+
| File/link mechanics (create/detect/read, copy, hash, metadata) | `dazzle-filekit` (L1) |
|
|
61
|
+
| UNC <-> drive identity, path origin classification | `unctools` (L0) |
|
|
62
|
+
| Shared Protocols / TypedDicts / exception root | `dazzle-lib` (B) |
|
|
63
|
+
| Graph **traversal** (walking the records' relation edges) | `dazzletreelib` (perpendicular) |
|
|
64
|
+
|
|
65
|
+
"Records that point at each other" live here; "walking and interpreting those
|
|
66
|
+
pointers" do not. (See the L2 design rationale, decision D6.)
|
|
67
|
+
|
|
68
|
+
## Status
|
|
69
|
+
|
|
70
|
+
**0.1.0 is a name-reservation placeholder (pre-alpha).** It is published to
|
|
71
|
+
PyPI to claim the name, but exposes only its version -- there is no functional
|
|
72
|
+
content yet. The extraction of `DazzleLinkData` and the resolver from the
|
|
73
|
+
`dazzlelink` tool is stack phase **P2** and lands in a later release -- see the
|
|
74
|
+
[Roadmap](https://github.com/DazzleLib/dazzle-linklib/issues/2).
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install dazzle-linklib
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### From source
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
git clone https://github.com/DazzleLib/dazzle-linklib.git
|
|
86
|
+
cd dazzle-linklib
|
|
87
|
+
pip install -e ".[dev]"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
python -m venv .venv
|
|
94
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
95
|
+
pip install -e ".[dev]"
|
|
96
|
+
|
|
97
|
+
# Run tests
|
|
98
|
+
python -m pytest tests/ -v
|
|
99
|
+
|
|
100
|
+
# Install git hooks
|
|
101
|
+
bash scripts/install-hooks.sh
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# dazzle-linklib
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/dazzle-linklib/)
|
|
4
|
+
[](https://github.com/DazzleLib/dazzle-linklib/releases)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](docs/platform-support.md)
|
|
8
|
+
|
|
9
|
+
**Content-addressable link-record library** -- the **L2** serialization layer of
|
|
10
|
+
the [DazzleLib stack](https://github.com/DazzleLib/.github/blob/main/docs/STACK-MAP.md).
|
|
11
|
+
|
|
12
|
+
A link record maps an **identity** to a **typed list of locators** plus
|
|
13
|
+
metadata, and knows how to serialize, find, and resolve itself. One model
|
|
14
|
+
serves three consumers:
|
|
15
|
+
|
|
16
|
+
- the **dazzlelink** filesystem CLI (the `.dazzlelink` file format),
|
|
17
|
+
- **preserve**'s content-hash manifest (L3), and
|
|
18
|
+
- **Relinker** -- a hash-addressed, decentralized anti-link-rot resolver
|
|
19
|
+
(`rln.kr/{hash}` -> a multi-protocol location set).
|
|
20
|
+
|
|
21
|
+
## What this owns (and what it doesn't)
|
|
22
|
+
|
|
23
|
+
`dazzle-linklib` owns the link **record**: its schema, JSON I/O, the locator
|
|
24
|
+
list, `content_id`, relation edges, and the injectable target resolver. It
|
|
25
|
+
**delegates** the rest down the stack:
|
|
26
|
+
|
|
27
|
+
| Concern | Layer |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Link record, locators, `content_id`, relations, resolve | **dazzle-linklib (L2, this lib)** |
|
|
30
|
+
| File/link mechanics (create/detect/read, copy, hash, metadata) | `dazzle-filekit` (L1) |
|
|
31
|
+
| UNC <-> drive identity, path origin classification | `unctools` (L0) |
|
|
32
|
+
| Shared Protocols / TypedDicts / exception root | `dazzle-lib` (B) |
|
|
33
|
+
| Graph **traversal** (walking the records' relation edges) | `dazzletreelib` (perpendicular) |
|
|
34
|
+
|
|
35
|
+
"Records that point at each other" live here; "walking and interpreting those
|
|
36
|
+
pointers" do not. (See the L2 design rationale, decision D6.)
|
|
37
|
+
|
|
38
|
+
## Status
|
|
39
|
+
|
|
40
|
+
**0.1.0 is a name-reservation placeholder (pre-alpha).** It is published to
|
|
41
|
+
PyPI to claim the name, but exposes only its version -- there is no functional
|
|
42
|
+
content yet. The extraction of `DazzleLinkData` and the resolver from the
|
|
43
|
+
`dazzlelink` tool is stack phase **P2** and lands in a later release -- see the
|
|
44
|
+
[Roadmap](https://github.com/DazzleLib/dazzle-linklib/issues/2).
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install dazzle-linklib
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### From source
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/DazzleLib/dazzle-linklib.git
|
|
56
|
+
cd dazzle-linklib
|
|
57
|
+
pip install -e ".[dev]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Development
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python -m venv .venv
|
|
64
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
65
|
+
pip install -e ".[dev]"
|
|
66
|
+
|
|
67
|
+
# Run tests
|
|
68
|
+
python -m pytest tests/ -v
|
|
69
|
+
|
|
70
|
+
# Install git hooks
|
|
71
|
+
bash scripts/install-hooks.sh
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""dazzle-linklib -- the DazzleLib stack's L2 link-record library.
|
|
2
|
+
|
|
3
|
+
A **content-addressable link record**: one model that maps an identity to a
|
|
4
|
+
typed list of locators plus metadata, and knows how to serialize, find, and
|
|
5
|
+
resolve itself. It is the portable-DATA layer beneath three consumers:
|
|
6
|
+
|
|
7
|
+
* the **dazzlelink** filesystem CLI (the `.dazzlelink` file format),
|
|
8
|
+
* **preserve**'s content-hash manifest (L3), and
|
|
9
|
+
* **Relinker** -- a hash-addressed, decentralized anti-link-rot resolver
|
|
10
|
+
(``rln.kr/{hash}`` -> a multi-protocol location set).
|
|
11
|
+
|
|
12
|
+
The boundary (STACK-MAP, layers B/L0/L1/L2/L3): this library owns the link
|
|
13
|
+
RECORD -- its schema, JSON I/O, locator list, ``content_id``, and relation
|
|
14
|
+
edges -- and the injectable target resolver. It does NOT own filesystem
|
|
15
|
+
mechanics (those delegate down to ``dazzle-filekit`` L1), UNC/drive identity
|
|
16
|
+
(``unctools`` L0), or graph TRAVERSAL (``dazzletreelib`` is the perpendicular
|
|
17
|
+
traversal tier). "Records that point at each other" live here; "walking and
|
|
18
|
+
interpreting those pointers" do not (see the L2 design DWP, decision D6).
|
|
19
|
+
|
|
20
|
+
Status: **scaffold (0.1.0, pre-alpha).** The extraction of ``DazzleLinkData``
|
|
21
|
+
and the resolver from the dazzlelink tool is stack phase **P2** -- tracked on
|
|
22
|
+
the roadmap (issue #2). Until then this package exposes only its version.
|
|
23
|
+
|
|
24
|
+
License: MIT (whole stack; STACK-MAP D11). Architecture contract:
|
|
25
|
+
https://github.com/DazzleLib/.github/blob/main/docs/STACK-MAP.md
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from ._version import PIP_VERSION, __app_name__, __version__
|
|
29
|
+
|
|
30
|
+
__all__ = ["__version__", "__app_name__", "PIP_VERSION"]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Allow running as: python -m dazzle_linklib
|
|
2
|
+
|
|
3
|
+
dazzle-linklib is a LIBRARY, not a CLI -- the `dazzlelink` command lives in the
|
|
4
|
+
DazzleTools/dazzlelink tool (STACK-MAP D1). Running the module just reports the
|
|
5
|
+
installed version.
|
|
6
|
+
"""
|
|
7
|
+
from . import __app_name__, __version__
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main() -> None:
|
|
11
|
+
print(f"{__app_name__} {__version__}")
|
|
12
|
+
print("Library only -- the dazzlelink CLI lives in DazzleTools/dazzlelink.")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
main()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Version information for dazzle-linklib.
|
|
3
|
+
|
|
4
|
+
This file is the canonical source for version numbers.
|
|
5
|
+
The __version__ string is automatically updated by git hooks
|
|
6
|
+
with build metadata (branch, build number, date, commit hash).
|
|
7
|
+
|
|
8
|
+
Format: MAJOR.MINOR.PATCH[-PHASE]_BRANCH_BUILD-YYYYMMDD-COMMITHASH
|
|
9
|
+
Example: 0.1.0_main_1-20260101-a1b2c3d4
|
|
10
|
+
|
|
11
|
+
Version levels:
|
|
12
|
+
PROJECT_PHASE: Global project maturity (prealpha -> alpha -> beta -> stable).
|
|
13
|
+
Changes rarely, when the overall project hits a threshold.
|
|
14
|
+
PHASE: Per-MINOR feature set maturity (alpha -> beta -> "" for stable).
|
|
15
|
+
Drops when a MINOR's feature set is complete.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Version components - edit these for version bumps
|
|
19
|
+
MAJOR = 0
|
|
20
|
+
MINOR = 1
|
|
21
|
+
PATCH = 0
|
|
22
|
+
PHASE = "" # Per-MINOR feature set: "" (stable), "alpha", "beta", "rc1", etc.
|
|
23
|
+
|
|
24
|
+
# Project-level phase (independent of version phase)
|
|
25
|
+
PROJECT_PHASE = "" # "prealpha", "alpha", "beta", "stable", or ""
|
|
26
|
+
|
|
27
|
+
# Auto-updated by git hooks - do not edit manually
|
|
28
|
+
__version__ = "0.1.0_main_7-20260619-08de0656"
|
|
29
|
+
__app_name__ = "dazzle-linklib"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_version():
|
|
33
|
+
"""Return the full version string including branch and build info."""
|
|
34
|
+
return __version__
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_base_version():
|
|
38
|
+
"""Return the semantic version string (MAJOR.MINOR.PATCH[-PHASE])."""
|
|
39
|
+
if "_" in __version__:
|
|
40
|
+
return __version__.split("_")[0]
|
|
41
|
+
base = f"{MAJOR}.{MINOR}.{PATCH}"
|
|
42
|
+
if PHASE:
|
|
43
|
+
base = f"{base}-{PHASE}"
|
|
44
|
+
return base
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_display_version():
|
|
48
|
+
"""Return a human-friendly version string with project phase.
|
|
49
|
+
|
|
50
|
+
Example: 'PREALPHA 0.1.0-alpha' or 'BETA 0.5.1' or '1.0.0'
|
|
51
|
+
"""
|
|
52
|
+
base = get_base_version()
|
|
53
|
+
if PROJECT_PHASE and PROJECT_PHASE != "stable":
|
|
54
|
+
return f"{PROJECT_PHASE.upper()} {base}"
|
|
55
|
+
return base
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_pip_version():
|
|
59
|
+
"""
|
|
60
|
+
Return PEP 440 compliant version for pip/setuptools.
|
|
61
|
+
|
|
62
|
+
Converts our version format to PEP 440:
|
|
63
|
+
- Main branch: 0.1.0_main_3-20260404-hash -> 0.1.0
|
|
64
|
+
- Dev branch: 0.1.0_dev_3-20260404-hash -> 0.1.0.dev3
|
|
65
|
+
- Alpha: 0.1.0-alpha_main_3 -> 0.1.0a0
|
|
66
|
+
"""
|
|
67
|
+
base = f"{MAJOR}.{MINOR}.{PATCH}"
|
|
68
|
+
|
|
69
|
+
# Map phase to PEP 440 pre-release segment
|
|
70
|
+
phase_map = {"alpha": "a0", "beta": "b0"}
|
|
71
|
+
if PHASE:
|
|
72
|
+
base += phase_map.get(PHASE, PHASE)
|
|
73
|
+
|
|
74
|
+
if "_" not in __version__:
|
|
75
|
+
return base
|
|
76
|
+
|
|
77
|
+
parts = __version__.split("_")
|
|
78
|
+
branch = parts[1] if len(parts) > 1 else "unknown"
|
|
79
|
+
|
|
80
|
+
if branch == "main":
|
|
81
|
+
return base
|
|
82
|
+
else:
|
|
83
|
+
build_info = "_".join(parts[2:]) if len(parts) > 2 else ""
|
|
84
|
+
build_num = build_info.split("-")[0] if "-" in build_info else "0"
|
|
85
|
+
return f"{base}.dev{build_num}"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# For convenience in imports
|
|
89
|
+
VERSION = get_version()
|
|
90
|
+
BASE_VERSION = get_base_version()
|
|
91
|
+
PIP_VERSION = get_pip_version()
|
|
92
|
+
DISPLAY_VERSION = get_display_version()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dazzle-linklib
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Content-addressable link-record library -- the DazzleLib stack's L2 serialization layer (typed locators, content_id, export/import/rebase/scan).
|
|
5
|
+
Author-email: djdarcy <djdarcy@users.noreply.github.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/DazzleLib/dazzle-linklib
|
|
8
|
+
Project-URL: Repository, https://github.com/DazzleLib/dazzle-linklib
|
|
9
|
+
Project-URL: Issues, https://github.com/DazzleLib/dazzle-linklib/issues
|
|
10
|
+
Keywords: dazzlelib,links,symlink,junction,serialization,content-addressable,anti-link-rot,relinker,stack
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: System :: Filesystems
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# dazzle-linklib
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/dazzle-linklib/)
|
|
34
|
+
[](https://github.com/DazzleLib/dazzle-linklib/releases)
|
|
35
|
+
[](https://www.python.org/downloads/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
[](docs/platform-support.md)
|
|
38
|
+
|
|
39
|
+
**Content-addressable link-record library** -- the **L2** serialization layer of
|
|
40
|
+
the [DazzleLib stack](https://github.com/DazzleLib/.github/blob/main/docs/STACK-MAP.md).
|
|
41
|
+
|
|
42
|
+
A link record maps an **identity** to a **typed list of locators** plus
|
|
43
|
+
metadata, and knows how to serialize, find, and resolve itself. One model
|
|
44
|
+
serves three consumers:
|
|
45
|
+
|
|
46
|
+
- the **dazzlelink** filesystem CLI (the `.dazzlelink` file format),
|
|
47
|
+
- **preserve**'s content-hash manifest (L3), and
|
|
48
|
+
- **Relinker** -- a hash-addressed, decentralized anti-link-rot resolver
|
|
49
|
+
(`rln.kr/{hash}` -> a multi-protocol location set).
|
|
50
|
+
|
|
51
|
+
## What this owns (and what it doesn't)
|
|
52
|
+
|
|
53
|
+
`dazzle-linklib` owns the link **record**: its schema, JSON I/O, the locator
|
|
54
|
+
list, `content_id`, relation edges, and the injectable target resolver. It
|
|
55
|
+
**delegates** the rest down the stack:
|
|
56
|
+
|
|
57
|
+
| Concern | Layer |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Link record, locators, `content_id`, relations, resolve | **dazzle-linklib (L2, this lib)** |
|
|
60
|
+
| File/link mechanics (create/detect/read, copy, hash, metadata) | `dazzle-filekit` (L1) |
|
|
61
|
+
| UNC <-> drive identity, path origin classification | `unctools` (L0) |
|
|
62
|
+
| Shared Protocols / TypedDicts / exception root | `dazzle-lib` (B) |
|
|
63
|
+
| Graph **traversal** (walking the records' relation edges) | `dazzletreelib` (perpendicular) |
|
|
64
|
+
|
|
65
|
+
"Records that point at each other" live here; "walking and interpreting those
|
|
66
|
+
pointers" do not. (See the L2 design rationale, decision D6.)
|
|
67
|
+
|
|
68
|
+
## Status
|
|
69
|
+
|
|
70
|
+
**0.1.0 is a name-reservation placeholder (pre-alpha).** It is published to
|
|
71
|
+
PyPI to claim the name, but exposes only its version -- there is no functional
|
|
72
|
+
content yet. The extraction of `DazzleLinkData` and the resolver from the
|
|
73
|
+
`dazzlelink` tool is stack phase **P2** and lands in a later release -- see the
|
|
74
|
+
[Roadmap](https://github.com/DazzleLib/dazzle-linklib/issues/2).
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install dazzle-linklib
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### From source
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
git clone https://github.com/DazzleLib/dazzle-linklib.git
|
|
86
|
+
cd dazzle-linklib
|
|
87
|
+
pip install -e ".[dev]"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
python -m venv .venv
|
|
94
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
95
|
+
pip install -e ".[dev]"
|
|
96
|
+
|
|
97
|
+
# Run tests
|
|
98
|
+
python -m pytest tests/ -v
|
|
99
|
+
|
|
100
|
+
# Install git hooks
|
|
101
|
+
bash scripts/install-hooks.sh
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
dazzle_linklib/__init__.py
|
|
5
|
+
dazzle_linklib/__main__.py
|
|
6
|
+
dazzle_linklib/_version.py
|
|
7
|
+
dazzle_linklib.egg-info/PKG-INFO
|
|
8
|
+
dazzle_linklib.egg-info/SOURCES.txt
|
|
9
|
+
dazzle_linklib.egg-info/dependency_links.txt
|
|
10
|
+
dazzle_linklib.egg-info/requires.txt
|
|
11
|
+
dazzle_linklib.egg-info/top_level.txt
|
|
12
|
+
tests/test_import_stability.py
|
|
13
|
+
tests/test_version.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dazzle_linklib
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dazzle-linklib"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Content-addressable link-record library -- the DazzleLib stack's L2 serialization layer (typed locators, content_id, export/import/rebase/scan)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "djdarcy", email = "djdarcy@users.noreply.github.com"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["dazzlelib", "links", "symlink", "junction", "serialization", "content-addressable", "anti-link-rot", "relinker", "stack"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: Software Development :: Libraries",
|
|
28
|
+
"Topic :: System :: Filesystems",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
dependencies = []
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=7.0.0",
|
|
36
|
+
"pytest-cov>=4.0.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/DazzleLib/dazzle-linklib"
|
|
41
|
+
Repository = "https://github.com/DazzleLib/dazzle-linklib"
|
|
42
|
+
Issues = "https://github.com/DazzleLib/dazzle-linklib/issues"
|
|
43
|
+
|
|
44
|
+
# Library-only: no console_scripts. The `dazzlelink` CLI lives in the
|
|
45
|
+
# DazzleTools/dazzlelink tool, which consumes this library (STACK-MAP D1).
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.dynamic]
|
|
48
|
+
version = {attr = "dazzle_linklib._version.PIP_VERSION"}
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.packages.find]
|
|
51
|
+
where = ["."]
|
|
52
|
+
include = ["dazzle_linklib", "dazzle_linklib.*"]
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
python_files = "test_*.py"
|
|
57
|
+
python_functions = "test_*"
|
|
58
|
+
python_classes = "Test*"
|
|
59
|
+
|
|
60
|
+
[tool.repokit-common]
|
|
61
|
+
version-source = "dazzle_linklib/_version.py"
|
|
62
|
+
changelog = "CHANGELOG.md"
|
|
63
|
+
repo-url = "https://github.com/DazzleLib/dazzle-linklib"
|
|
64
|
+
tag-prefix = "v"
|
|
65
|
+
private-patterns = ["private/", "local/", ".env"]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Import-stability canary (see docs/api-stability.md).
|
|
2
|
+
|
|
3
|
+
Every symbol listed here is part of the locked public API. If this test
|
|
4
|
+
fails, a consumer somewhere breaks: do NOT silently fix the test -- follow
|
|
5
|
+
the api-stability.md process (deprecate with a noisy shim, register it,
|
|
6
|
+
slate removal).
|
|
7
|
+
|
|
8
|
+
The locked surface is intentionally tiny at the 0.1.0 scaffold stage (version
|
|
9
|
+
exports only). The record model (DazzleLinkData, export/import/scan/rebase,
|
|
10
|
+
resolve_target) joins this canary at its P2 release.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import importlib
|
|
14
|
+
|
|
15
|
+
LOCKED_SURFACE = {
|
|
16
|
+
"dazzle_linklib": [
|
|
17
|
+
"__version__",
|
|
18
|
+
"__app_name__",
|
|
19
|
+
"PIP_VERSION",
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_locked_surface_importable():
|
|
25
|
+
missing = []
|
|
26
|
+
for module_name, symbols in LOCKED_SURFACE.items():
|
|
27
|
+
module = importlib.import_module(module_name)
|
|
28
|
+
for symbol in symbols:
|
|
29
|
+
if not hasattr(module, symbol):
|
|
30
|
+
missing.append(f"{module_name}.{symbol}")
|
|
31
|
+
assert not missing, (
|
|
32
|
+
f"Locked API symbols missing: {missing} -- see docs/api-stability.md "
|
|
33
|
+
f"before changing the public surface."
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_package_is_importable():
|
|
38
|
+
"""The package imports cleanly with no side effects at import time."""
|
|
39
|
+
mod = importlib.import_module("dazzle_linklib")
|
|
40
|
+
assert isinstance(mod.__version__, str)
|
|
41
|
+
assert mod.__app_name__ == "dazzle-linklib"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Tests for version module."""
|
|
2
|
+
|
|
3
|
+
from dazzle_linklib._version import (
|
|
4
|
+
MAJOR, MINOR, PATCH, PHASE, PROJECT_PHASE,
|
|
5
|
+
get_version, get_base_version, get_display_version, get_pip_version,
|
|
6
|
+
__app_name__,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_app_name():
|
|
11
|
+
assert __app_name__ == "dazzle-linklib"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_version_components():
|
|
15
|
+
assert isinstance(MAJOR, int)
|
|
16
|
+
assert isinstance(MINOR, int)
|
|
17
|
+
assert isinstance(PATCH, int)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_phase_valid():
|
|
21
|
+
"""PHASE is empty string (stable release) or a string like 'alpha', 'beta', 'rc1'."""
|
|
22
|
+
assert isinstance(PHASE, str)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_get_version_returns_string():
|
|
26
|
+
v = get_version()
|
|
27
|
+
assert isinstance(v, str)
|
|
28
|
+
assert len(v) > 0
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_base_version_format():
|
|
32
|
+
base = get_base_version()
|
|
33
|
+
assert base.startswith(f"{MAJOR}.{MINOR}.{PATCH}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_display_version_includes_project_phase():
|
|
37
|
+
display = get_display_version()
|
|
38
|
+
if PROJECT_PHASE and PROJECT_PHASE != "stable":
|
|
39
|
+
assert PROJECT_PHASE.upper() in display
|
|
40
|
+
else:
|
|
41
|
+
assert display == get_base_version()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_pip_version_pep440():
|
|
45
|
+
pip_v = get_pip_version()
|
|
46
|
+
assert "-" not in pip_v
|
|
47
|
+
if PHASE:
|
|
48
|
+
assert any(c.isalpha() for c in pip_v.split(".")[-1])
|
|
49
|
+
else:
|
|
50
|
+
assert all(c.isdigit() or c == "." for c in pip_v)
|