pypeline-runner 0.1.1__tar.gz → 0.2.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 (31) hide show
  1. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/PKG-INFO +22 -12
  2. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/README.md +20 -10
  3. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/pyproject.toml +2 -2
  4. pypeline_runner-0.2.1/src/pypeline/__init__.py +1 -0
  5. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/config.py +6 -3
  6. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/pipeline.py +5 -3
  7. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/create.py +5 -7
  8. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/main.py +11 -19
  9. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/pypeline.py +5 -3
  10. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/steps/create_venv.py +14 -6
  11. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/steps/scoop_install.py +4 -4
  12. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/steps/west_install.py +3 -3
  13. pypeline_runner-0.1.1/src/pypeline/__init__.py +0 -1
  14. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/LICENSE +0 -0
  15. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/__run.py +0 -0
  16. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/__init__.py +0 -0
  17. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/artifacts.py +0 -0
  18. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/execution_context.py +0 -0
  19. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/domain/project_slurper.py +0 -0
  20. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/__init__.py +0 -0
  21. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/bootstrap/bootstrap.ps1 +0 -0
  22. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/bootstrap/bootstrap.py +0 -0
  23. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/.gitignore +0 -0
  24. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/poetry.toml +0 -0
  25. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/pypeline.ps1 +0 -0
  26. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/pypeline.yaml +0 -0
  27. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/pyproject.toml +0 -0
  28. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/scoopfile.json +0 -0
  29. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/kickstart/templates/project/steps/my_step.py +0 -0
  30. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/py.typed +0 -0
  31. {pypeline_runner-0.1.1 → pypeline_runner-0.2.1}/src/pypeline/steps/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypeline-runner
3
- Version: 0.1.1
3
+ Version: 0.2.1
4
4
  Summary: Configure and execute pipelines with Python (similar to GitHub workflows or Jenkins pipelines).
5
5
  Home-page: https://github.com/cuinixam/pypeline
6
6
  License: MIT
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Topic :: Software Development :: Libraries
20
- Requires-Dist: py-app-dev (>=2.1.0,<3.0.0)
20
+ Requires-Dist: py-app-dev (>=2.1.1,<3.0.0)
21
21
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
22
22
  Requires-Dist: typer[all] (>=0.12.0,<0.13.0)
23
23
  Project-URL: Bug Tracker, https://github.com/cuinixam/pypeline/issues
@@ -26,7 +26,7 @@ Project-URL: Documentation, https://pypeline-runner.readthedocs.io
26
26
  Project-URL: Repository, https://github.com/cuinixam/pypeline
27
27
  Description-Content-Type: text/markdown
28
28
 
29
- # Python Pipeline
29
+ # Pypeline
30
30
 
31
31
  <p align="center">
32
32
  <a href="https://github.com/cuinixam/pypeline/actions/workflows/ci.yml?query=branch%3Amain">
@@ -51,14 +51,27 @@ Description-Content-Type: text/markdown
51
51
  </a>
52
52
  </p>
53
53
  <p align="center">
54
- <a href="https://pypi.org/project/pypeline/">
55
- <img src="https://img.shields.io/pypi/v/pypeline.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
54
+ <a href="https://pypi.org/project/pypeline-runner/">
55
+ <img src="https://img.shields.io/pypi/v/pypeline-runner.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
56
56
  </a>
57
- <img src="https://img.shields.io/pypi/pyversions/pypeline.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
58
- <img src="https://img.shields.io/pypi/l/pypeline.svg?style=flat-square" alt="License">
57
+ <img src="https://img.shields.io/pypi/pyversions/pypeline-runner.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
58
+ <img src="https://img.shields.io/pypi/l/pypeline-runner.svg?style=flat-square" alt="License">
59
59
  </p>
60
60
 
