path-link 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

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.
@@ -0,0 +1,128 @@
1
+ """Static URL model generator with deterministic ordering and atomic writes.
2
+
3
+ This module generates a static dataclass for project URLs that provides
4
+ IDE autocomplete without requiring runtime configuration loading.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ from pathlib import Path
11
+ from typing import Optional, Union
12
+
13
+ from path_link.url_factory import ProjectUrls
14
+ from path_link.url_model import ValidationMode
15
+
16
+
17
+ def generate_static_url_model_text(mode: ValidationMode = ValidationMode.LENIENT) -> str:
18
+ """
19
+ Generates the Python code for the static URL dataclass model.
20
+
21
+ Args:
22
+ mode: Validation mode to use when loading URLs (default: lenient)
23
+
24
+ Returns:
25
+ Python source code as a string
26
+ """
27
+ lines = [
28
+ "from dataclasses import dataclass, field",
29
+ "",
30
+ "# This file is auto-generated by path-link. Do not edit manually.",
31
+ "# Run `pathlink gen-static-urls` to regenerate.",
32
+ "",
33
+ "@dataclass(frozen=True)",
34
+ "class ProjectUrlsStatic:",
35
+ ' """A static, auto-generated dataclass for project URLs."""',
36
+ "",
37
+ ]
38
+
39
+ # Instantiate from merged sources to get all URL fields
40
+ try:
41
+ model = ProjectUrls.from_merged(mode=mode)
42
+ except Exception:
43
+ # If merged loading fails, try just pyproject
44
+ try:
45
+ model = ProjectUrls.from_pyproject(mode=mode)
46
+ except Exception:
47
+ # If that fails too, return empty model with comment
48
+ lines.append(" # No URLs configured")
49
+ lines.append(" pass")
50
+ return "\n".join(lines)
51
+
52
+ # Get all fields and sort them for deterministic output (stable diffs)
53
+ field_names = sorted(model.__class__.model_fields.keys())
54
+
55
+ if not field_names:
56
+ # No fields, generate empty model
57
+ lines.append(" # No URLs configured")
58
+ lines.append(" pass")
59
+ else:
60
+ for field_name in field_names:
61
+ # Get the actual URL value from the model instance
62
+ url_value = getattr(model, field_name)
63
+
64
+ # Create field with simple string default (no factories for URLs)
65
+ line = f' {field_name}: str = "{url_value}"'
66
+ lines.append(line)
67
+
68
+ # Add empty line at end for clean formatting
69
+ lines.append("")
70
+
71
+ return "\n".join(lines)
72
+
73
+
74
+ def write_url_dataclass_file(
75
+ output_path: Optional[Union[str, Path]] = None,
76
+ mode: Union[ValidationMode, str, None] = None,
77
+ ) -> None:
78
+ """
79
+ Generates and writes the static URL dataclass file with atomic write.
80
+
81
+ Uses atomic file operations to prevent TOCTOU vulnerabilities:
82
+ 1. Write to temporary file
83
+ 2. Flush and sync to disk
84
+ 3. Atomically replace target file
85
+
86
+ Args:
87
+ output_path: Optional output path (default: src/project_paths/project_urls_static.py)
88
+ mode: Validation mode (lenient or strict). If None, defaults to lenient.
89
+
90
+ Raises:
91
+ FileNotFoundError: If file write verification fails
92
+ """
93
+ # Determine validation mode
94
+ if mode is None:
95
+ validation_mode = ValidationMode.LENIENT
96
+ elif isinstance(mode, str):
97
+ validation_mode = ValidationMode(mode.lower())
98
+ else:
99
+ validation_mode = mode
100
+
101
+ # Determine output path
102
+ if output_path is None:
103
+ # Default path within the src directory
104
+ output_path = Path(__file__).parent / "project_urls_static.py"
105
+
106
+ resolved_path = Path(output_path).resolve()
107
+ resolved_path.parent.mkdir(parents=True, exist_ok=True)
108
+
109
+ # Generate the code
110
+ generated_code = generate_static_url_model_text(validation_mode)
111
+
112
+ # Write to a temporary file first to avoid race conditions (TOCTOU)
113
+ temp_path = resolved_path.with_suffix(".tmp")
114
+
115
+ # Write and sync to disk before replace (prevents TOCTOU vulnerability)
116
+ with temp_path.open("w", encoding="utf-8") as f:
117
+ f.write(generated_code)
118
+ f.flush()
119
+ os.fsync(f.fileno()) # Ensure data is written to disk
120
+
121
+ # Atomically replace the old file with the new one (atomic on POSIX)
122
+ temp_path.replace(resolved_path)
123
+
124
+ # Verify the file exists (after atomic replace, no TOCTOU risk)
125
+ if resolved_path.exists():
126
+ print(f"✅ Static URL model written to {resolved_path}")
127
+ else:
128
+ raise FileNotFoundError(f"❌ Failed to write static URL model to {resolved_path}")
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: path-link
3
- Version: 0.2.0
4
- Summary: Type-safe path and URL configuration for Python projects with validation, static models, and IDE autocompletion. Currently supports local paths, URL support coming in v0.3.0.
3
+ Version: 0.3.0
4
+ Summary: Type-safe path and URL configuration for Python projects with validation, static models, and IDE autocompletion. Features path management and URL validation with lenient/strict modes.
5
5
  Author-email: Lasse Tammilehto <lasse@jaahdytyspalvelu.fi>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, http://jaahdytyspalvelu.fi
8
8
  Project-URL: Documentation, https://github.com/jaahdytyspalvelu/path-link#readme
9
9
  Project-URL: Issue Tracker, https://github.com/jaahdytyspalvelu/path-link/issues
@@ -11,7 +11,6 @@ Project-URL: AI Guidelines, https://github.com/jaahdytyspalvelu/path-link/blob/m
11
11
  Project-URL: Developer Guide, https://github.com/jaahdytyspalvelu/path-link/blob/main/CLAUDE.md
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: MIT License
15
14
  Classifier: Programming Language :: Python :: 3
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
@@ -23,6 +22,7 @@ Description-Content-Type: text/markdown
23
22
  License-File: LICENSE
24
23
  Requires-Dist: pydantic>=2.11.0
25
24
  Requires-Dist: python-dotenv>=1.0.1
25
+ Requires-Dist: twine>=6.2.0
26
26
  Provides-Extra: test
27
27
  Requires-Dist: pytest>=8.4.2; extra == "test"
28
28
  Requires-Dist: pytest-cov>=7.0.0; extra == "test"
@@ -35,17 +35,31 @@ Dynamic: license-file
35
35
 
36
36
  Type-safe path and URL configuration for Python projects with validation, static models, and IDE autocompletion.
37
37
 
38
- **Current:** Local path management ✅
39
- **Coming in v0.3.0:** URL support (API endpoints, external resources)
38
+ **Features:**
39
+ - Local path management
40
+ - ✅ URL configuration with lenient/strict validation
41
+ - ✅ Static model generation for both paths and URLs
42
+ - ✅ CLI tools for validation and inspection
40
43
 
41
44
  ## 🚀 Features
42
45
 
46
+ ### Path Management
43
47
  - **Dynamic Path Management**: Load paths from `pyproject.toml` or custom `.paths` files
44
48
  - **Type-Safe Static Models**: Generate static dataclasses for IDE autocomplete and type checking
45
- - **Extensible Validation**: Protocol-based validator system with built-in and custom validators
49
+ - **Environment Variable Expansion**: Support for `$VAR`, `${VAR}`, and `~` expansion
46
50
  - **Cross-Platform**: Works on Linux, Windows, and macOS
47
- - **Zero Runtime Dependencies**: Only requires `pydantic` and `python-dotenv`
48
- - **Developer Friendly**: Full type hints, comprehensive testing, and clear error messages
51
+
52
+ ### URL Management
53
+ - **Dual Validation Modes**: Lenient (dev/localhost) and strict (production) URL validation
54
+ - **Multiple Sources**: Load from `pyproject.toml`, `.urls` files, or merge both
55
+ - **Static URL Models**: Generate dataclasses for type-safe URL access
56
+ - **CLI Tools**: Validate, print, and generate static models from command line
57
+
58
+ ### General
59
+ - **Extensible Validation**: Protocol-based validator system with built-in and custom validators
60
+ - **Security Features**: Path traversal protection, sandbox validation
61
+ - **Minimal Dependencies**: Only requires `pydantic` and `python-dotenv`
62
+ - **Developer Friendly**: Full type hints, comprehensive testing (212 tests), and clear error messages
49
63
 
50
64
  ## 📦 Installation
51
65
 
@@ -71,7 +85,7 @@ uv sync
71
85
  ### Basic Usage
72
86
 
73
87
  ```python
74
- from project_paths import ProjectPaths
88
+ from path_link import ProjectPaths
75
89
 
76
90
  # Load paths from pyproject.toml
77
91
  paths = ProjectPaths.from_pyproject()
@@ -91,14 +105,14 @@ all_paths = paths.to_dict()
91
105
  ### Configuration in pyproject.toml
92
106
 
93
107
  ```toml
94
- [tool.project_paths.paths]
108
+ [tool.path_link.paths]
95
109
  config = "config"
96
110
  icons = "icons"
97
111
  data = "data"
98
112
  cache = ".cache"
99
113
  logs = "logs"
100
114
 
101
- [tool.project_paths.files]
115
+ [tool.path_link.files]
102
116
  settings = "config/settings.json"
103
117
  database = "data/app.db"
104
118
  ```
@@ -151,43 +165,202 @@ config_dir = ~/.config/myapp
151
165
 
152
166
  **Example `pyproject.toml`:**
153
167
  ```toml
154
- [tool.project_paths.paths]
168
+ [tool.path_link.paths]
155
169
  data_dir = "${DATA_ROOT}/files"
156
170
  config_dir = "~/.config/myapp"
157
171
  ```
158
172
 
173
+ ## 🌐 URL Management
174
+
175
+ path-link includes powerful URL configuration management with validation modes for different environments.
176
+
177
+ ### Basic URL Usage
178
+
179
+ ```python
180
+ from path_link import ProjectUrls, ValidationMode
181
+
182
+ # Load URLs from pyproject.toml (lenient mode by default)
183
+ urls = ProjectUrls.from_pyproject()
184
+
185
+ # Access URLs
186
+ print(urls.api_base) # API base URL
187
+ print(urls.webhook_url) # Webhook endpoint
188
+
189
+ # Dictionary-style access
190
+ api_url = urls["api_base"]
191
+
192
+ # Get all URLs as dictionary
193
+ all_urls = urls.to_dict()
194
+ ```
195
+
196
+ ### URL Configuration
197
+
198
+ **In `pyproject.toml`:**
199
+ ```toml
200
+ [tool.path_link.urls]
201
+ api_base = "https://api.example.com"
202
+ webhook_url = "https://example.com/webhooks/callback"
203
+ docs_url = "https://docs.example.com"
204
+
205
+ # Development URLs (use lenient mode)
206
+ dev_api = "http://localhost:8000"
207
+ dev_db = "http://127.0.0.1:5432"
208
+ ```
209
+
210
+ **In `.urls` file (dotenv format):**
211
+ ```bash
212
+ # Production URLs
213
+ api_base=https://api.example.com
214
+ webhook_url=https://example.com/webhooks/callback
215
+
216
+ # Development URLs
217
+ dev_api=http://localhost:8000
218
+ dev_db=http://127.0.0.1:5432
219
+ ```
220
+
221
+ ### Validation Modes
222
+
223
+ **Lenient Mode (Development):**
224
+ - Accepts `localhost` and `127.0.0.1`
225
+ - Allows private IP addresses (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
226
+ - Permits custom ports
227
+ - Suitable for development and testing
228
+
229
+ **Strict Mode (Production):**
230
+ - Only accepts public HTTP(S) URLs
231
+ - Rejects localhost and private IPs
232
+ - RFC-compliant validation
233
+ - Suitable for production deployments
234
+
235
+ ```python
236
+ from path_link import ProjectUrls, ValidationMode
237
+
238
+ # Lenient mode (default) - allows localhost
239
+ dev_urls = ProjectUrls.from_pyproject(mode=ValidationMode.LENIENT)
240
+ # ✅ http://localhost:8000 is valid
241
+
242
+ # Strict mode - only public URLs
243
+ prod_urls = ProjectUrls.from_pyproject(mode=ValidationMode.STRICT)
244
+ # ❌ http://localhost:8000 raises ValidationError
245
+ # ✅ https://api.example.com is valid
246
+ ```
247
+
248
+ ### Loading from Multiple Sources
249
+
250
+ ```python
251
+ # Load from .urls file only
252
+ urls = ProjectUrls.from_config(".urls")
253
+
254
+ # Merge pyproject.toml and .urls (pyproject takes precedence)
255
+ urls = ProjectUrls.from_merged()
256
+
257
+ # Merge with custom .urls file
258
+ urls = ProjectUrls.from_merged(dotenv_path="config/.urls.prod")
259
+ ```
260
+
261
+ ### Environment-Based Mode Selection
262
+
263
+ Set the validation mode via environment variable:
264
+
265
+ ```bash
266
+ # Development
267
+ export PTOOL_URL_MODE=lenient
268
+ python your_app.py
269
+
270
+ # Production
271
+ export PTOOL_URL_MODE=strict
272
+ python your_app.py
273
+ ```
274
+
275
+ ```python
276
+ # Automatically uses environment variable
277
+ urls = ProjectUrls.from_pyproject() # Respects PTOOL_URL_MODE
278
+ ```
279
+
280
+ ### Static URL Model Generation
281
+
282
+ Generate a static dataclass for IDE autocomplete:
283
+
284
+ ```python
285
+ from path_link import write_url_dataclass_file, ValidationMode
286
+
287
+ # Generate with lenient validation (default)
288
+ write_url_dataclass_file()
289
+
290
+ # Generate with strict validation for production
291
+ write_url_dataclass_file(mode=ValidationMode.STRICT)
292
+
293
+ # Custom output location
294
+ write_url_dataclass_file(
295
+ output_path="config/urls_static.py",
296
+ mode=ValidationMode.LENIENT
297
+ )
298
+ ```
299
+
300
+ Then import and use:
301
+
302
+ ```python
303
+ from path_link.project_urls_static import ProjectUrlsStatic
304
+
305
+ urls = ProjectUrlsStatic()
306
+ # Full IDE autocomplete for all configured URLs!
307
+ print(urls.api_base)
308
+ ```
309
+
310
+ ### URL CLI Commands
311
+
312
+ ```bash
313
+ # Print all URLs as JSON
314
+ pathlink print-urls
315
+
316
+ # Print in table format
317
+ pathlink print-urls --format table
318
+
319
+ # Validate URLs (lenient mode)
320
+ pathlink validate-urls
321
+
322
+ # Validate with strict mode
323
+ pathlink validate-urls --mode strict
324
+
325
+ # Generate static URL model
326
+ pathlink gen-static-urls
327
+
328
+ # Generate with strict mode
329
+ pathlink gen-static-urls --mode strict
330
+ ```
331
+
159
332
  ## 🖥️ Command Line Interface
160
333
 
161
- ptool-serena includes a `ptool` CLI for quick operations without writing Python code.
334
+ path-link includes a `pathlink` CLI for quick operations without writing Python code.
162
335
 
163
336
  ### Available Commands
164
337
 
165
338
  ```bash
166
339
  # Print all configured paths as JSON
167
- ptool print
340
+ pathlink print
168
341
 
169
342
  # Validate project structure
170
- ptool validate
343
+ pathlink validate
171
344
 
172
345
  # Generate static dataclass model
173
- ptool gen-static
346
+ pathlink gen-static
174
347
 
175
348
  # Show help
176
- ptool --help
349
+ pathlink --help
177
350
  ```
178
351
 
179
352
  ### Command Reference
180
353
 
181
- #### `ptool print` - Display Paths
354
+ #### `pathlink print` - Display Paths
182
355
 
183
356
  Prints all configured paths as formatted JSON.
184
357
 
185
358
  ```bash
186
359
  # Print from pyproject.toml (default)
187
- ptool print
360
+ pathlink print
188
361
 
189
362
  # Print from custom .paths file
190
- ptool print --source config --config my.paths
363
+ pathlink print --source config --config my.paths
191
364
 
192
365
  # Output example:
193
366
  # {
@@ -202,22 +375,22 @@ ptool print --source config --config my.paths
202
375
  - `--source {pyproject,config}` - Configuration source (default: pyproject)
203
376
  - `--config PATH` - Path to .paths file (default: .paths)
204
377
 
205
- #### `ptool validate` - Validate Paths
378
+ #### `pathlink validate` - Validate Paths
206
379
 
207
380
  Validates that your project structure matches the configuration.
208
381
 
209
382
  ```bash
210
383
  # Basic validation (check paths can be loaded)
211
- ptool validate
384
+ pathlink validate
212
385
 
213
386
  # Strict validation (check paths exist, no symlinks)
214
- ptool validate --strict
387
+ pathlink validate --strict
215
388
 
216
389
  # Raise exception on validation failure
217
- ptool validate --strict --raise
390
+ pathlink validate --strict --raise
218
391
 
219
392
  # Validate from custom config
220
- ptool validate --source config --config production.paths
393
+ pathlink validate --source config --config production.paths
221
394
  ```
222
395
 
223
396
  **Options:**
@@ -230,57 +403,57 @@ ptool validate --source config --config production.paths
230
403
  - `0` - Validation passed
231
404
  - `1` - Validation failed or error occurred
232
405
 
233
- #### `ptool gen-static` - Generate Static Model
406
+ #### `pathlink gen-static` - Generate Static Model
234
407
 
235
408
  Generates a static dataclass for IDE autocomplete and type checking.
236
409
 
237
410
  ```bash
238
- # Generate at default location (src/project_paths/project_paths_static.py)
239
- ptool gen-static
411
+ # Generate at default location (src/path_link/project_paths_static.py)
412
+ pathlink gen-static
240
413
 
241
414
  # Generate at custom location
242
- ptool gen-static --out custom/path/static_paths.py
415
+ pathlink gen-static --out custom/path/static_paths.py
243
416
  ```
244
417
 
245
418
  **Options:**
246
419
  - `--out PATH` - Output path for static model
247
420
 
248
- **When to use:** After modifying `[tool.project_paths]` in `pyproject.toml` to keep static model in sync.
421
+ **When to use:** After modifying `[tool.path_link]` in `pyproject.toml` to keep static model in sync.
249
422
 
250
423
  ### CLI Usage Examples
251
424
 
252
425
  **Quick project validation:**
253
426
  ```bash
254
427
  cd your-project/
255
- ptool validate --strict
428
+ pathlink validate --strict
256
429
  # ✅ All paths valid (strict mode)
257
430
  ```
258
431
 
259
432
  **View all configured paths:**
260
433
  ```bash
261
- ptool print
434
+ pathlink print
262
435
  # Outputs JSON with all resolved paths
263
436
  ```
264
437
 
265
438
  **Generate static model for IDE support:**
266
439
  ```bash
267
- ptool gen-static
440
+ pathlink gen-static
268
441
  # ✅ Static model generated successfully
269
442
  ```
270
443
 
271
444
  **CI/CD integration:**
272
445
  ```bash
273
446
  # In your CI script
274
- ptool validate --strict --raise || exit 1
447
+ pathlink validate --strict --raise || exit 1
275
448
  ```
276
449
 
277
450
  **Multiple environments:**
278
451
  ```bash
279
452
  # Development
280
- ptool validate --source config --config .paths.dev
453
+ pathlink validate --source config --config .paths.dev
281
454
 
282
455
  # Production
283
- ptool validate --source config --config .paths.prod
456
+ pathlink validate --source config --config .paths.prod
284
457
  ```
285
458
 
286
459
  ### With Validation
@@ -288,8 +461,8 @@ ptool validate --source config --config .paths.prod
288
461
  You can validate your project's structure by using one of the built-in validators.
289
462
 
290
463
  ```python
291
- from project_paths import ProjectPaths, validate_or_raise, PathValidationError
292
- from project_paths.builtin_validators import StrictPathValidator
464
+ from path_link import ProjectPaths, validate_or_raise, PathValidationError
465
+ from path_link.builtin_validators import StrictPathValidator
293
466
 
294
467
  # 1. Load your paths
295
468
  paths = ProjectPaths.from_pyproject()
@@ -321,8 +494,8 @@ if not result.ok():
321
494
  The `SandboxPathValidator` prevents path traversal attacks by ensuring all paths stay within your project's base directory. This is crucial for applications that handle user input or load paths from external sources.
322
495
 
323
496
  ```python
324
- from project_paths import ProjectPaths
325
- from project_paths.builtin_validators import SandboxPathValidator
497
+ from path_link import ProjectPaths
498
+ from path_link.builtin_validators import SandboxPathValidator
326
499
 
327
500
  paths = ProjectPaths.from_pyproject()
328
501
 
@@ -386,7 +559,7 @@ targeted_sandbox = SandboxPathValidator(
386
559
  Generate a static dataclass for better IDE support:
387
560
 
388
561
  ```python
389
- from project_paths import write_dataclass_file
562
+ from path_link import write_dataclass_file
390
563
 
391
564
  # Generate src/project_paths/project_paths_static.py
392
565
  write_dataclass_file()
@@ -395,7 +568,7 @@ write_dataclass_file()
395
568
  This creates a fully typed dataclass that can be imported:
396
569
 
397
570
  ```python
398
- from project_paths.project_paths_static import ProjectPathsStatic
571
+ from path_link.project_paths_static import ProjectPathsStatic
399
572
 
400
573
  paths = ProjectPathsStatic()
401
574
  # Now you get full IDE autocomplete!
@@ -407,7 +580,7 @@ Create your own validators by creating a class with a `validate` method that ret
407
580
 
408
581
  ```python
409
582
  from dataclasses import dataclass
410
- from project_paths import Finding, Severity, ValidationResult, ProjectPaths
583
+ from path_link import Finding, Severity, ValidationResult, ProjectPaths
411
584
 
412
585
  @dataclass
413
586
  class MyCustomValidator:
@@ -443,7 +616,7 @@ Combine multiple validators to run them as a single pipeline.
443
616
 
444
617
  ```python
445
618
  # Assuming MyCustomValidator is defined as in the previous example
446
- from project_paths.builtin_validators import CompositeValidator, StrictPathValidator
619
+ from path_link.builtin_validators import CompositeValidator, StrictPathValidator
447
620
 
448
621
  # 1. Load paths
449
622
  paths = ProjectPaths.from_pyproject()
@@ -469,7 +642,7 @@ if not final_result.ok():
469
642
  The package includes bundled documentation that can be accessed programmatically, even in offline or airgapped environments. This is especially useful for AI assistants helping users with the package.
470
643
 
471
644
  ```python
472
- from project_paths import get_ai_guidelines, get_developer_guide, get_metadata
645
+ from path_link import get_ai_guidelines, get_developer_guide, get_metadata
473
646
  import json
474
647
 
475
648
  # Get AI assistant guidelines (comprehensive usage patterns and best practices)
@@ -533,8 +706,8 @@ uv run pytest tests/test_validators.py
533
706
 
534
707
  ```bash
535
708
  # Clone the repository
536
- git clone https://github.com/yourusername/ptool-serena.git
537
- cd ptool-serena
709
+ git clone https://github.com/jaahdytyspalvelu/path-link.git
710
+ cd path-link
538
711
 
539
712
  # Install with uv
540
713
  uv sync
@@ -619,8 +792,8 @@ MIT License - see LICENSE file for details.
619
792
 
620
793
  ## 🔗 Links
621
794
 
622
- - [Documentation](https://github.com/yourusername/ptool-serena/docs)
623
- - [Issue Tracker](https://github.com/yourusername/ptool-serena/issues)
795
+ - [Documentation](https://github.com/jaahdytyspalvelu/path-link/docs)
796
+ - [Issue Tracker](https://github.com/jaahdytyspalvelu/path-link/issues)
624
797
  - [Changelog](CHANGELOG.md)
625
798
 
626
799
  ## 💡 Examples
@@ -640,4 +813,4 @@ Check out the `tests/examples/` directory for more usage examples:
640
813
 
641
814
  ---
642
815
 
643
- Made with ❤️ for Python developers who value type safety and clean configuration management.
816
+ Made with ❤️ for Python developers who value type safety and clean configuration management.# path-link
@@ -0,0 +1,23 @@
1
+ path_link/__init__.py,sha256=sCXmpOGfNC6XFmoKr_XC61sZg43T6HxURKCeRr5SH38,5336
2
+ path_link/builder.py,sha256=08ltmPoFAjrMAupGosWT51meRY5pI90hB4MAXyvVOkQ,4525
3
+ path_link/cli.py,sha256=RX7mfLjBJPvMqcqadmAXRlJ4HtvPkZjDA2i24HQsrNM,12182
4
+ path_link/get_paths.py,sha256=yiA_IBSCqxt4NqtdQK5nzw7jw3toPh_hVbfRtatRM2w,4279
5
+ path_link/main.py,sha256=HxvBm4gr44u42HBfhwLOP1w4ZKGKGj9Ke_-4uQ-31QY,70
6
+ path_link/model.py,sha256=sE11Mh8JpPyxu07--fo19w3xZTPIa9SuU1NjetisiXU,2821
7
+ path_link/project_paths_static.py,sha256=24oAFbYAEL30xv3XA9VX_RoRaXNAaCBQOz16tCGa2fQ,558
8
+ path_link/url_factory.py,sha256=X6x4xjTrZ9hBKWczR_rSyAIOIPZ-QXFoxRLV5YwJNFQ,7298
9
+ path_link/url_model.py,sha256=6WivnMyMqf8iDP-KAhPYDQOLHhd_9jkYCMZBxiQQBhA,5004
10
+ path_link/url_static.py,sha256=sIF-6c1lPyOerVmbzky8no9WN1qz_EqaQev3X0_SXpU,4343
11
+ path_link/validation.py,sha256=JBKu2-NmU_x5jomLFrXy0sT87SiL9w1CpvWGq0QvOhc,2674
12
+ path_link/builtin_validators/__init__.py,sha256=dyjbHMJsx_LmNmaVz_Sr--SY-25mvZOmzJmgcnQXktM,257
13
+ path_link/builtin_validators/sandbox.py,sha256=LQRLJJvhFZQTfuvEaobC7LJg4rBZrmkZ_HfxK3Go43U,5617
14
+ path_link/builtin_validators/strict.py,sha256=Vv9AE2IDaSjqfp8Ujq570KQzB0C0HBcvxTFGwj5z-Qk,4098
15
+ path_link/docs/ai_guidelines.md,sha256=Ad_XRn-zytothC7BaexK2Up_gFWaBOtlc0jH9XrKGFI,19673
16
+ path_link/docs/developer_guide.md,sha256=FYry_R2_xvW6CTxAibL708Ebj6itLMVDq43USDLV-6E,12286
17
+ path_link/docs/metadata.json,sha256=_F8eX9j6nS4NSl_K-X4LEpb6bkeK0_v3YzRbuhb_pCc,4210
18
+ path_link-0.3.0.dist-info/licenses/LICENSE,sha256=aA7G9nVFO_aZED5c8AfjAIlwvLH09zkdwmYefc070r4,1158
19
+ path_link-0.3.0.dist-info/METADATA,sha256=QrT9CBTlOoIalwqpqUVdzxsZv-d3GWfBb8Y1pjUqOvs,22272
20
+ path_link-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ path_link-0.3.0.dist-info/entry_points.txt,sha256=dIGBrnENeLmR4y_1_VAa5qM8Sb5B3YHII9fx9q_71RM,48
22
+ path_link-0.3.0.dist-info/top_level.txt,sha256=LCfRsRoJFLC0Mrb94KvJTLcNv3rBtO5FuIJu2yF-9fM,10
23
+ path_link-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pathlink = path_link.cli:main
@@ -0,0 +1 @@
1
+ path_link
@@ -1,20 +0,0 @@
1
- path_link-0.2.0.dist-info/licenses/LICENSE,sha256=aA7G9nVFO_aZED5c8AfjAIlwvLH09zkdwmYefc070r4,1158
2
- project_paths/__init__.py,sha256=1zVkmr-8iQGJ71HMHMJhPw9bkode5pFTtH0g4_K2IW0,5103
3
- project_paths/builder.py,sha256=yMFNDg51MG4jHIDTKcMzzcN5YU2wLBtB5crYkq0jhWU,2675
4
- project_paths/cli.py,sha256=0K_2nQZOE2uFMmbcNmA1VEv13oB-YV_ad36Qy9Z1dAw,6644
5
- project_paths/get_paths.py,sha256=U_hnGKxa14-om1RLUbKpkoTgp9-hgguVLJkbGc8_h40,4270
6
- project_paths/main.py,sha256=HxvBm4gr44u42HBfhwLOP1w4ZKGKGj9Ke_-4uQ-31QY,70
7
- project_paths/model.py,sha256=4qrm72Fh0NRuid3i3X0G_tT_lOz06PM5vQxYyi85R9o,2812
8
- project_paths/project_paths_static.py,sha256=0K-Vi2RIrHHJJ56N3C6CCTEYUHzzcHnGx-FTEuHUKuE,558
9
- project_paths/validation.py,sha256=JBKu2-NmU_x5jomLFrXy0sT87SiL9w1CpvWGq0QvOhc,2674
10
- project_paths/builtin_validators/__init__.py,sha256=2fvsBGxrpo5YHI8D5aDFtb73PuXg86gzw23Um_rQf_A,201
11
- project_paths/builtin_validators/sandbox.py,sha256=7rki6esWVVLhOIt7xmfyCWNzUxqX81qxzBBcrZra7FY,5601
12
- project_paths/builtin_validators/strict.py,sha256=mKLjjn5Y_HEfL_aLL8_ZlC4r_hZMS4MfMGKrR2BYJCs,4082
13
- project_paths/docs/ai_guidelines.md,sha256=fUVd7h2ChO5YJ3zPUoQ5DLNcSEpKAHVwSSTYoIj8K1M,19802
14
- project_paths/docs/developer_guide.md,sha256=e-s-8kMHEiApZurwc6Gvc6P1SIe1crfOf00-hZyjndU,12361
15
- project_paths/docs/metadata.json,sha256=Pgo1Xa8dDOItJaYLP16UTztFd-1ensI3tIRc5c4-8qA,4233
16
- path_link-0.2.0.dist-info/METADATA,sha256=uYoiksSeA6Xq4kpRyDFgBoJXMmhYdiE5hygQvLbkCF0,18065
17
- path_link-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
- path_link-0.2.0.dist-info/entry_points.txt,sha256=-9RmhjQTx5GtiJ2YLyUWRIaLlHQperuSrniLiq8yT2M,49
19
- path_link-0.2.0.dist-info/top_level.txt,sha256=iW2KR0fh0Zp23tT_drLikfiZ1Imr5tJpCdZKmg42dA4,14
20
- path_link-0.2.0.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- ptool = project_paths.cli:main
@@ -1 +0,0 @@
1
- project_paths
@@ -1,6 +0,0 @@
1
- """Built-in validators for common validation scenarios."""
2
-
3
- from .strict import StrictPathValidator
4
- from .sandbox import SandboxPathValidator
5
-
6
- __all__ = ["StrictPathValidator", "SandboxPathValidator"]
File without changes
File without changes