python-package-folder 4.3.6__py3-none-any.whl → 5.0.1__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.
@@ -10,19 +10,22 @@ It can be invoked via:
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import logging
13
14
  import os
14
- import shutil
15
15
  import subprocess
16
16
  import sys
17
17
  from pathlib import Path
18
18
 
19
- try:
20
- from importlib import resources
21
- except ImportError:
22
- import importlib_resources as resources # type: ignore[no-redef]
23
-
24
19
  from .manager import BuildManager
25
20
  from .utils import find_project_root, find_source_directory
21
+ from .version_calculator import resolve_version
22
+
23
+ # Configure logging for version resolution
24
+ logging.basicConfig(
25
+ level=logging.INFO,
26
+ format="%(levelname)s: %(message)s",
27
+ handlers=[logging.StreamHandler(sys.stderr)],
28
+ )
26
29
 
27
30
 
28
31
  def is_github_actions() -> bool:
@@ -30,225 +33,6 @@ def is_github_actions() -> bool:
30
33
  return os.getenv("GITHUB_ACTIONS") == "true"
31
34
 
32
35
 
33
- def check_node_available() -> bool:
34
- """Check if Node.js is available."""
35
- return shutil.which("node") is not None
36
-
37
-
38
- def resolve_version_via_semantic_release(
39
- project_root: Path,
40
- subfolder_path: Path | None = None,
41
- package_name: str | None = None,
42
- repository: str | None = None,
43
- repository_url: str | None = None,
44
- ) -> tuple[str | None, str | None]:
45
- """
46
- Resolve the next version using semantic-release via Node.js script.
47
-
48
- Args:
49
- project_root: Root directory of the project
50
- subfolder_path: Optional path to subfolder (relative to project_root) for Workflow 1
51
- package_name: Optional package name for subfolder builds
52
- repository: Optional target repository ('pypi', 'testpypi', or 'azure')
53
- repository_url: Optional repository URL (required for Azure Artifacts)
54
-
55
- Returns:
56
- Tuple of (version string if a release is determined, error message if any)
57
- Returns (None, None) if no release or no error, (None, error_msg) on error
58
- """
59
- # Note: Node.js availability should be checked before calling this function
60
- # This check is a safety fallback
61
- if not check_node_available():
62
- if is_github_actions():
63
- error_msg = """Node.js is not available in this GitHub Actions workflow.
64
-
65
- To fix this, add the following steps BEFORE running python-package-folder:
66
-
67
- - name: Setup Node.js
68
- uses: actions/setup-node@v4
69
- with:
70
- node-version: '20'
71
-
72
- - name: Install semantic-release
73
- run: |
74
- npm install -g semantic-release semantic-release-commit-filter
75
-
76
- Alternatively, provide --version explicitly to skip automatic version resolution."""
77
- print(f"Error: {error_msg}", file=sys.stderr)
78
- return None, error_msg
79
- else:
80
- error_msg = "Node.js not found. Cannot resolve version via semantic-release."
81
- print(f"Error: {error_msg}", file=sys.stderr)
82
- return None, error_msg
83
-
84
- # Try to find the script in multiple locations:
85
- # 1. Project root / scripts (for development or when script is in repo)
86
- # 2. Package installation directory / scripts (for installed package)
87
- # - For normal installs: direct file path
88
- # - For zip/pex installs: extract to temporary file using as_file()
89
-
90
- # Track temporary file context for cleanup
91
- temp_script_context = None
92
-
93
- try:
94
- # First, try project root (development)
95
- dev_script = project_root / "scripts" / "get-next-version.cjs"
96
- if dev_script.exists():
97
- script_path = dev_script
98
- else:
99
- # Try to locate script in installed package using importlib.resources
100
- script_path = None
101
- diagnostic_info = []
102
-
103
- # Try importlib.resources approach
104
- try:
105
- package = resources.files("python_package_folder")
106
- script_resource = package / "scripts" / "get-next-version.cjs"
107
-
108
- diagnostic_info.append(f"Checked importlib.resources: python_package_folder/scripts/get-next-version.cjs")
109
-
110
- if script_resource.is_file():
111
- # Try direct path conversion first (normal file system install)
112
- try:
113
- script_path_candidate = Path(str(script_resource))
114
- if script_path_candidate.exists():
115
- script_path = script_path_candidate
116
- diagnostic_info.append(f"Found via direct path: {script_path}")
117
- except (TypeError, ValueError) as e:
118
- diagnostic_info.append(f"Direct path conversion failed: {e}")
119
-
120
- # If direct path didn't work, try as_file() for zip/pex installs
121
- if script_path is None:
122
- try:
123
- temp_script_context = resources.as_file(script_resource)
124
- script_path = temp_script_context.__enter__()
125
- diagnostic_info.append(f"Found via as_file() (temp): {script_path}")
126
- except (TypeError, ValueError, OSError) as e:
127
- diagnostic_info.append(f"as_file() extraction failed: {e}")
128
- else:
129
- # Try to list what's actually in the scripts directory
130
- try:
131
- scripts_dir = package / "scripts"
132
- if scripts_dir.is_dir():
133
- available_files = list(scripts_dir.iterdir())
134
- diagnostic_info.append(f"Scripts directory exists. Available files: {[f.name for f in available_files]}")
135
- else:
136
- diagnostic_info.append("Scripts directory does not exist in package")
137
- except Exception as e:
138
- diagnostic_info.append(f"Could not list scripts directory: {e}")
139
- except (ImportError, ModuleNotFoundError, TypeError, AttributeError, OSError) as e:
140
- diagnostic_info.append(f"importlib.resources failed: {type(e).__name__}: {e}")
141
-
142
- # Fallback: try relative to package directory
143
- if script_path is None:
144
- package_dir = Path(__file__).parent
145
- fallback_script = package_dir / "scripts" / "get-next-version.cjs"
146
- diagnostic_info.append(f"Checked fallback path: {fallback_script}")
147
- if fallback_script.exists():
148
- script_path = fallback_script
149
- diagnostic_info.append(f"Found via fallback: {script_path}")
150
- else:
151
- diagnostic_info.append(f"Fallback path does not exist")
152
-
153
- if not script_path:
154
- error_msg = "Could not locate get-next-version.cjs script"
155
- error_msg += "\n\nDiagnostic information:"
156
- for info in diagnostic_info:
157
- error_msg += f"\n - {info}"
158
- error_msg += (
159
- "\n\nThis usually means the script was not included in the installed package."
160
- "\nPlease ensure you're using the latest version of python-package-folder."
161
- "\nIf the issue persists, report this as a bug."
162
- )
163
- print(f"Error: {error_msg}", file=sys.stderr)
164
- return None, error_msg
165
-
166
- # Build command arguments
167
- cmd = ["node", str(script_path), str(project_root)]
168
- if subfolder_path and package_name:
169
- # Workflow 1: subfolder build
170
- rel_path = (
171
- subfolder_path.relative_to(project_root)
172
- if subfolder_path.is_absolute()
173
- else subfolder_path
174
- )
175
- cmd.extend([str(rel_path), package_name])
176
- elif package_name:
177
- # Main package build with package_name (for registry queries)
178
- # Pass null for subfolder_path, then package_name
179
- cmd.extend(["", package_name])
180
- # Workflow 2: main package without package_name (no additional args needed)
181
-
182
- # Add repository information if provided
183
- if repository:
184
- cmd.append(repository)
185
- if repository_url:
186
- cmd.append(repository_url)
187
-
188
- result = subprocess.run(
189
- cmd,
190
- capture_output=True,
191
- text=True,
192
- cwd=project_root,
193
- check=False,
194
- )
195
-
196
- if result.returncode != 0:
197
- # Collect error details
198
- error_details = []
199
- if result.stderr:
200
- error_details.append(f"stderr: {result.stderr}")
201
- if result.stdout:
202
- error_details.append(f"stdout: {result.stdout}")
203
-
204
- error_msg = "semantic-release version resolution failed"
205
- if error_details:
206
- error_msg += f": {'; '.join(error_details)}"
207
-
208
- print(f"Error: {error_msg}", file=sys.stderr)
209
- return None, error_msg
210
-
211
- version = result.stdout.strip()
212
- if version and version != "none":
213
- return version, None
214
-
215
- return None, None
216
- except FileNotFoundError:
217
- # Node.js not found (shouldn't happen if check_node_available() passed, but handle gracefully)
218
- if is_github_actions():
219
- error_msg = """Node.js is not available in this GitHub Actions workflow.
220
-
221
- To fix this, add the following steps BEFORE running python-package-folder:
222
-
223
- - name: Setup Node.js
224
- uses: actions/setup-node@v4
225
- with:
226
- node-version: '20'
227
-
228
- - name: Install semantic-release
229
- run: |
230
- npm install -g semantic-release semantic-release-commit-filter
231
-
232
- Alternatively, provide --version explicitly to skip automatic version resolution."""
233
- print(f"Error: {error_msg}", file=sys.stderr)
234
- return None, error_msg
235
- else:
236
- error_msg = "Node.js not found. Cannot resolve version via semantic-release."
237
- print(f"Error: {error_msg}", file=sys.stderr)
238
- return None, error_msg
239
- except Exception as e:
240
- # Other errors (e.g., permission issues, script not found)
241
- error_msg = f"Error resolving version via semantic-release: {e}"
242
- print(f"Error: {error_msg}", file=sys.stderr)
243
- return None, error_msg
244
- finally:
245
- # Clean up temporary file if we extracted from zip/pex
246
- # This must be at function level to ensure cleanup even on early return
247
- if temp_script_context is not None:
248
- try:
249
- temp_script_context.__exit__(None, None, None)
250
- except Exception:
251
- pass
252
36
 
