python-package-folder 1.0.0__tar.gz → 1.1.1__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.
Files changed (39) hide show
  1. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.vscode/settings.json +1 -0
  2. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/PKG-INFO +215 -130
  3. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/README.md +214 -129
  4. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/coverage.svg +2 -2
  5. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/finder.py +39 -10
  6. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/manager.py +57 -5
  7. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/python_package_folder.py +7 -1
  8. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.copier-answers.yml +0 -0
  9. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.cursor/rules/general.mdc +0 -0
  10. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.cursor/rules/python.mdc +0 -0
  11. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.github/workflows/ci.yml +0 -0
  12. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.github/workflows/publish.yml +0 -0
  13. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/.gitignore +0 -0
  14. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/LICENSE +0 -0
  15. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/Makefile +0 -0
  16. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/development.md +0 -0
  17. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/installation.md +0 -0
  18. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/publishing.md +0 -0
  19. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/pyproject.toml +0 -0
  20. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/__init__.py +0 -0
  21. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/__main__.py +0 -0
  22. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/analyzer.py +0 -0
  23. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/publisher.py +0 -0
  24. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/py.typed +0 -0
  25. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/subfolder_build.py +0 -0
  26. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/types.py +0 -0
  27. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/utils.py +0 -0
  28. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/src/python_package_folder/version.py +0 -0
  29. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/folder_structure/some_globals.py +0 -0
  30. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/folder_structure/subfolder_to_build/README.md +0 -0
  31. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
  32. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/folder_structure/utility_folder/some_utility.py +0 -0
  33. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/test_build_with_external_deps.py +0 -0
  34. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/test_publisher.py +0 -0
  35. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/test_subfolder_build.py +0 -0
  36. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/test_utils.py +0 -0
  37. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/test_version_manager.py +0 -0
  38. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/tests/tests.py +0 -0
  39. {python_package_folder-1.0.0 → python_package_folder-1.1.1}/uv.lock +0 -0
