pypeline-runner 1.23.0__py3-none-any.whl → 1.23.2__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.
pypeline/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.23.0"
1
+ __version__ = "1.23.2"
pypeline/bootstrap/run.py CHANGED
@@ -583,6 +583,7 @@ class CreateVirtualEnvironment(Runnable):
583
583
  self,
584
584
  root_dir: Path,
585
585
  bootstrap_env: CreateBootstrapEnvironment,
586
+ skip_venv_delete: bool = False,
586
587
  ) -> None:
587
588
  self.root_dir = root_dir
588
589
  self.venv_dir = self.root_dir / ".venv"
@@ -591,6 +592,7 @@ class CreateVirtualEnvironment(Runnable):
591
592
  self.bootstrap_env = bootstrap_env
592
593
  self.config = bootstrap_env.config
593
594
  self.python_version_marker = self.venv_dir / VENV_PYTHON_VERSION_MARKER
595
+ self.skip_venv_delete = skip_venv_delete
594
596
 
595
597
  @property
596
598
  def package_manager_name(self) -> str:
@@ -602,6 +604,7 @@ class CreateVirtualEnvironment(Runnable):
602
604
 
603
605
  If the Python version has changed (e.g., switching branches), delete the
604
606
  existing venv so it can be recreated by the package manager.
