python-package-folder 1.1.3__tar.gz → 1.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.
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/PKG-INFO +95 -22
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/README.md +94 -21
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/coverage.svg +2 -2
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/manager.py +175 -57
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/subfolder_build.py +69 -13
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_subfolder_build.py +288 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.copier-answers.yml +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.cursor/rules/general.mdc +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.cursor/rules/python.mdc +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.github/workflows/ci.yml +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.github/workflows/publish.yml +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.gitignore +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/.vscode/settings.json +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/LICENSE +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/Makefile +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/development.md +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/installation.md +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/publishing.md +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/pyproject.toml +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/__init__.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/__main__.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/analyzer.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/finder.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/publisher.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/py.typed +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/python_package_folder.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/types.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/utils.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/src/python_package_folder/version.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/folder_structure/some_globals.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/folder_structure/subfolder_to_build/README.md +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/folder_structure/utility_folder/_SS/some_superseded_file.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/folder_structure/utility_folder/some_utility.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_build_with_external_deps.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_linting.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_publisher.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_utils.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/test_version_manager.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/tests/tests.py +0 -0
- {python_package_folder-1.1.3 → python_package_folder-1.2.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-package-folder
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Python package to automatically package and build a folder, fetching all relevant dependencies.
|
|
5
5
|
Project-URL: Repository, https://github.com/alelom/python-package-folder
|
|
6
6
|
Author-email: Alessio Lombardi <work@alelom.com>
|
|
@@ -125,9 +125,11 @@ This package will automatically:
|
|
|
125
125
|
|
|
126
126
|
## Features
|
|
127
127
|
|
|
128
|
-
- **Subfolder Build Support**: Build subfolders as separate packages with automatic
|
|
128
|
+
- **Subfolder Build Support**: Build subfolders as separate packages with automatic detection and configuration
|
|
129
|
+
- **Automatic subfolder detection**: Detects when building a subfolder (not the main `src/` directory)
|
|
129
130
|
- Creates any needed file for publishing automatically, cleaning up if not originally in the subfolder after the build/publish process. E.g. copies external dependencies into the source directory before build and cleans them up afterward; temporary `__init__.py` creation for non-package subfolders; uses subfolder README if present, otherwise creates minimal README
|
|
130
131
|
- Automatic package name derivation from subfolder name
|
|
132
|
+
- Automatic temporary `pyproject.toml` creation with correct package structure
|
|
131
133
|
- Dependency group selection: specify which dependency group from parent `pyproject.toml` to include.
|
|
132
134
|
|
|
133
135
|
- **Smart Import Classification and analysis**:
|
|
@@ -268,16 +270,20 @@ cd my_project/subfolder_to_build
|
|
|
268
270
|
python-package-folder --version "1.0.0" --publish pypi
|
|
269
271
|
```
|
|
270
272
|
|
|
271
|
-
|
|
273
|
+
The tool **automatically detects** when you're building a subfolder (any directory that's not the main `src/` directory) and sets up the appropriate build configuration.
|
|
272
274
|
|
|
273
275
|
The tool automatically:
|
|
276
|
+
- **Detects subfolder builds**: Automatically identifies when building from a subdirectory
|
|
274
277
|
- Finds the project root by looking for `pyproject.toml` in parent directories
|
|
275
278
|
- Uses the current directory as the source directory if it contains Python files
|
|
276
279
|
- Falls back to `project_root/src` if the current directory isn't suitable
|
|
277
|
-
- For subfolder builds
|
|
278
|
-
-
|
|
279
|
-
-
|
|
280
|
-
|
|
280
|
+
- **For subfolder builds**: Handles `pyproject.toml` configuration:
|
|
281
|
+
- **If `pyproject.toml` exists in subfolder**: Uses that file (copies it to project root temporarily)
|
|
282
|
+
- **If no `pyproject.toml` in subfolder**: Creates a temporary `pyproject.toml` with:
|
|
283
|
+
- Package name derived from the subfolder name (e.g., `empty_drawing_detection` → `empty-drawing-detection`)
|
|
284
|
+
- Version from `--version` argument (defaults to `0.0.0` with a warning if not provided)
|
|
285
|
+
- Proper package path configuration for hatchling
|
|
286
|
+
- Dependency groups from parent `pyproject.toml` if specified
|
|
281
287
|
- Creates temporary `__init__.py` files if needed to make subfolders valid Python packages
|
|
282
288
|
- **README handling for subfolder builds**:
|
|
283
289
|
- If a README file (README.md, README.rst, README.txt, or README) exists in the subfolder, it will be used instead of the parent README
|
|
@@ -285,6 +291,8 @@ The tool automatically:
|
|
|
285
291
|
- Restores the original `pyproject.toml` after build (unless `--no-restore-versioning` is used)
|
|
286
292
|
- Cleans up temporary `__init__.py` files after build
|
|
287
293
|
|
|
294
|
+
**Note**: While version is not strictly required (defaults to `0.0.0`), it's recommended to specify `--version` for subfolder builds to ensure proper versioning.
|
|
295
|
+
|
|
288
296
|
**Subfolder Build Example:**
|
|
289
297
|
```bash
|
|
290
298
|
# Build a subfolder as a separate package
|
|
@@ -293,6 +301,11 @@ python-package-folder --version "0.1.0" --package-name "my-subfolder-package" --
|
|
|
293
301
|
|
|
294
302
|
# Build with a specific dependency group from parent pyproject.toml
|
|
295
303
|
python-package-folder --version "0.1.0" --dependency-group "dev" --publish pypi
|
|
304
|
+
|
|
305
|
+
# If subfolder has its own pyproject.toml, it will be used automatically
|
|
306
|
+
# (package-name and version arguments are ignored in this case)
|
|
307
|
+
cd src/integration/my_package # assuming my_package/pyproject.toml exists
|
|
308
|
+
python-package-folder --publish pypi
|
|
296
309
|
```
|
|
297
310
|
|
|
298
311
|
**Dependency Groups**: When building a subfolder, you can specify a dependency group from the parent `pyproject.toml` to include in the subfolder's build configuration. This allows subfolders to inherit specific dependencies from the parent project:
|
|
@@ -308,6 +321,8 @@ The specified dependency group will be copied from the parent `pyproject.toml`'s
|
|
|
308
321
|
|
|
309
322
|
You can also use the package programmatically:
|
|
310
323
|
|
|
324
|
+
### Basic Usage
|
|
325
|
+
|
|
311
326
|
```python
|
|
312
327
|
from pathlib import Path
|
|
313
328
|
from python_package_folder import BuildManager
|
|
@@ -328,11 +343,11 @@ for dep in external_deps:
|
|
|
328
343
|
# Run your build process here
|
|
329
344
|
# ...
|
|
330
345
|
|
|
331
|
-
# Cleanup copied files
|
|
346
|
+
# Cleanup copied files (also restores pyproject.toml if subfolder build)
|
|
332
347
|
manager.cleanup()
|
|
333
348
|
```
|
|
334
349
|
|
|
335
|
-
|
|
350
|
+
### Using the Convenience Method
|
|
336
351
|
|
|
337
352
|
```python
|
|
338
353
|
from pathlib import Path
|
|
@@ -348,6 +363,55 @@ def build_command():
|
|
|
348
363
|
manager.run_build(build_command)
|
|
349
364
|
```
|
|
350
365
|
|
|
366
|
+
### Subfolder Builds (Automatic Detection)
|
|
367
|
+
|
|
368
|
+
The tool automatically detects when you're building a subfolder and sets up the appropriate configuration:
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
from pathlib import Path
|
|
372
|
+
from python_package_folder import BuildManager
|
|
373
|
+
import subprocess
|
|
374
|
+
|
|
375
|
+
# Building a subfolder - automatic detection!
|
|
376
|
+
manager = BuildManager(
|
|
377
|
+
project_root=Path("."),
|
|
378
|
+
src_dir=Path("src/integration/empty_drawing_detection")
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
def build_command():
|
|
382
|
+
subprocess.run(["uv", "build"], check=True)
|
|
383
|
+
|
|
384
|
+
# prepare_build() automatically:
|
|
385
|
+
# - Detects this is a subfolder build
|
|
386
|
+
# - If pyproject.toml exists in subfolder: uses that file
|
|
387
|
+
# - If no pyproject.toml in subfolder: creates temporary one with package name "empty-drawing-detection"
|
|
388
|
+
# - Uses version "0.0.0" (or pass version="1.0.0" to override) if creating temporary pyproject.toml
|
|
389
|
+
external_deps = manager.prepare_build(version="1.0.0")
|
|
390
|
+
|
|
391
|
+
# Run build - uses the pyproject.toml (either from subfolder or temporary)
|
|
392
|
+
build_command()
|
|
393
|
+
|
|
394
|
+
# Cleanup restores original pyproject.toml and removes copied files
|
|
395
|
+
manager.cleanup()
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Note**: If the subfolder has its own `pyproject.toml`, it will be used automatically. The `version` and `package_name` parameters are only used when creating a temporary `pyproject.toml` from the parent configuration.
|
|
399
|
+
|
|
400
|
+
Or use the convenience method:
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
manager = BuildManager(
|
|
404
|
+
project_root=Path("."),
|
|
405
|
+
src_dir=Path("src/integration/empty_drawing_detection")
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
def build_command():
|
|
409
|
+
subprocess.run(["uv", "build"], check=True)
|
|
410
|
+
|
|
411
|
+
# All handled automatically: subfolder detection, pyproject.toml setup, build, cleanup
|
|
412
|
+
manager.run_build(build_command, version="1.0.0", package_name="my-custom-name")
|
|
413
|
+
```
|
|
414
|
+
|
|
351
415
|
## Working with sysappend
|
|
352
416
|
|
|
353
417
|
This package works well with projects using [sysappend](https://pypi.org/project/sysappend/) for flexible import management. When you have imports like:
|
|
@@ -393,20 +457,28 @@ The `--version` option:
|
|
|
393
457
|
|
|
394
458
|
### Subfolder Versioning
|
|
395
459
|
|
|
396
|
-
When building from a subdirectory (not the main `src/` directory),
|
|
460
|
+
When building from a subdirectory (not the main `src/` directory), the tool automatically detects the subfolder and sets up the build configuration:
|
|
397
461
|
|
|
398
462
|
```bash
|
|
399
|
-
# Build a subfolder as a separate package
|
|
463
|
+
# Build a subfolder as a separate package (version recommended but not required)
|
|
400
464
|
cd my_project/subfolder_to_build
|
|
401
465
|
python-package-folder --version "1.0.0" --publish pypi
|
|
402
466
|
|
|
403
467
|
# With custom package name
|
|
404
468
|
python-package-folder --version "1.0.0" --package-name "my-custom-name" --publish pypi
|
|
469
|
+
|
|
470
|
+
# Version defaults to "0.0.0" if not specified (with a warning)
|
|
471
|
+
python-package-folder --publish pypi
|
|
405
472
|
```
|
|
406
473
|
|
|
407
474
|
For subfolder builds:
|
|
408
|
-
- **
|
|
409
|
-
- **
|
|
475
|
+
- **Automatic detection**: The tool automatically detects subfolder builds
|
|
476
|
+
- **pyproject.toml handling**:
|
|
477
|
+
- If `pyproject.toml` exists in subfolder: Uses that file (copied to project root temporarily)
|
|
478
|
+
- If no `pyproject.toml` in subfolder: Creates temporary one with correct package structure
|
|
479
|
+
- **Version**: Recommended but not required when creating temporary pyproject.toml. If not provided, defaults to `0.0.0` with a warning. Ignored if subfolder has its own `pyproject.toml`.
|
|
480
|
+
- **Package name**: Automatically derived from the subfolder name (e.g., `subfolder_to_build` → `subfolder-to-build`). Only used when creating temporary pyproject.toml.
|
|
481
|
+
- **Restoration**: Original `pyproject.toml` is restored after build
|
|
410
482
|
- **Temporary configuration**: Creates a temporary `pyproject.toml` with:
|
|
411
483
|
- Custom package name (from `--package-name` or derived)
|
|
412
484
|
- Specified version
|
|
@@ -715,7 +787,8 @@ version_manager.restore_dynamic_versioning()
|
|
|
715
787
|
|
|
716
788
|
### SubfolderBuildConfig
|
|
717
789
|
|
|
718
|
-
Manages temporary build configuration for subfolder builds.
|
|
790
|
+
Manages temporary build configuration for subfolder builds. If a `pyproject.toml` exists
|
|
791
|
+
in the subfolder, it will be used instead of creating a new one.
|
|
719
792
|
|
|
720
793
|
```python
|
|
721
794
|
from python_package_folder import SubfolderBuildConfig
|
|
@@ -724,11 +797,11 @@ from pathlib import Path
|
|
|
724
797
|
config = SubfolderBuildConfig(
|
|
725
798
|
project_root=Path("."),
|
|
726
799
|
src_dir=Path("subfolder"),
|
|
727
|
-
package_name="my-subfolder",
|
|
728
|
-
version="1.0.0"
|
|
800
|
+
package_name="my-subfolder", # Only used if subfolder has no pyproject.toml
|
|
801
|
+
version="1.0.0" # Only used if subfolder has no pyproject.toml
|
|
729
802
|
)
|
|
730
803
|
|
|
731
|
-
# Create temporary pyproject.toml
|
|
804
|
+
# Create temporary pyproject.toml (or use subfolder's if it exists)
|
|
732
805
|
config.create_temp_pyproject()
|
|
733
806
|
|
|
734
807
|
# ... build process ...
|
|
@@ -738,13 +811,13 @@ config.restore()
|
|
|
738
811
|
```
|
|
739
812
|
|
|
740
813
|
**Methods:**
|
|
741
|
-
- `create_temp_pyproject() -> Path`:
|
|
814
|
+
- `create_temp_pyproject() -> Path`: Use subfolder's `pyproject.toml` if it exists, otherwise create temporary `pyproject.toml` with subfolder-specific configuration
|
|
742
815
|
- `restore() -> None`: Restore original `pyproject.toml` and clean up temporary files
|
|
743
816
|
|
|
744
|
-
**Note**: This class automatically
|
|
745
|
-
- If a
|
|
746
|
-
- If no README exists in the subfolder, a minimal README with just the folder name will be created
|
|
747
|
-
-
|
|
817
|
+
**Note**: This class automatically:
|
|
818
|
+
- **pyproject.toml handling**: If a `pyproject.toml` exists in the subfolder, it will be used (copied to project root temporarily). Otherwise, creates a temporary one from the parent configuration.
|
|
819
|
+
- **README handling**: If a README exists in the subfolder, it will be used instead of the parent README. If no README exists in the subfolder, a minimal README with just the folder name will be created. The original parent README is backed up and restored after the build completes.
|
|
820
|
+
- **Package initialization**: Creates `__init__.py` files if needed to make subfolders valid Python packages.
|
|
748
821
|
|
|
749
822
|
|
|
750
823
|
## Development
|
|
@@ -105,9 +105,11 @@ This package will automatically:
|
|
|
105
105
|
|
|
106
106
|
## Features
|
|
107
107
|
|
|
108
|
-
- **Subfolder Build Support**: Build subfolders as separate packages with automatic
|
|
108
|
+
- **Subfolder Build Support**: Build subfolders as separate packages with automatic detection and configuration
|
|
109
|
+
- **Automatic subfolder detection**: Detects when building a subfolder (not the main `src/` directory)
|
|
109
110
|
- Creates any needed file for publishing automatically, cleaning up if not originally in the subfolder after the build/publish process. E.g. copies external dependencies into the source directory before build and cleans them up afterward; temporary `__init__.py` creation for non-package subfolders; uses subfolder README if present, otherwise creates minimal README
|
|
110
111
|
- Automatic package name derivation from subfolder name
|
|
112
|
+
- Automatic temporary `pyproject.toml` creation with correct package structure
|
|
111
113
|
- Dependency group selection: specify which dependency group from parent `pyproject.toml` to include.
|
|
112
114
|
|
|
113
115
|
- **Smart Import Classification and analysis**:
|
|
@@ -248,16 +250,20 @@ cd my_project/subfolder_to_build
|
|
|
248
250
|
python-package-folder --version "1.0.0" --publish pypi
|
|
249
251
|
```
|
|
250
252
|
|
|
251
|
-
|
|
253
|
+
The tool **automatically detects** when you're building a subfolder (any directory that's not the main `src/` directory) and sets up the appropriate build configuration.
|
|
252
254
|
|
|
253
255
|
The tool automatically:
|
|
256
|
+
- **Detects subfolder builds**: Automatically identifies when building from a subdirectory
|
|
254
257
|
- Finds the project root by looking for `pyproject.toml` in parent directories
|
|
255
258
|
- Uses the current directory as the source directory if it contains Python files
|
|
256
259
|
- Falls back to `project_root/src` if the current directory isn't suitable
|
|
257
|
-
- For subfolder builds
|
|
258
|
-
-
|
|
259
|
-
-
|
|
260
|
-
|
|
260
|
+
- **For subfolder builds**: Handles `pyproject.toml` configuration:
|
|
261
|
+
- **If `pyproject.toml` exists in subfolder**: Uses that file (copies it to project root temporarily)
|
|
262
|
+
- **If no `pyproject.toml` in subfolder**: Creates a temporary `pyproject.toml` with:
|
|
263
|
+
- Package name derived from the subfolder name (e.g., `empty_drawing_detection` → `empty-drawing-detection`)
|
|
264
|
+
- Version from `--version` argument (defaults to `0.0.0` with a warning if not provided)
|
|
265
|
+
- Proper package path configuration for hatchling
|
|
266
|
+
- Dependency groups from parent `pyproject.toml` if specified
|
|
261
267
|
- Creates temporary `__init__.py` files if needed to make subfolders valid Python packages
|
|
262
268
|
- **README handling for subfolder builds**:
|
|
263
269
|
- If a README file (README.md, README.rst, README.txt, or README) exists in the subfolder, it will be used instead of the parent README
|
|
@@ -265,6 +271,8 @@ The tool automatically:
|
|
|
265
271
|
- Restores the original `pyproject.toml` after build (unless `--no-restore-versioning` is used)
|
|
266
272
|
- Cleans up temporary `__init__.py` files after build
|
|
267
273
|
|
|
274
|
+
**Note**: While version is not strictly required (defaults to `0.0.0`), it's recommended to specify `--version` for subfolder builds to ensure proper versioning.
|
|
275
|
+
|
|
268
276
|
**Subfolder Build Example:**
|
|
269
277
|
```bash
|
|
270
278
|
# Build a subfolder as a separate package
|
|
@@ -273,6 +281,11 @@ python-package-folder --version "0.1.0" --package-name "my-subfolder-package" --
|
|
|
273
281
|
|
|
274
282
|
# Build with a specific dependency group from parent pyproject.toml
|
|
275
283
|
python-package-folder --version "0.1.0" --dependency-group "dev" --publish pypi
|
|
284
|
+
|
|
285
|
+
# If subfolder has its own pyproject.toml, it will be used automatically
|
|
286
|
+
# (package-name and version arguments are ignored in this case)
|
|
287
|
+
cd src/integration/my_package # assuming my_package/pyproject.toml exists
|
|
288
|
+
python-package-folder --publish pypi
|
|
276
289
|
```
|
|
277
290
|
|
|
278
291
|
**Dependency Groups**: When building a subfolder, you can specify a dependency group from the parent `pyproject.toml` to include in the subfolder's build configuration. This allows subfolders to inherit specific dependencies from the parent project:
|
|
@@ -288,6 +301,8 @@ The specified dependency group will be copied from the parent `pyproject.toml`'s
|
|
|
288
301
|
|
|
289
302
|
You can also use the package programmatically:
|
|
290
303
|
|
|
304
|
+
### Basic Usage
|
|
305
|
+
|
|
291
306
|
```python
|
|
292
307
|
from pathlib import Path
|
|
293
308
|
from python_package_folder import BuildManager
|
|
@@ -308,11 +323,11 @@ for dep in external_deps:
|
|
|
308
323
|
# Run your build process here
|
|
309
324
|
# ...
|
|
310
325
|
|
|
311
|
-
# Cleanup copied files
|
|
326
|
+
# Cleanup copied files (also restores pyproject.toml if subfolder build)
|
|
312
327
|
manager.cleanup()
|
|
313
328
|
```
|
|
314
329
|
|
|
315
|
-
|
|
330
|
+
### Using the Convenience Method
|
|
316
331
|
|
|
317
332
|
```python
|
|
318
333
|
from pathlib import Path
|
|
@@ -328,6 +343,55 @@ def build_command():
|
|
|
328
343
|
manager.run_build(build_command)
|
|
329
344
|
```
|
|
330
345
|
|
|
346
|
+
### Subfolder Builds (Automatic Detection)
|
|
347
|
+
|
|
348
|
+
The tool automatically detects when you're building a subfolder and sets up the appropriate configuration:
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
from pathlib import Path
|
|
352
|
+
from python_package_folder import BuildManager
|
|
353
|
+
import subprocess
|
|
354
|
+
|
|
355
|
+
# Building a subfolder - automatic detection!
|
|
356
|
+
manager = BuildManager(
|
|
357
|
+
project_root=Path("."),
|
|
358
|
+
src_dir=Path("src/integration/empty_drawing_detection")
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
def build_command():
|
|
362
|
+
subprocess.run(["uv", "build"], check=True)
|
|
363
|
+
|
|
364
|
+
# prepare_build() automatically:
|
|
365
|
+
# - Detects this is a subfolder build
|
|
366
|
+
# - If pyproject.toml exists in subfolder: uses that file
|
|
367
|
+
# - If no pyproject.toml in subfolder: creates temporary one with package name "empty-drawing-detection"
|
|
368
|
+
# - Uses version "0.0.0" (or pass version="1.0.0" to override) if creating temporary pyproject.toml
|
|
369
|
+
external_deps = manager.prepare_build(version="1.0.0")
|
|
370
|
+
|
|
371
|
+
# Run build - uses the pyproject.toml (either from subfolder or temporary)
|
|
372
|
+
build_command()
|
|
373
|
+
|
|
374
|
+
# Cleanup restores original pyproject.toml and removes copied files
|
|
375
|
+
manager.cleanup()
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Note**: If the subfolder has its own `pyproject.toml`, it will be used automatically. The `version` and `package_name` parameters are only used when creating a temporary `pyproject.toml` from the parent configuration.
|
|
379
|
+
|
|
380
|
+
Or use the convenience method:
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
manager = BuildManager(
|
|
384
|
+
project_root=Path("."),
|
|
385
|
+
src_dir=Path("src/integration/empty_drawing_detection")
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
def build_command():
|
|
389
|
+
subprocess.run(["uv", "build"], check=True)
|
|
390
|
+
|
|
391
|
+
# All handled automatically: subfolder detection, pyproject.toml setup, build, cleanup
|
|
392
|
+
manager.run_build(build_command, version="1.0.0", package_name="my-custom-name")
|
|
393
|
+
```
|
|
394
|
+
|
|
331
395
|
## Working with sysappend
|
|
332
396
|
|
|
333
397
|
This package works well with projects using [sysappend](https://pypi.org/project/sysappend/) for flexible import management. When you have imports like:
|
|
@@ -373,20 +437,28 @@ The `--version` option:
|
|
|
373
437
|
|
|
374
438
|
### Subfolder Versioning
|
|
375
439
|
|
|
376
|
-
When building from a subdirectory (not the main `src/` directory),
|
|
440
|
+
When building from a subdirectory (not the main `src/` directory), the tool automatically detects the subfolder and sets up the build configuration:
|
|
377
441
|
|
|
378
442
|
```bash
|
|
379
|
-
# Build a subfolder as a separate package
|
|
443
|
+
# Build a subfolder as a separate package (version recommended but not required)
|
|
380
444
|
cd my_project/subfolder_to_build
|
|
381
445
|
python-package-folder --version "1.0.0" --publish pypi
|
|
382
446
|
|
|
383
447
|
# With custom package name
|
|
384
448
|
python-package-folder --version "1.0.0" --package-name "my-custom-name" --publish pypi
|
|
449
|
+
|
|
450
|
+
# Version defaults to "0.0.0" if not specified (with a warning)
|
|
451
|
+
python-package-folder --publish pypi
|
|
385
452
|
```
|
|
386
453
|
|
|
387
454
|
For subfolder builds:
|
|
388
|
-
- **
|
|
389
|
-
- **
|
|
455
|
+
- **Automatic detection**: The tool automatically detects subfolder builds
|
|
456
|
+
- **pyproject.toml handling**:
|
|
457
|
+
- If `pyproject.toml` exists in subfolder: Uses that file (copied to project root temporarily)
|
|
458
|
+
- If no `pyproject.toml` in subfolder: Creates temporary one with correct package structure
|
|
459
|
+
- **Version**: Recommended but not required when creating temporary pyproject.toml. If not provided, defaults to `0.0.0` with a warning. Ignored if subfolder has its own `pyproject.toml`.
|
|
460
|
+
- **Package name**: Automatically derived from the subfolder name (e.g., `subfolder_to_build` → `subfolder-to-build`). Only used when creating temporary pyproject.toml.
|
|
461
|
+
- **Restoration**: Original `pyproject.toml` is restored after build
|
|
390
462
|
- **Temporary configuration**: Creates a temporary `pyproject.toml` with:
|
|
391
463
|
- Custom package name (from `--package-name` or derived)
|
|
392
464
|
- Specified version
|
|
@@ -695,7 +767,8 @@ version_manager.restore_dynamic_versioning()
|
|
|
695
767
|
|
|
696
768
|
### SubfolderBuildConfig
|
|
697
769
|
|
|
698
|
-
Manages temporary build configuration for subfolder builds.
|
|
770
|
+
Manages temporary build configuration for subfolder builds. If a `pyproject.toml` exists
|
|
771
|
+
in the subfolder, it will be used instead of creating a new one.
|
|
699
772
|
|
|
700
773
|
```python
|
|
701
774
|
from python_package_folder import SubfolderBuildConfig
|
|
@@ -704,11 +777,11 @@ from pathlib import Path
|
|
|
704
777
|
config = SubfolderBuildConfig(
|
|
705
778
|
project_root=Path("."),
|
|
706
779
|
src_dir=Path("subfolder"),
|
|
707
|
-
package_name="my-subfolder",
|
|
708
|
-
version="1.0.0"
|
|
780
|
+
package_name="my-subfolder", # Only used if subfolder has no pyproject.toml
|
|
781
|
+
version="1.0.0" # Only used if subfolder has no pyproject.toml
|
|
709
782
|
)
|
|
710
783
|
|
|
711
|
-
# Create temporary pyproject.toml
|
|
784
|
+
# Create temporary pyproject.toml (or use subfolder's if it exists)
|
|
712
785
|
config.create_temp_pyproject()
|
|
713
786
|
|
|
714
787
|
# ... build process ...
|
|
@@ -718,13 +791,13 @@ config.restore()
|
|
|
718
791
|
```
|
|
719
792
|
|
|
720
793
|
**Methods:**
|
|
721
|
-
- `create_temp_pyproject() -> Path`:
|
|
794
|
+
- `create_temp_pyproject() -> Path`: Use subfolder's `pyproject.toml` if it exists, otherwise create temporary `pyproject.toml` with subfolder-specific configuration
|
|
722
795
|
- `restore() -> None`: Restore original `pyproject.toml` and clean up temporary files
|
|
723
796
|
|
|
724
|
-
**Note**: This class automatically
|
|
725
|
-
- If a
|
|
726
|
-
- If no README exists in the subfolder, a minimal README with just the folder name will be created
|
|
727
|
-
-
|
|
797
|
+
**Note**: This class automatically:
|
|
798
|
+
- **pyproject.toml handling**: If a `pyproject.toml` exists in the subfolder, it will be used (copied to project root temporarily). Otherwise, creates a temporary one from the parent configuration.
|
|
799
|
+
- **README handling**: If a README exists in the subfolder, it will be used instead of the parent README. If no README exists in the subfolder, a minimal README with just the folder name will be created. The original parent README is backed up and restored after the build completes.
|
|
800
|
+
- **Package initialization**: Creates `__init__.py` files if needed to make subfolders valid Python packages.
|
|
728
801
|
|
|
729
802
|
|
|
730
803
|
## Development
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
|
15
15
|
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
|
16
16
|
<text x="31.5" y="14">coverage</text>
|
|
17
|
-
<text x="81" y="15" fill="#010101" fill-opacity=".3">
|
|
18
|
-
<text x="81" y="14">
|
|
17
|
+
<text x="81" y="15" fill="#010101" fill-opacity=".3">67%</text>
|
|
18
|
+
<text x="81" y="14">67%</text>
|
|
19
19
|
</g>
|
|
20
20
|
</svg>
|