61
- Configure and execute pipelines with Python (similar to GitHub workflows or Jenkins pipelines).
61
+ Pypeline is a Python application designed to streamline and automate the software development lifecycle, particularly the pipeline execution processes across various environments such as GitHub and Jenkins.
62
+ The primary motivation for developing Pypeline stemmed from the need to unify and simplify the creation of build, test, and deployment pipelines that are traditionally defined separately across these platforms using GitHub workflows (YAML) and Jenkins pipelines (Jenkinsfile).
63
+
64
+ **Key Features**
65
+
66
+ - **Unified Pipeline Definition**: Users can define their entire pipeline in a single YAML file, eliminating the need to switch between different syntaxes and configurations for different CI/CD tools.
67
+
68
+ - **Extensibility**: Pypeline supports execution steps defined not only through local scripts but also from installed Python packages.
69
+
70
+ - **Execution Context**: Each step in the pipeline receives an execution context that can be updated during step execution. This allows for the sharing of information and state between steps.
71
+
72
+ - **Dependency Handling**: Dependency management ensures that only the necessary steps are executed, reducing runtime and resource usage by avoiding unnecessary operations.
73
+
74
+ - **Ease of Use**: With Pypeline, setting up and running pipelines becomes more straightforward, enabling developers to focus more on coding and less on configuring pipeline specifics.
62
75
 
63
76
  ## Installation
64
77
 