@@ -1,4 +1,5 @@
1
1
  {
2
+ "markdown.extension.toc.levels": "1..2",
2
3
  "python.testing.pytestArgs": [
3
4
  "tests"
4
5
  ],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-package-folder
3
- Version: 1.0.0
3
+ Version: 1.1.1
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>
@@ -18,42 +18,143 @@ Classifier: Typing :: Typed
18
18
  Requires-Python: <4.0,>=3.11
19
19
  Description-Content-Type: text/markdown
20
20
 
21
- # python-package-folder
21
+ # python-package-folder <!-- omit from toc -->
22
22
 
23
23
  [![Tests](https://github.com/alelom/python-package-folder/actions/workflows/ci.yml/badge.svg)](https://github.com/alelom/python-package-folder/actions/workflows/ci.yml)
24
24
  [![Coverage](https://raw.githubusercontent.com/alelom/python-package-folder/main/coverage.svg)](https://github.com/alelom/python-package-folder)
25
25
 
26
- Python package to automatically analyze, detect, and manage external dependencies when building Python packages. This tool recursively parses all Python files in your project, identifies imports from outside the main package directory, and temporarily copies them into the source directory during the build process.
26
+ Easily build and publish any target folder in a repository, including subfolders of a monorepo.
27
+ Together with [sysappend](https://pypi.org/project/sysappend/), this library makes relative imports, flexible import management, and package publishing a breeze.
28
+
29
+ - [Use Cases](#use-cases)
30
+ - [Features](#features)
31
+ - [Installation and requirements](#installation-and-requirements)
32
+ - [Quick Start](#quick-start)
33
+ - [How does `python-package-folder` work?](#how-does-python-package-folder-work)
34
+ - [Python API Usage](#python-api-usage)
35
+ - [Working with sysappend](#working-with-sysappend)
36
+ - [Publishing version Management](#publishing-version-management)
37
+ - [Publishing Packages](#publishing-packages)
38
+ - [Command Line Options](#command-line-options)
39
+ - [API Reference](#api-reference)
40
+ - [Development](#development)
41
+
42
+
43
+ ## Use Cases
44
+
45
+ ### 1) Publishing a Subfolder from src/ in a Monorepo
46
+
47
+ If you have a monorepo structure with multiple packages in `src/`:
48
+
49
+ ```
50
+ project/
51
+ ├── src/
52
+ │ ├── core_package/
53
+ │ │ ├── __init__.py
54
+ │ │ ├── core.py
55
+ │ │ └── README.md
56
+ │ ├── api_package/
57
+ │ │ ├── __init__.py
58
+ │ │ ├── api.py
59
+ │ │ └── README.md
60
+ │ └── utils_package/
61
+ │ ├── __init__.py
62
+ │ ├── utils.py
63
+ │ └── README.md
64
+ ├── shared/
65
+ │ └── common.py
66
+ └── pyproject.toml
67
+ ```
68
+
69
+ You can build and publish any subfolder from `src/` as a standalone package:
70
+
71
+ ```bash
72
+ # Navigate to the subfolder you want to publish
73
+ cd src/api_package
74
+
75
+ # Build and publish to TestPyPI with version 1.2.0
76
+ python-package-folder --publish testpypi --version 1.2.0
77
+
78
+ # Or publish to PyPI with a custom package name
79
+ python-package-folder --publish pypi --version 1.2.0 --package-name "my-api-package"
80
+
81
+ # Include a specific dependency group from the parent pyproject.toml
82
+ python-package-folder --publish pypi --version 1.2.0 --dependency-group "dev"
83
+ ```
84
+
85
+ The tool will automatically:
86
+ 1. Detect the project root (where `pyproject.toml` is located)
87
+ 2. Use `src/api_package` as the source directory
88
+ 3. Copy any external dependencies (like `shared/common.py`) into the package before building
89
+ 4. Use the subfolder's README if present, or create a minimal one
90
+ 5. Create a temporary `pyproject.toml` with the subfolder's package name and version
91
+ 6. Build and publish the package
92
+ 7. Clean up all temporary files and restore the original `pyproject.toml`
93
+
94
+ This is especially useful for monorepos where you want to publish individual packages independently while sharing common code.
95
+
96
+
97
+ ### 2) Building Packages with Shared Code
98
+
99
+ If your project structure looks like this:
100
+
101
+ ```
102
+ project/
103
+ ├── src/
104
+ │ └── my_package/
105
+ │ └── main.py
106
+ ├── shared/
107
+ │ ├── utils.py
108
+ │ └── helpers.py
109
+ └── pyproject.toml
110
+ ```
111
+
112
+ And `main.py` imports from `shared/`:
113
+
114
+ ```python
115
+ from shared.utils import some_function
116
+ from shared.helpers import Helper
117
+ ```
118
+
119
+ This package will automatically:
120
+ 1. Detect that `shared/` is outside `src/`
121
+ 2. Copy `shared/` into `src/` before building
122
+ 3. Build your package with all dependencies included
123
+ 4. Clean up the copied files after build
124
+
27
125
 
28
126
  ## Features
29
127
 
30
- - **Automatic Import Analysis**: Recursively parses all `.py` files to detect `import` and `from ... import ...` statements
31
- - **Smart Import Classification**: Distinguishes between:
32
- - Standard library imports
33
- - Third-party packages (from site-packages)
34
- - Local imports (within the source directory)
35
- - External imports (outside source directory but in the project)
36
- - Ambiguous imports (unresolvable)
37
- - **External Dependency Detection**: Automatically finds modules and files that originate from outside the main package directory
38
- - **Temporary File Management**: Copies external dependencies into the source directory before build and cleans them up afterward
128
+ - **Subfolder Build Support**: Build subfolders as separate packages with automatic project root detection
129
+ - 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
+ - Automatic package name derivation from subfolder name
131
+ - Dependency group selection: specify which dependency group from parent `pyproject.toml` to include.
132
+
133
+ - **Smart Import Classification and analysis**:
134
+ - Recursively parses all `.py` files to detect `import` and `from ... import ...` statements
135
+ - Handles external dependencies (modules and files that originate from outside the main package directory), and distinguishes standard library imports, 3rd-party packages (from site-packages), local/external/relative/ambiguous imports.
136
+
39
137
  - **Idempotent Operations**: Safely handles repeated runs without duplicating files
40
138
  - **Build Integration**: Seamlessly integrates with build tools like `uv build`, `pip build`, etc.
41
- - **Warning System**: Reports ambiguous imports that couldn't be resolved
42
- - **Subfolder Build Support**: Build subfolders as separate packages with automatic project root detection
43
- - **Smart Publishing**: Only uploads distribution files from the current build, filtering out old artifacts
44
- - **Auto-Detection**: Automatically finds project root and source directory when run from any subdirectory
45
- - **Authentication Helpers**: Auto-detects API tokens and uses correct username format
139
+ - **Version Management**:
140
+ - Set static versions for publishing (PEP 440 compliant)
141
+ - Temporarily override dynamic versioning during builds
142
+ - Automatic restoration of dynamic versioning after build
143
+ - **Package Publishing**:
144
+ - Uses twine to publish the built folder/subfolder
145
+ - Handles publishing to to PyPI, TestPyPI, or Azure Artifacts, with interactive credential prompts, secure storage support
46
146
 
47
- ## Installation
48
147
 
49
- ```bash
50
- pip install python-package-folder
51
- ```
148
+ ## Installation and requirements
52
149
 
53
- Or using `uv`:
150
+ Python >= 3.11 is required.
54
151
 
55
152
  ```bash
56
153
  uv add python-package-folder
154
+
155
+ # or
156
+
157
+ pip install python-package-folder
57
158
  ```
58
159
 
59
160
  **Note**: For publishing functionality, you'll also need `twine`:
@@ -64,30 +165,97 @@ pip install twine
64
165
  uv add twine
65
166
  ```
66
167
 
168
+ **For secure credential storage**: `keyring` is optional but recommended (install with `pip install keyring`)
169
+
170
+
67
171
  ## Quick Start
68
172
 
69
- ### Command Line Usage
173
+ The simplest way to use this package is via the command-line interface
70
174
 
71
- The simplest way to use this package is via the command-line interface:
175
+ **Build/publish a specific subfolder in a repository**
176
+
177
+ Useful for monorepos containing many subfolders that may need publishing as stand-alone packages for external usage.
72
178
 
73
179
  ```bash
74
- # Build with automatic dependency management (from project root)
75
- python-package-folder --build-command "uv build"
180
+ # First cd to the specific subfolder
181
+ cd src/subfolder_to_build_and_publish
76
182
 
77
- # Analyze dependencies without building
78
- python-package-folder --analyze-only
183
+ # Build and publish any subdirectory of your repo to TestPyPi (https://test.pypi.org/)
184
+ python-package-folder --publish testpypi --version 0.0.2
79
185
 
80
- # Build from any subdirectory - auto-detects project root and source directory
81
- cd tests/folder_structure/subfolder_to_build
186
+ # Only analyse (no building)
187
+ cd src/subfolder_to_build_and_publish
82
188
  python-package-folder --analyze-only
83
189
 
190
+ # Only build
191
+ cd src/subfolder_to_build_and_publish
192
+ python-package-folder
193
+
194
+ # Build with automatic dependency management
195
+ python-package-folder --build-command "uv build"
196
+ ```
197
+
198
+ You can also target a specific subfolder via commandline, rather than `cd`ing there:
199
+
200
+ ```python
84
201
  # Specify custom project root and source directory
85
202
  python-package-folder --project-root /path/to/project --src-dir /path/to/src --build-command "pip build"
86
203
  ```
87
204
 
88
- ### Building from Subdirectories
205
+ ## How does `python-package-folder` work?
206
+
207
+
208
+ ### Build Process
209
+
210
+ 1. **Import Extraction**: Uses Python's AST module to parse all `.py` files and extract import statements
211
+ 2. **Classification**: Each import is classified as:
212
+ - **stdlib**: Standard library modules
213
+ - **third_party**: Packages installed in site-packages
214
+ - **local**: Modules within the source directory
215
+ - **external**: Modules outside source directory but in the project
216
+ - **ambiguous**: Cannot be resolved
217
+ 3. **Dependency Resolution**: For external imports, the tool resolves the file path by checking:
218
+ - Parent directories of the source directory
219
+ - Project root and its subdirectories
220
+ - Relative import paths
221
+ 4. **File Copying**: External dependencies are temporarily copied into the source directory
222
+ 5. **Build Execution**: Your build command runs with all dependencies in place
223
+ 6. **Cleanup**: All temporarily copied files are removed after build
224
+
225
+ ### Publishing Process
226
+
227
+ 1. **Build Verification**: Ensures distribution files exist in the `dist/` directory
228
+ 2. **File Filtering**: Automatically filters distribution files to only include those matching the current package name and version (prevents uploading old artifacts)
229
+ 3. **Credential Management**:
230
+ - Prompts for credentials if not provided
231
+ - Uses `keyring` for secure storage (if available)
232
+ - Supports both username/password and API tokens
233
+ - Auto-detects API tokens and uses `__token__` as username
234
+ 4. **Repository Configuration**: Configures the target repository (PyPI, TestPyPI, or Azure)
235
+ 5. **Upload**: Uses `twine` to upload distribution files to the repository
236
+ 6. **Verification**: Confirms successful upload
237
+
238
+ ### Subfolder Build Process
89
239
 
90
- The tool can automatically detect the project root by searching for `pyproject.toml` in parent directories. This allows you to build subfolders of a main project as separate packages:
240
+ 1. **Project Root Detection**: Searches parent directories for `pyproject.toml`
241
+ 2. **Source Directory Detection**: Uses current directory if it contains Python files, otherwise falls back to `project_root/src`
242
+ 3. **Package Initialization**: Creates temporary `__init__.py` if subfolder doesn't have one (required for hatchling)
243
+ 4. **README Handling**:
244
+ - Checks for README files in the subfolder (README.md, README.rst, README.txt, or README)
245
+ - If found, copies the subfolder README to project root (backing up the original parent README)
246
+ - If not found, creates a minimal README with just the folder name
247
+ 5. **Configuration Creation**: Creates temporary `pyproject.toml` with:
248
+ - Subfolder-specific package name (derived or custom)
249
+ - Specified version
250
+ - Correct package path for hatchling
251
+ 6. **Build Execution**: Runs build command with all dependencies in place
252
+ 7. **Cleanup**: Restores original `pyproject.toml` and removes temporary `__init__.py`
253
+
254
+ ### How does building from Subdirectories work?
255
+
256
+ This is useful for monorepos containing many subfolders that may need publishing as stand-alone packages for external usage.
257
+ The tool automatically detects the project root by searching for `pyproject.toml` in parent directories.
258
+ This allows you to build subfolders of a main project as separate packages:
91
259
 
92
260
  ```bash
93
261
  # From a subdirectory, the tool will:
@@ -100,7 +268,7 @@ cd my_project/subfolder_to_build
100
268
  python-package-folder --version "1.0.0" --publish pypi
101
269
  ```
102
270
 
103
- **Important**: When building from a subdirectory, you **must** specify `--version` because subfolders are built as separate packages with their own version.
271
+ When building from a subdirectory, you **must** specify `--version` because subfolders are built as separate packages with their own version.
104
272
 
105
273
  The tool automatically:
106
274
  - Finds the project root by looking for `pyproject.toml` in parent directories
@@ -136,7 +304,7 @@ python-package-folder --version "1.0.0" --dependency-group "dev" --publish pypi
136
304
 
137
305
  The specified dependency group will be copied from the parent `pyproject.toml`'s `[dependency-groups]` section into the temporary `pyproject.toml` used for the subfolder build.
138
306
 
139
- ### Python API Usage
307
+ ## Python API Usage
140
308
 
141
309
  You can also use the package programmatically:
142
310
 
@@ -180,37 +348,7 @@ def build_command():
180
348
  manager.run_build(build_command)
181
349
  ```
182
350
 
183
- ## Use Cases
184
-
185
- ### Building Packages with Shared Code
186
-
187
- If your project structure looks like this:
188
-
189
- ```
190
- project/
191
- ├── src/
192
- │ └── my_package/
193
- │ └── main.py
194
- ├── shared/
195
- │ ├── utils.py
196
- │ └── helpers.py
197
- └── pyproject.toml
198
- ```
199
-
200
- And `main.py` imports from `shared/`:
201
-
202
- ```python
203
- from shared.utils import some_function
204
- from shared.helpers import Helper
205
- ```
206
-
207
- This package will automatically:
208
- 1. Detect that `shared/` is outside `src/`
209
- 2. Copy `shared/` into `src/` before building
210
- 3. Build your package with all dependencies included
211
- 4. Clean up the copied files after build
212
-
213
- ### Working with sysappend
351
+ ## Working with sysappend
214
352
 
215
353
  This package works well with projects using [sysappend](https://pypi.org/project/sysappend/) for flexible import management. When you have imports like:
216
354
 
@@ -224,10 +362,11 @@ from folder_structure.utility_folder.some_utility import print_something
224
362
 
225
363
  The package will correctly identify and copy external dependencies even when they're referenced without full package paths.
226
364
 
227
- ## Version Management
365
+ ## Publishing version Management
228
366
 
229
367
  The package supports both dynamic versioning (from git tags) and manual version specification.
230
368
 
369
+
231
370
  ### Manual Version Setting
232
371
 
233
372
  You can manually set a version before building and publishing:
@@ -251,6 +390,7 @@ The `--version` option:
251
390
 
252
391
  **Version Format**: Versions must follow PEP 440 (e.g., `1.2.3`, `1.2.3a1`, `1.2.3.post1`, `1.2.3.dev1`)
253
392
 
393
+
254
394
  ### Subfolder Versioning
255
395
 
256
396
  When building from a subdirectory (not the main `src/` directory), you **must** specify `--version`:
@@ -278,6 +418,7 @@ For subfolder builds:
278
418
  - If no README exists in the subfolder, a minimal README with just the folder name will be created
279
419
  - **Auto-restore**: Original `pyproject.toml` is restored after build, and temporary `__init__.py` files are removed
280
420
 
421
+
281
422
  ### Python API for Version Management
282
423
 
283
424
  ```python
@@ -318,6 +459,7 @@ When you use `--version`, the package temporarily switches to static versioning
318
459
 
319
460
  The package includes built-in support for publishing to PyPI, TestPyPI, and Azure Artifacts.
320
461
 
462
+
321
463
  ### Command Line Publishing
322
464
 
323
465
  Publish after building:
@@ -346,6 +488,7 @@ python-package-folder --publish pypi --username __token__ --password pypi-xxxxx
346
488
  python-package-folder --publish pypi --skip-existing
347
489
  ```
348
490
 
491
+
349
492
  ### Credentials
350
493
 
351
494
  **For PyPI/TestPyPI:**
@@ -357,6 +500,7 @@ python-package-folder --publish pypi --skip-existing
357
500
  - **403 Forbidden**: Usually means you used your username instead of `__token__` with an API token. The tool now auto-detects this.
358
501
  - **TestPyPI vs PyPI**: TestPyPI requires a separate account and token from https://test.pypi.org/manage/account/token/
359
502
 
503
+
360
504
  ### Smart File Filtering
361
505
 
362
506
  When publishing, the tool automatically filters distribution files to only upload those matching the current build:
@@ -377,6 +521,7 @@ To get a PyPI API token:
377
521
  - **Password**: Personal Access Token (PAT) with packaging permissions
378
522
  - **Repository URL**: Your Azure Artifacts feed URL
379
523
 
524
+
380
525
  ### Python API Publishing
381
526
 
382
527
  You can also publish programmatically:
@@ -417,6 +562,7 @@ publisher = Publisher(
417
562
  publisher.publish()
418
563
  ```
419
564
 
565
+
420
566
  ### Credential Storage
421
567
 
422
568
  The package uses the `keyring` library (if installed) to securely store credentials. Credentials are stored per repository and will be reused on subsequent runs.
@@ -600,59 +746,6 @@ config.restore()
600
746
  - If no README exists in the subfolder, a minimal README with just the folder name will be created
601
747
  - The original parent README is backed up and restored after the build completes
602
748
 
603
- ## How It Works
604
-
605
- ### Build Process
606
-
607
- 1. **Import Extraction**: Uses Python's AST module to parse all `.py` files and extract import statements
608
- 2. **Classification**: Each import is classified as:
609
- - **stdlib**: Standard library modules
610
- - **third_party**: Packages installed in site-packages
611
- - **local**: Modules within the source directory
612
- - **external**: Modules outside source directory but in the project
613
- - **ambiguous**: Cannot be resolved
614
- 3. **Dependency Resolution**: For external imports, the tool resolves the file path by checking:
615
- - Parent directories of the source directory
616
- - Project root and its subdirectories
617
- - Relative import paths
618
- 4. **File Copying**: External dependencies are temporarily copied into the source directory
619
- 5. **Build Execution**: Your build command runs with all dependencies in place
620
- 6. **Cleanup**: All temporarily copied files are removed after build
621
-
622
- ### Publishing Process
623
-
624
- 1. **Build Verification**: Ensures distribution files exist in the `dist/` directory
625
- 2. **File Filtering**: Automatically filters distribution files to only include those matching the current package name and version (prevents uploading old artifacts)
626
- 3. **Credential Management**:
627
- - Prompts for credentials if not provided
628
- - Uses `keyring` for secure storage (if available)
629
- - Supports both username/password and API tokens
630
- - Auto-detects API tokens and uses `__token__` as username
631
- 4. **Repository Configuration**: Configures the target repository (PyPI, TestPyPI, or Azure)
632
- 5. **Upload**: Uses `twine` to upload distribution files to the repository
633
- 6. **Verification**: Confirms successful upload
634
-
635
- ### Subfolder Build Process
636
-
637
- 1. **Project Root Detection**: Searches parent directories for `pyproject.toml`
638
- 2. **Source Directory Detection**: Uses current directory if it contains Python files, otherwise falls back to `project_root/src`
639
- 3. **Package Initialization**: Creates temporary `__init__.py` if subfolder doesn't have one (required for hatchling)
640
- 4. **README Handling**:
641
- - Checks for README files in the subfolder (README.md, README.rst, README.txt, or README)
642
- - If found, copies the subfolder README to project root (backing up the original parent README)
643
- - If not found, creates a minimal README with just the folder name
644
- 5. **Configuration Creation**: Creates temporary `pyproject.toml` with:
645
- - Subfolder-specific package name (derived or custom)
646
- - Specified version
647
- - Correct package path for hatchling
648
- 6. **Build Execution**: Runs build command with all dependencies in place
649
- 7. **Cleanup**: Restores original `pyproject.toml` and removes temporary `__init__.py`
650
-
651
- ## Requirements
652
-
653
- - Python >= 3.11
654
- - **For publishing**: `twine` is required (install with `pip install twine`)
655
- - **For secure credential storage**: `keyring` is optional but recommended (install with `pip install keyring`)
656
749
 
657
750
  ## Development
658
751
 
@@ -673,7 +766,7 @@ uv run pytest
673
766
  make lint
674
767
  ```
675
768
 
676
- ### Project Structure
769
+ ### Project Structure
677
770
 
678
771
  ```
679
772
  python-package-folder/
@@ -693,18 +786,10 @@ python-package-folder/
693
786
  └── pyproject.toml
694
787
  ```
695
788
 
696
- ## License
789
+ ## License <!-- omit from toc -->
697
790
 
698
791
  MIT License - see LICENSE file for details
699
792
 
700
- ## Contributing
793
+ ## Contributing <!-- omit from toc -->
701
794
 
702
795
  Contributions are welcome! Please feel free to submit a Pull Request.
703
-
704
- ## Author
705
-
706
- Alessio Lombardi - [GitHub](https://github.com/alelom)
707
-
708
- ## Related Projects
709
-
710
- - [sysappend](https://pypi.org/project/sysappend/) - Flexible import management for Python projects