pypeline-runner 1.15.1__tar.gz → 1.16.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.
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/PKG-INFO +1 -1
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/pyproject.toml +1 -1
- pypeline_runner-1.16.1/src/pypeline/__init__.py +1 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/bootstrap/run.py +3 -126
- pypeline_runner-1.16.1/src/pypeline/steps/create_venv.py +111 -0
- pypeline_runner-1.15.1/src/pypeline/__init__.py +0 -1
- pypeline_runner-1.15.1/src/pypeline/steps/create_venv.py +0 -62
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/LICENSE +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/README.md +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/__run.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/bootstrap/__init__.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/__init__.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/artifacts.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/config.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/execution_context.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/pipeline.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/domain/project_slurper.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/inputs_parser.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/__init__.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/create.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/.gitignore +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/pypeline.ps1 +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/pypeline.yaml +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/pyproject.toml +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/steps/my_step.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/west.yaml +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/main.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/py.typed +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/pypeline.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/steps/__init__.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/steps/env_setup_script.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/steps/scoop_install.py +0 -0
- {pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/steps/west_install.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.16.1"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import configparser
|
|
3
3
|
import ensurepip
|
|
4
|
-
import hashlib
|
|
5
4
|
import json
|
|
6
5
|
import logging
|
|
7
6
|
import os
|
|
@@ -12,7 +11,6 @@ import tempfile
|
|
|
12
11
|
import venv
|
|
13
12
|
from abc import ABC, abstractmethod
|
|
14
13
|
from dataclasses import dataclass
|
|
15
|
-
from enum import Enum
|
|
16
14
|
from functools import total_ordering
|
|
17
15
|
from pathlib import Path
|
|
18
16
|
from typing import List, Optional, Tuple
|
|
@@ -153,106 +151,6 @@ class PyPiSourceParser:
|
|
|
153
151
|
return sections
|
|
154
152
|
|
|
155
153
|
|
|
156
|
-
class Runnable(ABC):
|
|
157
|
-
@abstractmethod
|
|
158
|
-
def run(self) -> int:
|
|
159
|
-
"""Run stage."""
|
|
160
|
-
|
|
161
|
-
@abstractmethod
|
|
162
|
-
def get_name(self) -> str:
|
|
163
|
-
"""Get stage name."""
|
|
164
|
-
|
|
165
|
-
@abstractmethod
|
|
166
|
-
def get_inputs(self) -> List[Path]:
|
|
167
|
-
"""Get stage dependencies."""
|
|
168
|
-
|
|
169
|
-
@abstractmethod
|
|
170
|
-
def get_outputs(self) -> List[Path]:
|
|
171
|
-
"""Get stage outputs."""
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
class RunInfoStatus(Enum):
|
|
175
|
-
MATCH = (False, "Nothing has changed, previous execution information matches.")
|
|
176
|
-
NO_INFO = (True, "No previous execution information found.")
|
|
177
|
-
FILE_CHANGED = (True, "Dependencies have been changed.")
|
|
178
|
-
|
|
179
|
-
def __init__(self, should_run: bool, message: str) -> None:
|
|
180
|
-
self.should_run = should_run
|
|
181
|
-
self.message = message
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
class Executor:
|
|
185
|
-
"""
|
|
186
|
-
Accepts Runnable objects and executes them.
|
|
187
|
-
|
|
188
|
-
It create a file with the same name as the runnable's name
|
|
189
|
-
and stores the inputs and outputs with their hashes.
|
|
190
|
-
If the file exists, it checks the hashes of the inputs and outputs
|
|
191
|
-
and if they match, it skips the execution.
|
|
192
|
-
"""
|
|
193
|
-
|
|
194
|
-
RUN_INFO_FILE_EXTENSION = ".deps.json"
|
|
195
|
-
|
|
196
|
-
def __init__(self, cache_dir: Path) -> None:
|
|
197
|
-
self.cache_dir = cache_dir
|
|
198
|
-
|
|
199
|
-
@staticmethod
|
|
200
|
-
def get_file_hash(path: Path) -> str:
|
|
201
|
-
"""
|
|
202
|
-
Get the hash of a file.
|
|
203
|
-
|
|
204
|
-
Returns an empty string if the file does not exist.
|
|
205
|
-
"""
|
|
206
|
-
if path.is_file():
|
|
207
|
-
with open(path, "rb") as file:
|
|
208
|
-
bytes = file.read()
|
|
209
|
-
readable_hash = hashlib.sha256(bytes).hexdigest()
|
|
210
|
-
return readable_hash
|
|
211
|
-
else:
|
|
212
|
-
return ""
|
|
213
|
-
|
|
214
|
-
def store_run_info(self, runnable: Runnable) -> None:
|
|
215
|
-
file_info = {
|
|
216
|
-
"inputs": {str(path): self.get_file_hash(path) for path in runnable.get_inputs()},
|
|
217
|
-
"outputs": {str(path): self.get_file_hash(path) for path in runnable.get_outputs()},
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
run_info_path = self.get_runnable_run_info_file(runnable)
|
|
221
|
-
run_info_path.parent.mkdir(parents=True, exist_ok=True)
|
|
222
|
-
with run_info_path.open("w") as f:
|
|
223
|
-
# pretty print the json file
|
|
224
|
-
json.dump(file_info, f, indent=4)
|
|
225
|
-
|
|
226
|
-
def get_runnable_run_info_file(self, runnable: Runnable) -> Path:
|
|
227
|
-
return self.cache_dir / f"{runnable.get_name()}{self.RUN_INFO_FILE_EXTENSION}"
|
|
228
|
-
|
|
229
|
-
def previous_run_info_matches(self, runnable: Runnable) -> RunInfoStatus:
|
|
230
|
-
run_info_path = self.get_runnable_run_info_file(runnable)
|
|
231
|
-
if not run_info_path.exists():
|
|
232
|
-
return RunInfoStatus.NO_INFO
|
|
233
|
-
|
|
234
|
-
with run_info_path.open() as f:
|
|
235
|
-
previous_info = json.load(f)
|
|
236
|
-
|
|
237
|
-
for file_type in ["inputs", "outputs"]:
|
|
238
|
-
for path_str, previous_hash in previous_info[file_type].items():
|
|
239
|
-
path = Path(path_str)
|
|
240
|
-
if self.get_file_hash(path) != previous_hash:
|
|
241
|
-
return RunInfoStatus.FILE_CHANGED
|
|
242
|
-
return RunInfoStatus.MATCH
|
|
243
|
-
|
|
244
|
-
def execute(self, runnable: Runnable) -> int:
|
|
245
|
-
run_info_status = self.previous_run_info_matches(runnable)
|
|
246
|
-
if run_info_status.should_run:
|
|
247
|
-
logger.info(f"Runnable '{runnable.get_name()}' must run. {run_info_status.message}")
|
|
248
|
-
exit_code = runnable.run()
|
|
249
|
-
self.store_run_info(runnable)
|
|
250
|
-
return exit_code
|
|
251
|
-
logger.info(f"Runnable '{runnable.get_name()}' execution skipped. {run_info_status.message}")
|
|
252
|
-
|
|
253
|
-
return 0
|
|
254
|
-
|
|
255
|
-
|
|
256
154
|
class UserNotificationException(Exception):
|
|
257
155
|
pass
|
|
258
156
|
|
|
@@ -399,7 +297,7 @@ class UnixVirtualEnvironment(VirtualEnvironment):
|
|
|
399
297
|
os.remove(temp_script_path)
|
|
400
298
|
|
|
401
299
|
|
|
402
|
-
class CreateVirtualEnvironment
|
|
300
|
+
class CreateVirtualEnvironment:
|
|
403
301
|
def __init__(self, root_dir: Path, package_manager: str) -> None:
|
|
404
302
|
self.root_dir = root_dir
|
|
405
303
|
self.venv_dir = self.root_dir / ".venv"
|
|
@@ -422,9 +320,7 @@ class CreateVirtualEnvironment(Runnable):
|
|
|
422
320
|
return "install"
|
|
423
321
|
|
|
424
322
|
def run(self) -> int:
|
|
425
|
-
|
|
426
|
-
if not self.virtual_env.pip_path().exists():
|
|
427
|
-
self.virtual_env.create()
|
|
323
|
+
self.virtual_env.create()
|
|
428
324
|
|
|
429
325
|
# Get the PyPi source from pyproject.toml or Pipfile if it is defined
|
|
430
326
|
pypi_source = PyPiSourceParser.from_pyproject(self.root_dir)
|
|
@@ -454,24 +350,6 @@ class CreateVirtualEnvironment(Runnable):
|
|
|
454
350
|
else:
|
|
455
351
|
raise UserNotificationException(f"Unsupported operating system: {sys.platform}")
|
|
456
352
|
|
|
457
|
-
def get_name(self) -> str:
|
|
458
|
-
return "create-virtual-environment"
|
|
459
|
-
|
|
460
|
-
def get_inputs(self) -> List[Path]:
|
|
461
|
-
venv_relevant_files = [
|
|
462
|
-
"uv.lock",
|
|
463
|
-
"poetry.lock",
|
|
464
|
-
"poetry.toml",
|
|
465
|
-
"pyproject.toml",
|
|
466
|
-
".env",
|
|
467
|
-
"Pipfile",
|
|
468
|
-
"Pipfile.lock",
|
|
469
|
-
]
|
|
470
|
-
return [self.root_dir / file for file in venv_relevant_files] + [get_bootstrap_script()]
|
|
471
|
-
|
|
472
|
-
def get_outputs(self) -> List[Path]:
|
|
473
|
-
return []
|
|
474
|
-
|
|
475
353
|
|
|
476
354
|
def print_environment_info() -> None:
|
|
477
355
|
str_bar = "".join(["-" for _ in range(80)])
|
|
@@ -501,8 +379,7 @@ def main() -> int:
|
|
|
501
379
|
)
|
|
502
380
|
args = parser.parse_args()
|
|
503
381
|
|
|
504
|
-
|
|
505
|
-
Executor(creator.venv_dir).execute(creator)
|
|
382
|
+
CreateVirtualEnvironment(args.project_dir, package_manager=args.package_manager).run()
|
|
506
383
|
except UserNotificationException as e:
|
|
507
384
|
logger.error(e)
|
|
508
385
|
return 1
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from enum import Enum, auto
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
from mashumaro import DataClassDictMixin
|
|
8
|
+
from py_app_dev.core.exceptions import UserNotificationException
|
|
9
|
+
from py_app_dev.core.logging import logger
|
|
10
|
+
|
|
11
|
+
from pypeline import __version__
|
|
12
|
+
from pypeline.bootstrap.run import get_bootstrap_script
|
|
13
|
+
|
|
14
|
+
from ..domain.execution_context import ExecutionContext
|
|
15
|
+
from ..domain.pipeline import PipelineStep
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class CreateVEnvConfig(DataClassDictMixin):
|
|
20
|
+
bootstrap_script: Optional[str] = None
|
|
21
|
+
python_executable: Optional[str] = None
|
|
22
|
+
package_manager: Optional[str] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class BootstrapScriptType(Enum):
|
|
26
|
+
CUSTOM = auto()
|
|
27
|
+
INTERNAL = auto()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CreateVEnv(PipelineStep[ExecutionContext]):
|
|
31
|
+
DEFAULT_PACKAGE_MANAGER = "uv>=0.6"
|
|
32
|
+
DEFAULT_PYTHON_EXECUTABLE = "python311"
|
|
33
|
+
SUPPORTED_PACKAGE_MANAGERS: ClassVar[Dict[str, List[str]]] = {
|
|
34
|
+
"uv": ["uv.lock", "pyproject.toml"],
|
|
35
|
+
"pipenv": ["Pipfile", "Pipfile.lock"],
|
|
36
|
+
"poetry": ["pyproject.toml", "poetry.lock"],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def __init__(self, execution_context: ExecutionContext, group_name: str, config: Optional[Dict[str, Any]] = None) -> None:
|
|
40
|
+
self.user_config = CreateVEnvConfig.from_dict(config) if config else CreateVEnvConfig()
|
|
41
|
+
self.bootstrap_script_type = BootstrapScriptType.CUSTOM if self.user_config.bootstrap_script else BootstrapScriptType.INTERNAL
|
|
42
|
+
super().__init__(execution_context, group_name, config)
|
|
43
|
+
self.logger = logger.bind()
|
|
44
|
+
self.bootstrap_script = get_bootstrap_script()
|
|
45
|
+
self.package_manager = self.user_config.package_manager if self.user_config.package_manager else self.DEFAULT_PACKAGE_MANAGER
|
|
46
|
+
self.python_executable = self.user_config.python_executable if self.user_config.python_executable else self.DEFAULT_PYTHON_EXECUTABLE
|
|
47
|
+
self.venv_dir = self.project_root_dir / ".venv"
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def install_dirs(self) -> List[Path]:
|
|
51
|
+
return [self.project_root_dir / dir for dir in [".venv/Scripts", ".venv/bin"] if (self.project_root_dir / dir).exists()]
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def package_manager_name(self) -> str:
|
|
55
|
+
match = re.match(r"^([a-zA-Z0-9_-]+)", self.package_manager)
|
|
56
|
+
if match:
|
|
57
|
+
result = match.group(1)
|
|
58
|
+
if result in self.SUPPORTED_PACKAGE_MANAGERS:
|
|
59
|
+
return result
|
|
60
|
+
else:
|
|
61
|
+
raise UserNotificationException(f"Package manager {result} is not supported. Supported package managers are: {', '.join(self.SUPPORTED_PACKAGE_MANAGERS)}")
|
|
62
|
+
else:
|
|
63
|
+
raise UserNotificationException(f"Could not extract the package manager name from {self.package_manager}")
|
|
64
|
+
|
|
65
|
+
def get_name(self) -> str:
|
|
66
|
+
return self.__class__.__name__
|
|
67
|
+
|
|
68
|
+
def run(self) -> int:
|
|
69
|
+
self.logger.debug(f"Run {self.get_name()} step. Output dir: {self.output_dir}")
|
|
70
|
+
|
|
71
|
+
if self.user_config.bootstrap_script:
|
|
72
|
+
bootstrap_script = self.project_root_dir / self.user_config.bootstrap_script
|
|
73
|
+
if not bootstrap_script.exists():
|
|
74
|
+
raise UserNotificationException(f"Bootstrap script {bootstrap_script} does not exist.")
|
|
75
|
+
self.execution_context.create_process_executor(
|
|
76
|
+
[self.python_executable, bootstrap_script.as_posix()],
|
|
77
|
+
cwd=self.project_root_dir,
|
|
78
|
+
).execute()
|
|
79
|
+
else:
|
|
80
|
+
# The internal bootstrap script supports arguments.
|
|
81
|
+
bootstrap_args = [
|
|
82
|
+
"--project-dir",
|
|
83
|
+
self.project_root_dir.as_posix(),
|
|
84
|
+
"--package-manager",
|
|
85
|
+
f'"{self.package_manager}"',
|
|
86
|
+
]
|
|
87
|
+
self.execution_context.create_process_executor(
|
|
88
|
+
[self.python_executable, self.bootstrap_script.as_posix(), *bootstrap_args],
|
|
89
|
+
cwd=self.project_root_dir,
|
|
90
|
+
).execute()
|
|
91
|
+
return 0
|
|
92
|
+
|
|
93
|
+
def get_inputs(self) -> List[Path]:
|
|
94
|
+
package_manager_relevant_file = self.SUPPORTED_PACKAGE_MANAGERS.get(self.package_manager_name, [])
|
|
95
|
+
return [self.project_root_dir / file for file in package_manager_relevant_file]
|
|
96
|
+
|
|
97
|
+
def get_outputs(self) -> List[Path]:
|
|
98
|
+
return [self.venv_dir]
|
|
99
|
+
|
|
100
|
+
def get_config(self) -> Optional[dict[str, str]]:
|
|
101
|
+
return {
|
|
102
|
+
"version": __version__,
|
|
103
|
+
"python_executable": self.python_executable,
|
|
104
|
+
"package_manager": self.package_manager,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
def update_execution_context(self) -> None:
|
|
108
|
+
self.execution_context.add_install_dirs(self.install_dirs)
|
|
109
|
+
|
|
110
|
+
def get_needs_dependency_management(self) -> bool:
|
|
111
|
+
return False if self.bootstrap_script_type == BootstrapScriptType.CUSTOM else True
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.15.1"
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Any, Dict, List, Optional
|
|
4
|
-
|
|
5
|
-
from mashumaro import DataClassDictMixin
|
|
6
|
-
from py_app_dev.core.logging import logger
|
|
7
|
-
|
|
8
|
-
from pypeline.bootstrap.run import get_bootstrap_script
|
|
9
|
-
|
|
10
|
-
from ..domain.execution_context import ExecutionContext
|
|
11
|
-
from ..domain.pipeline import PipelineStep
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass
|
|
15
|
-
class CreateVEnvConfig(DataClassDictMixin):
|
|
16
|
-
bootstrap_script: str = "bootstrap.py"
|
|
17
|
-
python_executable: str = "python3"
|
|
18
|
-
package_manager: Optional[str] = None
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class CreateVEnv(PipelineStep[ExecutionContext]):
|
|
22
|
-
def __init__(self, execution_context: ExecutionContext, group_name: str, config: Optional[Dict[str, Any]] = None) -> None:
|
|
23
|
-
super().__init__(execution_context, group_name, config)
|
|
24
|
-
self.logger = logger.bind()
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def install_dirs(self) -> List[Path]:
|
|
28
|
-
return [self.project_root_dir / dir for dir in [".venv/Scripts", ".venv/bin"] if (self.project_root_dir / dir).exists()]
|
|
29
|
-
|
|
30
|
-
def get_name(self) -> str:
|
|
31
|
-
return self.__class__.__name__
|
|
32
|
-
|
|
33
|
-
def run(self) -> int:
|
|
34
|
-
self.logger.debug(f"Run {self.get_name()} step. Output dir: {self.output_dir}")
|
|
35
|
-
config = CreateVEnvConfig.from_dict(self.config) if self.config else CreateVEnvConfig()
|
|
36
|
-
bootstrap_script = self.project_root_dir / config.bootstrap_script
|
|
37
|
-
bootstrap_args = []
|
|
38
|
-
if not bootstrap_script.exists():
|
|
39
|
-
self.logger.warning(f"Bootstrap script {bootstrap_script} does not exist. Use pypeline internal `bootstrap.py`.")
|
|
40
|
-
bootstrap_script = get_bootstrap_script()
|
|
41
|
-
# Only the internal bootstrap.py script supports arguments.
|
|
42
|
-
bootstrap_args = ["--project-dir", self.project_root_dir.as_posix()]
|
|
43
|
-
if config.package_manager:
|
|
44
|
-
bootstrap_args.extend(["--package-manager", f'"{config.package_manager}"'])
|
|
45
|
-
self.execution_context.create_process_executor(
|
|
46
|
-
[config.python_executable, bootstrap_script.as_posix(), *bootstrap_args],
|
|
47
|
-
cwd=self.project_root_dir,
|
|
48
|
-
).execute()
|
|
49
|
-
self.execution_context.add_install_dirs(self.install_dirs)
|
|
50
|
-
return 0
|
|
51
|
-
|
|
52
|
-
def get_inputs(self) -> List[Path]:
|
|
53
|
-
return []
|
|
54
|
-
|
|
55
|
-
def get_outputs(self) -> List[Path]:
|
|
56
|
-
return []
|
|
57
|
-
|
|
58
|
-
def update_execution_context(self) -> None:
|
|
59
|
-
pass
|
|
60
|
-
|
|
61
|
-
def get_needs_dependency_management(self) -> bool:
|
|
62
|
-
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pypeline_runner-1.15.1 → pypeline_runner-1.16.1}/src/pypeline/kickstart/templates/project/west.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|