253
37
 
254
38
  def main() -> int:
@@ -310,7 +94,7 @@ def main() -> int:
310
94
  )
311
95
  parser.add_argument(
312
96
  "--version",
313
- help="Set a specific version before building (PEP 440 format, e.g., '1.2.3'). Optional: if omitted, version will be resolved via semantic-release when needed.",
97
+ help="Set a specific version before building (PEP 440 format, e.g., '1.2.3'). Optional: if omitted, version will be resolved via conventional commits when needed.",
314
98
  )
315
99
  parser.add_argument(
316
100
  "--package-name",
@@ -391,51 +175,12 @@ def main() -> int:
391
175
  and src_dir != project_root
392
176
  )
393
177
 
394
- # Resolve version via semantic-release if not provided and needed
178
+ # Resolve version via conventional commits if not provided and needed
395
179
  resolved_version = args.version
396
180
  if not resolved_version and not args.analyze_only:
397
181
  # Version is needed for subfolder builds or when publishing main package
398
182
  if is_subfolder or args.publish:
399
- print("No --version provided, attempting to resolve via semantic-release...")
400
-
401
- # Check Node.js availability upfront
402
- if not check_node_available():
403
- if is_github_actions():
404
- error_msg = """Node.js is not available in this GitHub Actions workflow.
405
-
406
- To fix this, add the following steps BEFORE running python-package-folder:
407
-
408
- - name: Setup Node.js
409
- uses: actions/setup-node@v4
410
- with:
411
- node-version: '20'
412
-
413
- - name: Install semantic-release
414
- run: |
415
- npm install -g semantic-release semantic-release-commit-filter
416
-
417
- Alternatively, provide --version explicitly to skip automatic version resolution."""
418
- print(f"Error: {error_msg}", file=sys.stderr)
419
- else:
420
- print(
421
- "Error: Node.js is not available. Cannot resolve version via semantic-release.",
422
- file=sys.stderr,
423
- )
424
- print(
425
- "Please install Node.js or provide --version explicitly.",
426
- file=sys.stderr,
427
- )
428
- return 1
429
-
430
- # Log that Node.js is available (for debugging)
431
- node_version = subprocess.run(
432
- ["node", "--version"],
433
- capture_output=True,
434
- text=True,
435
- check=False,
436
- )
437
- if node_version.returncode == 0:
438
- print(f"Node.js detected: {node_version.stdout.strip()}")
183
+ print("No --version provided, attempting to resolve via conventional commits...")
439
184
 