@@ -114,8 +127,5 @@ This project follows the [all-contributors](https://github.com/all-contributors/
114
127
 
115
128
  ## Credits
116
129
 
117
- This package was created with
118
- [Copier](https://copier.readthedocs.io/) and the
119
- [cuinixam/pypackage-template](https://github.com/cuinixam/pypackage-template)
120
- project template.
130
+ This package was created with [Copier](https://copier.readthedocs.io/) and the [cuinixam/pypackage-template](https://github.com/cuinixam/pypackage-template) project template.
121
131
 
@@ -1,4 +1,4 @@
1
- # Python Pipeline
1
+ # Pypeline
2
2
 
3
3
  <p align="center">
4
4
  <a href="https://github.com/cuinixam/pypeline/actions/workflows/ci.yml?query=branch%3Amain">
@@ -23,14 +23,27 @@
23
23
  </a>
24
24
  </p>
25
25
  <p align="center">
26
- <a href="https://pypi.org/project/pypeline/">
27
- <img src="https://img.shields.io/pypi/v/pypeline.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
26
+ <a href="https://pypi.org/project/pypeline-runner/">
27
+ <img src="https://img.shields.io/pypi/v/pypeline-runner.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
28
28
  </a>
29
- <img src="https://img.shields.io/pypi/pyversions/pypeline.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
30
- <img src="https://img.shields.io/pypi/l/pypeline.svg?style=flat-square" alt="License">
29
+ <img src="https://img.shields.io/pypi/pyversions/pypeline-runner.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
30
+ <img src="https://img.shields.io/pypi/l/pypeline-runner.svg?style=flat-square" alt="License">
31
31
  </p>
32
32
 
33
- Configure and execute pipelines with Python (similar to GitHub workflows or Jenkins pipelines).
33
+ Pypeline is a Python application designed to streamline and automate the software development lifecycle, particularly the pipeline execution processes across various environments such as GitHub and Jenkins.
34
+ The primary motivation for developing Pypeline stemmed from the need to unify and simplify the creation of build, test, and deployment pipelines that are traditionally defined separately across these platforms using GitHub workflows (YAML) and Jenkins pipelines (Jenkinsfile).
35
+
36
+ **Key Features**
37
+
38
+ - **Unified Pipeline Definition**: Users can define their entire pipeline in a single YAML file, eliminating the need to switch between different syntaxes and configurations for different CI/CD tools.
39
+
40
+ - **Extensibility**: Pypeline supports execution steps defined not only through local scripts but also from installed Python packages.
41
+
42
+ - **Execution Context**: Each step in the pipeline receives an execution context that can be updated during step execution. This allows for the sharing of information and state between steps.
43
+
44
+ - **Dependency Handling**: Dependency management ensures that only the necessary steps are executed, reducing runtime and resource usage by avoiding unnecessary operations.
45
+
46
+ - **Ease of Use**: With Pypeline, setting up and running pipelines becomes more straightforward, enabling developers to focus more on coding and less on configuring pipeline specifics.
34
47
 
35
48
  ## Installation
36
49
 
@@ -86,7 +99,4 @@ This project follows the [all-contributors](https://github.com/all-contributors/
86
99
 
87
100
  ## Credits
88
101
 
89
- This package was created with
90
- [Copier](https://copier.readthedocs.io/) and the
91
- [cuinixam/pypackage-template](https://github.com/cuinixam/pypackage-template)
92
- project template.
102
+ This package was created with [Copier](https://copier.readthedocs.io/) and the [cuinixam/pypackage-template](https://github.com/cuinixam/pypackage-template) project template.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pypeline-runner"
3
- version = "0.1.1"
3
+ version = "0.2.1"
4
4
  description = "Configure and execute pipelines with Python (similar to GitHub workflows or Jenkins pipelines)."
5
5
  authors = ["cuinixam <me@cuinixam.com>"]
6
6
  license = "MIT"
@@ -27,7 +27,7 @@ pypeline = "pypeline.main:main"
27
27
 
28
28
  [tool.poetry.dependencies]
29
29
  python = "^3.10"
30
- py-app-dev = "^2.1.0"
30
+ py-app-dev = "^2.1.1"
31
31
  typer = {extras = ["all"], version = "^0.12.0"}
32
32
  pyyaml = "^6.0.1"
33
33
 
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"
@@ -20,7 +20,10 @@ class ProjectConfig(DataClassDictMixin):
20
20
  @classmethod
21
21
  def from_file(cls, config_file: Path) -> "ProjectConfig":
22
22
  config_dict = cls.parse_to_dict(config_file)
23
- return cls.from_dict(config_dict)
23
+ try:
24
+ return cls.from_dict(config_dict)
25
+ except Exception as e:
26
+ raise UserNotificationException(f"Invalid configuration file '{config_file}'. \nError: {e}") from None
24
27
 
25
28
  @staticmethod
26
29
  def parse_to_dict(config_file: Path) -> Dict[str, Any]:
@@ -31,6 +34,6 @@ class ProjectConfig(DataClassDictMixin):
31
34
  config_dict["file"] = config_file
32
35
  return config_dict
33
36
  except ScannerError as e:
34
- raise UserNotificationException(f"Failed scanning configuration file '{config_file}'. \nError: {e}") from e
37
+ raise UserNotificationException(f"Failed scanning configuration file '{config_file}'. \nError: {e}") from None
35
38
  except ParserError as e:
36
- raise UserNotificationException(f"Failed parsing configuration file '{config_file}'. \nError: {e}") from e
39
+ raise UserNotificationException(f"Failed parsing configuration file '{config_file}'. \nError: {e}") from None
@@ -1,6 +1,6 @@
1
1
  from abc import abstractmethod
2
2
  from pathlib import Path
3
- from typing import Type
3
+ from typing import Any, Dict, Optional, Type
4
4
 
5
5
  from py_app_dev.core.runnable import Runnable
6
6
 
@@ -8,9 +8,10 @@ from .execution_context import ExecutionContext
8
8
 
9
9
 
10
10
  class PipelineStep(Runnable):
11
- def __init__(self, execution_context: ExecutionContext, output_dir: Path) -> None:
11
+ def __init__(self, execution_context: ExecutionContext, output_dir: Path, config: Optional[Dict[str, Any]] = None) -> None:
12
12
  self.execution_context = execution_context
13
13
  self.output_dir = output_dir
14
+ self.config = config
14
15
  self.project_root_dir = self.execution_context.project_root_dir
15
16
 
16
17
  @abstractmethod
@@ -19,9 +20,10 @@ class PipelineStep(Runnable):
19
20
 
20
21
 
21
22
  class PipelineStepReference:
22
- def __init__(self, group_name: str, _class: Type[PipelineStep]) -> None:
23
+ def __init__(self, group_name: str, _class: Type[PipelineStep], config: Optional[Dict[str, Any]] = None) -> None:
23
24
  self.group_name = group_name
24
25
  self._class = _class
26
+ self.config = config
25
27
 
26
28
  @property
27
29
  def name(self) -> str:
@@ -31,7 +31,7 @@ class ProjectBuilder:
31
31
  @staticmethod
32
32
  def _check_target_directory(project_dir: Path) -> None:
33
33
  if project_dir.is_dir() and any(project_dir.iterdir()):
34
- raise UserNotificationException(f"Project directory '{project_dir}' is not empty." " The target directory shall either be empty or not exist.")
34
+ raise UserNotificationException(f"Project directory '{project_dir}' is not empty. Use --force to override.")
35
35
 
36
36
  def build(self) -> None:
37
37
  if self.check_target_directory_flag:
@@ -41,18 +41,16 @@ class ProjectBuilder:
41
41
 
42
42
 
43
43
  class KickstartProject:
44
- def __init__(self, project_dir: Path, bootstrap_only: bool = False, force: bool = False) -> None:
44
+ def __init__(self, project_dir: Path, force: bool = False) -> None:
45
45
  self.logger = logger.bind()
46
46
  self.project_dir = project_dir
47
- self.bootstrap_only = bootstrap_only
48
47
  self.force = force
49
48
 
50
49
  def run(self) -> None:
51
50
  self.logger.info(f"Kickstart new project in '{self.project_dir.absolute().as_posix()}'")
52
51
  project_builder = ProjectBuilder(self.project_dir)
53
- project_builder.with_dir("bootstrap")
54
- if self.bootstrap_only or self.force:
52
+ if self.force:
55
53
  project_builder.with_disable_target_directory_check()
56
- if not self.bootstrap_only:
57
- project_builder.with_dir("project")
54
+ project_builder.with_dir("bootstrap")
55
+ project_builder.with_dir("project")
58
56
  project_builder.build()
@@ -1,6 +1,6 @@
1
1
  import sys
2
2
  from pathlib import Path
3
- from typing import List, Optional
3
+ from typing import Optional
4
4
 
5
5
  import typer
6
6
  from py_app_dev.core.exceptions import UserNotificationException
@@ -31,10 +31,9 @@ def version(
31
31
  @time_it("init")
32
32
  def init(
33
33
  project_dir: Path = typer.Option(Path.cwd().absolute(), help="The project directory"), # noqa: B008
34
- bootstrap_only: bool = typer.Option(False, help="Initialize only the bootstrap files."),
35
34
  force: bool = typer.Option(False, help="Force the initialization of the project even if the directory is not empty."),
36
35
  ) -> None:
37
- KickstartProject(project_dir, bootstrap_only, force).run()
36
+ KickstartProject(project_dir, force).run()
38
37
 
39
38
 
40
39
  @app.command()
@@ -60,10 +59,14 @@ def run(
60
59
  help="Force the execution of a step even if it is not dirty.",
61
60
  is_flag=True,
62
61
  ),
62
+ dry_run: bool = typer.Option(
63
+ False,
64
+ help="Do not run any step, just print the steps that would be executed.",
65
+ is_flag=True,
66
+ ),
63
67
  ) -> None:
64
68
  project_slurper = ProjectSlurper(project_dir)
65
69
  if print:
66
- logger.warning("TODO: print pipeline steps")
67
70
  logger.info("Pipeline steps:")
68
71
  for group, step_configs in project_slurper.pipeline.items():
69
72
  logger.info(f" Group: {group}")
@@ -80,24 +83,13 @@ def run(
80
83
  logger.info("No steps to run.")
81
84
  return
82
85
 
83
- PipelineStepsExecutor(
84
- project_slurper.artifacts_locator,
85
- steps_references,
86
- force_run,
87
- ).run()
86
+ PipelineStepsExecutor(project_slurper.artifacts_locator, steps_references, force_run, dry_run).run()
88
87
 
89
88
 
90
- def main(args: Optional[List[str]] = None) -> int:
89
+ if __name__ == "__main__":
91
90
  try:
92
91
  setup_logger()
93
- if args is None:
94
- args = sys.argv[1:]
95
- app(args)
96
- return 0
92
+ app()
97
93
  except UserNotificationException as e:
98
94
  logger.error(f"{e}")
99
- return 1
100
-
101
-
102
- if __name__ == "__main__":
103
- sys.exit(main())
95
+ sys.exit(1)
@@ -26,7 +26,7 @@ class PipelineLoader:
26
26
  self._loader = GenericPipelineLoader[PipelineStep](self.pipeline_config, self.project_root_dir)
27
27
 
28
28
  def load_steps_references(self) -> List[PipelineStepReference]:
29
- return [PipelineStepReference(step_reference.group_name, step_reference._class) for step_reference in self._loader.load_steps()]
29
+ return [PipelineStepReference(step_reference.group_name, step_reference._class, step_reference.config) for step_reference in self._loader.load_steps()]
30
30
 
31
31
 
32
32
  class PipelineStepsExecutor:
@@ -37,11 +37,13 @@ class PipelineStepsExecutor:
37
37
  artifacts_locator: ProjectArtifactsLocator,
38
38
  steps_references: List[PipelineStepReference],
39
39
  force_run: bool = False,
40
+ dry_run: bool = False,
40
41
  ) -> None:
41
42
  self.logger = logger.bind()
42
43
  self.artifacts_locator = artifacts_locator
43
44
  self.steps_references = steps_references
44
45
  self.force_run = force_run
46
+ self.dry_run = dry_run
45
47
 
46
48
  def run(self) -> None:
47
49
  execution_context = ExecutionContext(project_root_dir=self.artifacts_locator.project_root_dir, install_dirs=[])
@@ -49,9 +51,9 @@ class PipelineStepsExecutor:
49
51
  step_output_dir = self.artifacts_locator.build_dir / step_reference.group_name
50
52
  # Create the step output directory, to make sure that files can be created.
51
53
  step_output_dir.mkdir(parents=True, exist_ok=True)
52
- step = step_reference._class(execution_context, step_output_dir)
54
+ step = step_reference._class(execution_context, step_output_dir, step_reference.config)
53
55
  # Execute the step is necessary. If the step is not dirty, it will not be executed
54
- Executor(step.output_dir, self.force_run).execute(step)
56
+ Executor(step.output_dir, self.force_run, self.dry_run).execute(step)
55
57
  # Independent if the step was executed or not, every step shall update the context
56
58
  step.update_execution_context()
57
59
 
@@ -1,6 +1,8 @@
1
+ from dataclasses import dataclass
1
2
  from pathlib import Path
2
- from typing import List
3
+ from typing import Any, Dict, List, Optional
3
4
 
5
+ from mashumaro import DataClassDictMixin
4
6
  from py_app_dev.core.exceptions import UserNotificationException
5
7
  from py_app_dev.core.logging import logger
6
8
 
@@ -8,9 +10,14 @@ from ..domain.execution_context import ExecutionContext
8
10
  from ..domain.pipeline import PipelineStep
9
11
 
10
12
 
13
+ @dataclass
14
+ class CreateVEnvConfig(DataClassDictMixin):
15
+ bootstrap_script: str = "bootstrap.py"
16
+
17
+
11
18
  class CreateVEnv(PipelineStep):
12
- def __init__(self, execution_context: ExecutionContext, output_dir: Path) -> None:
13
- super().__init__(execution_context, output_dir)
19
+ def __init__(self, execution_context: ExecutionContext, output_dir: Path, config: Optional[Dict[str, Any]] = None) -> None:
20
+ super().__init__(execution_context, output_dir, config)
14
21
  self.logger = logger.bind()
15
22
  self.logger = logger.bind()
16
23
 
@@ -23,11 +30,12 @@ class CreateVEnv(PipelineStep):
23
30
 
24
31
  def run(self) -> int:
25
32
  self.logger.debug(f"Run {self.get_name()} step. Output dir: {self.output_dir}")
26
- build_script_path = self.project_root_dir / "bootstrap.py"
27
- if not build_script_path.exists():
33
+ config = CreateVEnvConfig.from_dict(self.config) if self.config else CreateVEnvConfig()
34
+ bootstrap_script = self.project_root_dir / config.bootstrap_script
35
+ if not bootstrap_script.exists():
28
36
  raise UserNotificationException("Failed to find bootstrap script. Make sure that the project is initialized correctly.")
29
37
  self.execution_context.create_process_executor(
30
- ["python", build_script_path.as_posix()],
38
+ ["python", bootstrap_script.as_posix()],
31
39
  cwd=self.project_root_dir,
32
40
  ).execute()
33
41
  self.execution_context.add_install_dirs(self.install_dirs)
@@ -3,7 +3,7 @@ import json
3
3
  import traceback
4
4
  from dataclasses import dataclass
5
5
  from pathlib import Path
6
- from typing import ClassVar, List
6
+ from typing import Any, ClassVar, Dict, List, Optional
7
7
 
8
8
  from mashumaro.config import TO_DICT_ADD_OMIT_NONE_FLAG, BaseConfig
9
9
  from mashumaro.mixins.json import DataClassJSONMixin
@@ -46,8 +46,8 @@ def create_scoop_wrapper() -> ScoopWrapper:
46
46
 
47
47
 
48
48
  class ScoopInstall(PipelineStep):
49
- def __init__(self, execution_context: ExecutionContext, output_dir: Path) -> None:
50
- super().__init__(execution_context, output_dir)
49
+ def __init__(self, execution_context: ExecutionContext, output_dir: Path, config: Optional[Dict[str, Any]] = None) -> None:
50
+ super().__init__(execution_context, output_dir, config)
51
51
  self.logger = logger.bind()
52
52
  self.execution_info = ScoopInstallExecutionInfo([])
53
53
  # One needs to keep track of the installed apps to get the required paths
@@ -77,7 +77,7 @@ class ScoopInstall(PipelineStep):
77
77
  return [self.scoop_file]
78
78
 
79
79
  def get_outputs(self) -> List[Path]:
80
- return self.install_dirs
80
+ return [self.execution_info_file, *self.install_dirs]
81
81
 
82
82
  def update_execution_context(self) -> None:
83
83
  install_dirs = ScoopInstallExecutionInfo.from_json_file(self.execution_info_file).install_dirs
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import List
2
+ from typing import Any, Dict, List, Optional
3
3
 
4
4
  from py_app_dev.core.exceptions import UserNotificationException
5
5
  from py_app_dev.core.logging import logger
@@ -9,8 +9,8 @@ from ..domain.pipeline import PipelineStep
9
9
 
10
10
 
11
11
  class WestInstall(PipelineStep):
12
- def __init__(self, execution_context: ExecutionContext, output_dir: Path) -> None:
13
- super().__init__(execution_context, output_dir)
12
+ def __init__(self, execution_context: ExecutionContext, output_dir: Path, config: Optional[Dict[str, Any]] = None) -> None:
13
+ super().__init__(execution_context, output_dir, config)
14
14
  self.logger = logger.bind()
15
15
  self.artifacts_locator = execution_context.create_artifacts_locator()
16
16
 
@@ -1 +0,0 @@
1
- __version__ = "0.1.1"
File without changes