607
+ If skip_venv_delete is True, log a warning instead of deleting.
605
608
  """
606
609
  if not self.venv_dir.exists():
607
610
  return
@@ -609,19 +612,27 @@ class CreateVirtualEnvironment(Runnable):
609
612
  current_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
610
613
 
611
614
  if not self.python_version_marker.exists():
612
- logger.info(
613
- f"No Python version marker found in {self.venv_dir}. "
614
- f"This venv may have been created before version tracking was added. "
615
- f"Deleting {self.venv_dir} to ensure clean state."
616
- )
617
- shutil.rmtree(self.venv_dir)
615
+ if self.skip_venv_delete:
616
+ logger.warning(f"No Python version marker found in {self.venv_dir}. Cannot verify venv compatibility, but skipping deletion as requested.")
617
+ else:
618
+ logger.info(
619
+ f"No Python version marker found in {self.venv_dir}. "
620
+ f"This venv may have been created before version tracking was added. "
621
+ f"Deleting {self.venv_dir} to ensure clean state."
622
+ )
623
+ shutil.rmtree(self.venv_dir)
618
624
  return
619
625
 
620
626
  try:
621
627
  stored_version = self.python_version_marker.read_text().strip()
622
628
  if stored_version != current_version:
623
- logger.info(f"Python version changed from {stored_version} to {current_version}. Deleting {self.venv_dir} for recreation.")
624
- shutil.rmtree(self.venv_dir)
629
+ if self.skip_venv_delete:
630
+ logger.warning(
631
+ f"Python version changed from {stored_version} to {current_version}. Skipping venv deletion as requested - dependencies will be updated in place."
632
+ )
633
+ else:
634
+ logger.info(f"Python version changed from {stored_version} to {current_version}. Deleting {self.venv_dir} for recreation.")
635
+ shutil.rmtree(self.venv_dir)
625
636
  except OSError as exc:
626
637
  logger.warning(f"Could not read Python version marker: {exc}")
627
638
 
@@ -632,22 +643,31 @@ class CreateVirtualEnvironment(Runnable):
632
643
  except OSError as exc:
633
644
  logger.warning(f"Could not write Python version marker: {exc}")
634
645
 
646
+ def _set_env_var(self, key: str, value: str) -> None:
647
+ """Helper method to set environment variables (easier to mock in tests)."""
648
+ os.environ[key] = value
649
+
635
650
  def _ensure_in_project_venv(self) -> None:
636
651
  """Configure package managers to create venv in-project (.venv in repository)."""
637
652
  if self.package_manager_name == "poetry":
638
653
  # Set environment variable for poetry to create venv in-project
639
- os.environ["POETRY_VIRTUALENVS_IN_PROJECT"] = "true"
654
+ self._set_env_var("POETRY_VIRTUALENVS_IN_PROJECT", "true")
640
655
  elif self.package_manager_name == "pipenv":
641
656
  # Set environment variable for pipenv
642
- os.environ["PIPENV_VENV_IN_PROJECT"] = "1"
657
+ self._set_env_var("PIPENV_VENV_IN_PROJECT", "1")
643
658
  # UV creates .venv in-project by default, no configuration needed
644
659
 
645
660
  def _ensure_correct_python_version(self) -> None:
646
661
  """Ensure the correct Python version is used in the virtual environment."""
647
662
  if self.package_manager_name == "poetry":
648
663
  # Make Poetry use the Python interpreter it's being run with
649
- os.environ["POETRY_VIRTUALENVS_PREFER_ACTIVE_PYTHON"] = "false"
650
- os.environ["POETRY_VIRTUALENVS_USE_POETRY_PYTHON"] = "true"
664
+ self._set_env_var("POETRY_VIRTUALENVS_PREFER_ACTIVE_PYTHON", "false")
665
+ self._set_env_var("POETRY_VIRTUALENVS_USE_POETRY_PYTHON", "true")
666
+ elif self.package_manager_name == "uv":
667
+ # Make UV use the Python interpreter it's being run with
668
+ self._set_env_var("UV_PYTHON", self.config.python_version)
669
+ self._set_env_var("UV_MANAGED_PYTHON", "false")
670
+ self._set_env_var("UV_NO_PYTHON_DOWNLOADS", "true")
651
671
 
652
672
  def _get_install_argument(self) -> str:
653
673
  if self.package_manager_name == "uv":
@@ -763,11 +783,11 @@ def main() -> int:
763
783
  help="Specify the project directory (default: current working directory).",
764
784
  )
765
785
  parser.add_argument(
766
- "--skip-venv-creation",
786
+ "--skip-venv-delete",
767
787
  action="store_true",
768
788
  required=False,
769
789
  default=False,
770
- help="Skip the virtual environment creation process.",
790
+ help="Skip deleting the virtual environment (used when running from within the venv). Dependencies will still be updated.",
771
791
  )
772
792
  parser.add_argument(
773
793
  "--config",
@@ -795,13 +815,11 @@ def main() -> int:
795
815
  bootstrap_executor.execute(bootstrap_env)
796
816
 
797
817
  # Step 2: Create the project virtual environment using the bootstrap env
798
- # Skip if requested (e.g., when running from within the venv)
799
- if not args.skip_venv_creation:
800
- project_venv = CreateVirtualEnvironment(project_dir, bootstrap_env)
801
- project_executor = Executor(project_venv.venv_dir)
802
- project_executor.execute(project_venv)
803
- else:
804
- logger.info("Skipping virtual environment creation as requested.")
818
+ # When skip_venv_delete is True (e.g., running from within the venv),
819
+ # we still update dependencies but skip deleting the venv to avoid write access exceptions
820
+ project_venv = CreateVirtualEnvironment(project_dir, bootstrap_env, skip_venv_delete=args.skip_venv_delete)
821
+ project_executor = Executor(project_venv.venv_dir)
822
+ project_executor.execute(project_venv)
805
823
 
806
824
  except UserNotificationException as exc:
807
825
  logger.error(exc)
@@ -287,11 +287,11 @@ class CreateVEnv(PipelineStep[ExecutionContext]):
287
287
  ).execute()
288
288
  else:
289
289
  # Use internal bootstrap script
290
- skip_venv_creation = False
290
+ skip_venv_delete = False
291
291
  python_executable = Path(sys.executable).absolute()
292
292
  if python_executable.is_relative_to(self.project_root_dir):
293
- self.logger.info(f"Detected that the python executable '{python_executable}' is from the virtual environment. Skip updating the virtual environment.")
294
- skip_venv_creation = True
293
+ self.logger.info(f"Detected that the python executable '{python_executable}' is from the virtual environment. Will update dependencies but skip venv deletion.")
294
+ skip_venv_delete = True
295
295
 
296
296
  # Create bootstrap.json with all configuration
297
297
  bootstrap_config = {}
@@ -330,8 +330,8 @@ class CreateVEnv(PipelineStep[ExecutionContext]):
330
330
  if self.bootstrap_config_file.exists():
331
331
  bootstrap_args.extend(["--config", self.bootstrap_config_file.as_posix()])
332
332
 
333
- if skip_venv_creation:
334
- bootstrap_args.append("--skip-venv-creation")
333
+ if skip_venv_delete:
334
+ bootstrap_args.append("--skip-venv-delete")
335
335
 
336
336
  # Copy the internal bootstrap script to the project root .bootstrap/bootstrap.py
337
337
  self.target_internal_bootstrap_script.parent.mkdir(exist_ok=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypeline-runner
3
- Version: 1.23.0
3
+ Version: 1.23.2
4
4
  Summary: Configure and execute pipelines with Python (similar to GitHub workflows or Jenkins pipelines).
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -1,7 +1,7 @@
1
- pypeline/__init__.py,sha256=ytSrJKh9KOuUfqP3DPPNXc0__n_XE-EgHA5DOGwts50,23
1
+ pypeline/__init__.py,sha256=E-2G4Hdg4R8nPq6b1QbVJLKpuG0f-4nDpEUCxDxWzzw,23
2
2
  pypeline/__run.py,sha256=TCdaX05Qm3g8T4QYryKB25Xxf0L5Km7hFOHe1mK9vI0,350
3
3
  pypeline/bootstrap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pypeline/bootstrap/run.py,sha256=tFyi5LeH8OY9EjqvJww2Ruq6XVv0t3dDpmG5sU-VfyY,32167
4
+ pypeline/bootstrap/run.py,sha256=H5rxSa_owbAUpMA2lw-UhgBFB0eDgnQC0B4jYO8j3sE,33463
5
5
  pypeline/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pypeline/domain/artifacts.py,sha256=5k7cVfHhLmvWXNuHKxXb9ca4Lxu0JytGQqazENCeKEU,1404
7
7
  pypeline/domain/config.py,sha256=6vWdHi7B6MA7NGi9wWXQE-YhSg1COSRmc3b1ji6AdAk,2053
@@ -21,12 +21,12 @@ pypeline/main.py,sha256=k1CkeFGRvQ-zLv6C-AMLC2ed1iyFzDUdvEam3HLHy2E,4210
21
21
  pypeline/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  pypeline/pypeline.py,sha256=mDKUnTuMDw8l-kSDJCHRNbn6zrxAfXhAIAqc5HyHd5M,8758
23
23
  pypeline/steps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- pypeline/steps/create_venv.py,sha256=MrA1zfwabVIjFLP47wagyR2JVUP3SSrLTQNqQdtWi-Y,16751
24
+ pypeline/steps/create_venv.py,sha256=QFVJkMuRjbJSFAdl3nbiAn0JwquYemSJKi_4J9D0h0s,16753
25
25
  pypeline/steps/env_setup_script.py,sha256=L8TwGo_Ugo2r4Z10MxtE0P8w0ApAxMKCHMnW-NkyG3w,4968
26
26
  pypeline/steps/scoop_install.py,sha256=2MhsJ0iPmL8ueQhI52sKjVY9fqzj5xOQweQ65C0onfE,4117
27
27
  pypeline/steps/west_install.py,sha256=hPyr28ksdKsQ0tv0gMNytzupgk1IgjN9CpmaBdX5zps,1947
28
- pypeline_runner-1.23.0.dist-info/METADATA,sha256=i8_6yzoi_RG4t7Hznpu5x12Rqk5-_qkmqL6wiE49xho,7659
29
- pypeline_runner-1.23.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
30
- pypeline_runner-1.23.0.dist-info/entry_points.txt,sha256=pe1u0uuhPI_yeQ0KjEw6jK-EvQfPcZwBSajgbAdKz1o,47
31
- pypeline_runner-1.23.0.dist-info/licenses/LICENSE,sha256=sKxdoqSmW9ezvPvt0ZGJbneyA0SBcm0GiqzTv2jN230,1066
32
- pypeline_runner-1.23.0.dist-info/RECORD,,
28
+ pypeline_runner-1.23.2.dist-info/METADATA,sha256=VwartKBN7HjvjHU1jrE5ptFelT6FNIfB5zP40ribdK8,7659
29
+ pypeline_runner-1.23.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
30
+ pypeline_runner-1.23.2.dist-info/entry_points.txt,sha256=pe1u0uuhPI_yeQ0KjEw6jK-EvQfPcZwBSajgbAdKz1o,47
31
+ pypeline_runner-1.23.2.dist-info/licenses/LICENSE,sha256=sKxdoqSmW9ezvPvt0ZGJbneyA0SBcm0GiqzTv2jN230,1066
32
+ pypeline_runner-1.23.2.dist-info/RECORD,,