440
185
  # Get repository info if publishing
441
186
  repository = args.publish if args.publish else None
@@ -448,10 +193,10 @@ Alternatively, provide --version explicitly to skip automatic version resolution
448
193
  " ", "-"
449
194
  ).lower().strip("-")
450
195
  subfolder_rel_path = src_dir.relative_to(project_root)
451
- resolved_version, error_details = resolve_version_via_semantic_release(
196
+ resolved_version, error_details = resolve_version(
452
197
  project_root,
453
- subfolder_rel_path,
454
- package_name,
198
+ package_name=package_name,
199
+ subfolder_path=subfolder_rel_path,
455
200
  repository=repository,
456
201
  repository_url=repository_url,
457
202
  )
@@ -470,31 +215,25 @@ Alternatively, provide --version explicitly to skip automatic version resolution
470
215
  except Exception:
471
216
  pass
472
217
 
473
- resolved_version, error_details = resolve_version_via_semantic_release(
218
+ resolved_version, error_details = resolve_version(
474
219
  project_root,
475
- subfolder_path=None,
476
220
  package_name=package_name_for_registry,
221
+ subfolder_path=None,
477
222
  repository=repository,
478
223
  repository_url=repository_url,
479
224
  )
480
225
 
481
226
  if resolved_version:
482
- print(f"Resolved version via semantic-release: {resolved_version}")
227
+ print(f"Resolved version via conventional commits: {resolved_version}")
483
228
  else:
484
229
  error_msg = (
485
- "Could not resolve version via semantic-release.\n"
230
+ "Could not resolve version via conventional commits.\n"
486
231
  "This could mean:\n"
487
232
  " - No release is needed (no relevant commits)\n"
488
- " - semantic-release is not installed or configured\n"
233
+ " - No baseline version found (no registry version or git tags)\n"
489
234
  )
490
235
  if error_details:
491
236
  error_msg += f"\nDetails: {error_details}\n"
492
- error_msg += (
493
- "\nPlease either:\n"
494
- " - Install semantic-release: npm install -g semantic-release"
495
- )
496
- if is_subfolder:
497
- error_msg += "\n - Install semantic-release-commit-filter: npm install -g semantic-release-commit-filter"
498
237
  error_msg += "\n - Or provide --version explicitly"
499
238
  print(f"Error: {error_msg}", file=sys.stderr)
500
239
  return 1