ansys-saf-cli 4.1.dev0__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.
- ansys/saf/cli/__init__.py +15 -0
- ansys/saf/cli/_cli/__init__.py +15 -0
- ansys/saf/cli/_cli/main.py +816 -0
- ansys/saf/cli/_cli/py.typed +0 -0
- ansys/saf/cli/_config/__init__.py +15 -0
- ansys/saf/cli/_config/const.py +45 -0
- ansys/saf/cli/_config/py.typed +0 -0
- ansys/saf/cli/_database/__init__.py +15 -0
- ansys/saf/cli/_database/manager.py +94 -0
- ansys/saf/cli/_database/models.py +53 -0
- ansys/saf/cli/_database/py.typed +0 -0
- ansys/saf/cli/_solutions/__init__.py +15 -0
- ansys/saf/cli/_solutions/add_step.py +256 -0
- ansys/saf/cli/_solutions/dependencies.py +162 -0
- ansys/saf/cli/_solutions/environment.py +1145 -0
- ansys/saf/cli/_solutions/plugins.py +254 -0
- ansys/saf/cli/_solutions/py.typed +0 -0
- ansys/saf/cli/_solutions/scaffolding.py +73 -0
- ansys/saf/cli/_solutions/templates/__init__.py +15 -0
- ansys/saf/cli/_solutions/templates/py.typed +0 -0
- ansys/saf/cli/_solutions/templates/solution/cookiecutter.json +18 -0
- ansys/saf/cli/_solutions/templates/solution/hooks/post_gen_project.py +54 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.codespell.ignore +2 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.devcontainer/devcontainer.json +26 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.env +5 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.flake8 +8 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/labeler.yml +9 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/labels.yml +27 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/workflows/build-release.yml +175 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/workflows/label.yml +89 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.gitignore +137 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.pre-commit-config.yaml +48 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.release-please-manifest.json +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.reuse/templates/copyright.jinja2 +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.vscode/extensions.json +8 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.vscode/launch.json +28 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/AUTHORS +12 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/CHANGELOG.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/CODEOWNERS +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/CODE_OF_CONDUCT.md +65 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/CONTRIBUTING.md +2 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/CONTRIBUTORS.md +9 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/LICENSE.rst +41 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/README.md +69 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/Dockerfile +43 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/README.md +13 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/distributed-deployment-template/.env +27 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/distributed-deployment-template/compose.yaml +132 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone/.env +20 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone/compose.yaml +118 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone-with-hps/.env +28 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone-with-hps/compose.yaml +146 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone-with-minerva/.env +25 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/deployments/standalone-with-minerva/compose.yaml +122 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/.vale.ini +28 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/Makefile +30 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/changelog.d/changelog_template.jinja +17 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/make.bat +46 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/_static/css/custom.css +8 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/_static/images/repository-banner.png +0 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/_templates/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/changelog.rst +12 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/conf.py +253 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/examples.rst +8 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/getting_started/desktop_installation.rst +165 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/getting_started/docker_installation.rst +68 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/index.rst +51 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/source/user_guide/index.rst +6 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/styles/config/vocabularies/ANSYS/accept.txt +5 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/doc/styles/config/vocabularies/ANSYS/reject.txt +0 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/examples/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/lock_files/dash/poetry.lock +7621 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/lock_files/no_ui/poetry.lock +7173 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/minerva/cli/README.md +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/minerva/oauth/App_Data/Certificates/README.md +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/minerva/oauth/oauth.config +9 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/pyproject.toml +192 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/release-please-config.json +9 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/sonar-project.properties +12 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/__init__.py +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/main.py +19 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/portal_assets/application.svg +36 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/portal_assets/description.json +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/portal_assets/project.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/definition.py +24 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/first_step.py +34 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/method_assets/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/scripts/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/scripts/assets/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/solution/second_step.py +12 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/app.py +30 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/css/all.css +9 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/css/bootstrap.min.css +6 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/css/style.css +47 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/carbon--ibm-engineering-workflow-mgmt.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/carbon--return.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/game-icons--crossed-air-flows.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/material-symbols--home.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/radix-icons--moon.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/radix-icons--sun.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/streamline--startup-solid.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/dark/teenyicons--doc-solid.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/carbon--ibm-engineering-workflow-mgmt.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/carbon--return.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/game-icons--crossed-air-flows.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/material-symbols--home.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/radix-icons--moon.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/radix-icons--sun.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/streamline--startup-solid.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/icons/light/teenyicons--doc-solid.svg +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/images/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/images/workflow-placeholder.png +0 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/installer/README.md +5 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/logos/dark/placeholder_logo.png +0 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/logos/light/placeholder_logo.png +0 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/orchestrator/README.md +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/pywebview/README.md +3 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/assets/scripts/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/components/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/pages/about_page.py +71 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/pages/first_page.py +147 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/pages/page.py +367 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/src/{{ cookiecutter.__solution_namespace_path }}/{{cookiecutter.__solution_module_name}}/ui/pages/second_page.py +32 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/tests/common_test_files/README.md +1 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/tests/conftest.py +37 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/tests/unit/test_solution_api.py +42 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/tests/unit/test_solution_ui.py +30 -0
- ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/tox.ini +56 -0
- ansys/saf/cli/_utilities/__init__.py +15 -0
- ansys/saf/cli/_utilities/archiver.py +67 -0
- ansys/saf/cli/_utilities/backup.py +181 -0
- ansys/saf/cli/_utilities/conversion.py +64 -0
- ansys/saf/cli/_utilities/platform.py +26 -0
- ansys/saf/cli/_utilities/py.typed +0 -0
- ansys/saf/cli/_utilities/solution_modules.py +173 -0
- ansys/saf/cli/integrations/solutions_manager.py +64 -0
- ansys/saf/cli/py.typed +0 -0
- ansys_saf_cli-4.1.dev0.dist-info/METADATA +201 -0
- ansys_saf_cli-4.1.dev0.dist-info/RECORD +143 -0
- ansys_saf_cli-4.1.dev0.dist-info/WHEEL +4 -0
- ansys_saf_cli-4.1.dev0.dist-info/entry_points.txt +3 -0
- ansys_saf_cli-4.1.dev0.dist-info/licenses/AUTHORS +12 -0
- ansys_saf_cli-4.1.dev0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Copyright (C) 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from collections.abc import Generator
|
|
18
|
+
from importlib.metadata import entry_points
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
import sys
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
import click
|
|
24
|
+
from packaging.specifiers import SpecifierSet
|
|
25
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator, model_validator
|
|
26
|
+
import tomlkit
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SafTemplateValidationError:
|
|
30
|
+
def __init__(self, template_name: str, error: ValidationError):
|
|
31
|
+
self.template_name = template_name
|
|
32
|
+
self.error = error
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class SafTemplate(BaseModel):
|
|
36
|
+
name: str = Field(min_length=1)
|
|
37
|
+
type: str = Field(min_length=1)
|
|
38
|
+
description: str = Field(min_length=1)
|
|
39
|
+
location: Path
|
|
40
|
+
dependencies: dict[str, Any] = Field(default_factory=dict)
|
|
41
|
+
saf_cli_compatibility_range: SpecifierSet | None = None
|
|
42
|
+
|
|
43
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
44
|
+
|
|
45
|
+
@field_validator("location")
|
|
46
|
+
@classmethod
|
|
47
|
+
def validate_location(cls, v: Path) -> Path:
|
|
48
|
+
if not v.is_dir():
|
|
49
|
+
raise ValueError(f"Location path '{v}' is not a valid directory")
|
|
50
|
+
return v
|
|
51
|
+
|
|
52
|
+
@field_validator("saf_cli_compatibility_range", mode="before")
|
|
53
|
+
@classmethod
|
|
54
|
+
def validate_saf_cli_compatibility_range(cls, value: Any) -> SpecifierSet | None:
|
|
55
|
+
if value is None:
|
|
56
|
+
return None
|
|
57
|
+
try:
|
|
58
|
+
spec_str: str = str(value).strip()
|
|
59
|
+
return SpecifierSet(spec_str)
|
|
60
|
+
except Exception as e:
|
|
61
|
+
raise ValueError(
|
|
62
|
+
f"Invalid saf-cli version compatibility range: '{value}'. "
|
|
63
|
+
f"Make sure you define a range of versions using standard packaging specifier format, "
|
|
64
|
+
f"e.g. '>=0.1.0,<1.0.0' or '==0.2.5'.",
|
|
65
|
+
) from e
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class SafPluginValidationError:
|
|
69
|
+
def __init__(self, module_name: str, error: ValidationError):
|
|
70
|
+
self.module_name = module_name
|
|
71
|
+
self.error = error
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class SafPlugin(BaseModel):
|
|
75
|
+
path: Path
|
|
76
|
+
module_name: str = Field(min_length=1)
|
|
77
|
+
templates_config: dict[str, Any] = Field(default_factory=dict)
|
|
78
|
+
|
|
79
|
+
@model_validator(mode="after")
|
|
80
|
+
def load_templates_config(self) -> "SafPlugin":
|
|
81
|
+
config_path = self.path / "templates.toml"
|
|
82
|
+
if not config_path.is_file():
|
|
83
|
+
raise ValueError(
|
|
84
|
+
f"Config file 'templates.toml' not found for plugin module '{self.module_name}' "
|
|
85
|
+
f"at expected location {config_path}",
|
|
86
|
+
)
|
|
87
|
+
try:
|
|
88
|
+
templates_config = tomlkit.loads(config_path.read_bytes()).unwrap()
|
|
89
|
+
except Exception as e:
|
|
90
|
+
raise ValueError(
|
|
91
|
+
f"Error loading config file 'templates.toml' for plugin module '{self.module_name}' "
|
|
92
|
+
f"at location {config_path}: {e}",
|
|
93
|
+
) from e
|
|
94
|
+
if not templates_config.get("templates"):
|
|
95
|
+
raise ValueError(
|
|
96
|
+
f"No templates in templates configuration file for plugin module '{self.module_name}'",
|
|
97
|
+
)
|
|
98
|
+
self.templates_config = templates_config
|
|
99
|
+
return self
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ClickRenderer:
|
|
103
|
+
def __init__(self, verbose: bool = False, steps_only: bool = False, solutions_only: bool = False):
|
|
104
|
+
self._verbose = verbose
|
|
105
|
+
self._steps_only = steps_only
|
|
106
|
+
self._solutions_only = solutions_only
|
|
107
|
+
|
|
108
|
+
def _render_plugin_information(self, module_name: str) -> None:
|
|
109
|
+
click_str = (
|
|
110
|
+
"Step templates" if self._steps_only else "Solution templates" if self._solutions_only else "Templates"
|
|
111
|
+
)
|
|
112
|
+
click.secho(f"{click_str} in ", fg="cyan", nl=False)
|
|
113
|
+
click.secho(f"{module_name}", fg="cyan", bold=True)
|
|
114
|
+
|
|
115
|
+
def _render_template_information(self, saf_template: SafTemplate) -> None:
|
|
116
|
+
click.secho(f" {saf_template.name} ({saf_template.type}): ", fg="green", nl=False)
|
|
117
|
+
click.secho(f"{saf_template.description}")
|
|
118
|
+
if self._verbose:
|
|
119
|
+
click.secho(f" location: {saf_template.location}")
|
|
120
|
+
if saf_template.dependencies:
|
|
121
|
+
for group_name in saf_template.dependencies:
|
|
122
|
+
click.secho(f" {group_name} dependencies:")
|
|
123
|
+
for dependency_name, dependency_specification in saf_template.dependencies[group_name].items():
|
|
124
|
+
click.secho(f" - {dependency_name}: {dependency_specification}")
|
|
125
|
+
click.echo()
|
|
126
|
+
|
|
127
|
+
def render_plugin_and_template_information(self, plugin_templates: dict[str, list[SafTemplate]]) -> None:
|
|
128
|
+
for module_name, templates in plugin_templates.items():
|
|
129
|
+
self._render_plugin_information(module_name)
|
|
130
|
+
for template in templates:
|
|
131
|
+
if self._steps_only and template.type != "step" or self._solutions_only and template.type != "solution":
|
|
132
|
+
continue
|
|
133
|
+
self._render_template_information(template)
|
|
134
|
+
|
|
135
|
+
def render_plugin_errors(self, plugin_errors: list[SafPluginValidationError]) -> None:
|
|
136
|
+
if self._verbose and plugin_errors:
|
|
137
|
+
for error in plugin_errors:
|
|
138
|
+
click.secho(f"Error in plugin module '{error.module_name}':", err=True, fg="red")
|
|
139
|
+
click.secho(f"{error.error}", err=True, fg="red")
|
|
140
|
+
click.echo()
|
|
141
|
+
elif plugin_errors:
|
|
142
|
+
click.secho(
|
|
143
|
+
f"Warning: {len(plugin_errors)} template plugin(s) could not be loaded. "
|
|
144
|
+
f"Use --verbose flag for more details.",
|
|
145
|
+
err=True,
|
|
146
|
+
fg="yellow",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
def render_template_errors(self, template_errors: list[SafTemplateValidationError]) -> None:
|
|
150
|
+
if self._verbose and template_errors:
|
|
151
|
+
for error in template_errors:
|
|
152
|
+
click.secho(f"Error in template '{error.template_name}':", err=True, fg="red")
|
|
153
|
+
click.secho(f"{error.error}", err=True, fg="red")
|
|
154
|
+
click.echo()
|
|
155
|
+
elif template_errors:
|
|
156
|
+
click.secho(
|
|
157
|
+
f"Warning: {len(template_errors)} template(s) could not be loaded. "
|
|
158
|
+
f"Use --verbose flag for more details.",
|
|
159
|
+
err=True,
|
|
160
|
+
fg="yellow",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _iterate_plugins() -> Generator[SafPlugin | SafPluginValidationError, None, None]:
|
|
165
|
+
plugins = entry_points(group="ansys_saf_templates")
|
|
166
|
+
if not plugins:
|
|
167
|
+
click.secho("No template plugins found.", fg="yellow")
|
|
168
|
+
sys.exit(1)
|
|
169
|
+
for plugin in sorted(plugins, key=lambda p: p.value.split(":")[0]):
|
|
170
|
+
module_name = plugin.value.split(":")[0]
|
|
171
|
+
try:
|
|
172
|
+
yield SafPlugin.model_validate(
|
|
173
|
+
{
|
|
174
|
+
"path": plugin.load()(),
|
|
175
|
+
"module_name": module_name,
|
|
176
|
+
},
|
|
177
|
+
)
|
|
178
|
+
except ValidationError as e:
|
|
179
|
+
yield SafPluginValidationError(module_name, e)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _find_template_in_plugin(template_name: str, plugin: SafPlugin) -> SafTemplate | None:
|
|
183
|
+
if template_name not in plugin.templates_config["templates"]:
|
|
184
|
+
return None
|
|
185
|
+
template = plugin.templates_config["templates"][template_name]
|
|
186
|
+
try:
|
|
187
|
+
return SafTemplate.model_validate(
|
|
188
|
+
{
|
|
189
|
+
"name": template_name,
|
|
190
|
+
"type": template["type"],
|
|
191
|
+
"description": template["description"],
|
|
192
|
+
"location": plugin.path / template["location"],
|
|
193
|
+
"dependencies": template.get("dependencies", {}),
|
|
194
|
+
"saf_cli_compatibility_range": template.get("saf_cli_compatibility_range"),
|
|
195
|
+
},
|
|
196
|
+
)
|
|
197
|
+
except Exception as e:
|
|
198
|
+
raise ValueError(f"Template '{template_name}' in plugin module '{plugin.module_name}' is invalid.") from e
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def resolve_template(template_name: str) -> SafTemplate:
|
|
202
|
+
plugin_errors: list[SafPluginValidationError] = []
|
|
203
|
+
for plugin in _iterate_plugins():
|
|
204
|
+
if isinstance(plugin, SafPluginValidationError):
|
|
205
|
+
plugin_errors.append(plugin)
|
|
206
|
+
continue
|
|
207
|
+
if not (saf_template := _find_template_in_plugin(template_name, plugin)):
|
|
208
|
+
continue
|
|
209
|
+
return saf_template
|
|
210
|
+
|
|
211
|
+
raise ValueError(
|
|
212
|
+
f"Could not find a valid template for template name '{template_name}'.\n"
|
|
213
|
+
f" - Run `saf templates` to list the available templates.\n"
|
|
214
|
+
f" - Run `saf templates --verbose` to include more details on plugin and template errors.",
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _scan_plugin_templates(plugin: SafPlugin) -> Generator[SafTemplate | SafTemplateValidationError, None, None]:
|
|
219
|
+
for template_name, template in plugin.templates_config["templates"].items():
|
|
220
|
+
try:
|
|
221
|
+
yield SafTemplate.model_validate(
|
|
222
|
+
{
|
|
223
|
+
"name": template_name,
|
|
224
|
+
"type": template.get("type", ""),
|
|
225
|
+
"description": template.get("description"),
|
|
226
|
+
"location": plugin.path / template.get("location", ""),
|
|
227
|
+
"dependencies": template.get("dependencies", {}),
|
|
228
|
+
"saf_cli_compatibility_range": template.get("saf_cli_compatibility_range"),
|
|
229
|
+
},
|
|
230
|
+
)
|
|
231
|
+
except ValidationError as e:
|
|
232
|
+
yield SafTemplateValidationError(template_name, e)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def list_available_templates(steps_only: bool = False, solutions_only: bool = False, verbose: bool = False) -> None:
|
|
236
|
+
renderer = ClickRenderer(verbose, steps_only, solutions_only)
|
|
237
|
+
plugin_templates: dict[str, list[SafTemplate]] = {}
|
|
238
|
+
plugin_errors: list[SafPluginValidationError] = []
|
|
239
|
+
template_errors: list[SafTemplateValidationError] = []
|
|
240
|
+
for plugin in _iterate_plugins():
|
|
241
|
+
if isinstance(plugin, SafPluginValidationError):
|
|
242
|
+
plugin_errors.append(plugin)
|
|
243
|
+
continue
|
|
244
|
+
for saf_template in _scan_plugin_templates(plugin):
|
|
245
|
+
if isinstance(saf_template, SafTemplateValidationError):
|
|
246
|
+
template_errors.append(saf_template)
|
|
247
|
+
continue
|
|
248
|
+
if plugin.module_name not in plugin_templates:
|
|
249
|
+
plugin_templates[plugin.module_name] = []
|
|
250
|
+
plugin_templates[plugin.module_name].append(saf_template)
|
|
251
|
+
|
|
252
|
+
renderer.render_plugin_and_template_information(plugin_templates)
|
|
253
|
+
renderer.render_plugin_errors(plugin_errors)
|
|
254
|
+
renderer.render_template_errors(template_errors)
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Copyright (C) 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
import importlib.metadata
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
from cookiecutter.main import cookiecutter # pyright: ignore[reportUnknownVariableType, reportMissingTypeStubs]
|
|
22
|
+
|
|
23
|
+
from ansys.saf.cli._config.const import DEFAULT_SOLUTION_NAMESPACE, SOLUTION_TEMPLATE_PATH
|
|
24
|
+
from ansys.saf.cli._utilities.conversion import (
|
|
25
|
+
namespace_to_path,
|
|
26
|
+
namespace_to_pkg_name,
|
|
27
|
+
to_class_name,
|
|
28
|
+
to_docker_name,
|
|
29
|
+
to_module_name,
|
|
30
|
+
to_package_name,
|
|
31
|
+
)
|
|
32
|
+
from ansys.saf.cli._utilities.platform import appdata_directory
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def create_solution(
|
|
36
|
+
solution_name: str,
|
|
37
|
+
solution_display_name: str,
|
|
38
|
+
ui_framework: str,
|
|
39
|
+
namespace: str = DEFAULT_SOLUTION_NAMESPACE,
|
|
40
|
+
) -> None:
|
|
41
|
+
# see docs' glossary for a detailed explanation of every term used in the cookiecutter_kwargs
|
|
42
|
+
solution_module_name = to_module_name(solution_name)
|
|
43
|
+
solution_definition_class_name = to_class_name(solution_name, "Solution")
|
|
44
|
+
solution_package_name = to_package_name(solution_name)
|
|
45
|
+
version = "0.0.0"
|
|
46
|
+
docker_name = to_docker_name(solution_name, version)
|
|
47
|
+
saf_cli_version = importlib.metadata.version("ansys-saf-cli")
|
|
48
|
+
|
|
49
|
+
cookiecutter(
|
|
50
|
+
SOLUTION_TEMPLATE_PATH.as_posix(),
|
|
51
|
+
output_dir=Path.cwd().as_posix(),
|
|
52
|
+
no_input=True,
|
|
53
|
+
# overwrite all cookiecutter.json's terms
|
|
54
|
+
extra_context={
|
|
55
|
+
"__solution_name": solution_name,
|
|
56
|
+
"__solution_display_name": solution_display_name,
|
|
57
|
+
"__ui_framework": ui_framework,
|
|
58
|
+
"__solution_module_name": solution_module_name,
|
|
59
|
+
"__solution_definition_class_name": solution_definition_class_name,
|
|
60
|
+
"__solution_package_name": solution_package_name,
|
|
61
|
+
"__solution_namespace": namespace,
|
|
62
|
+
"__solution_namespace_path": namespace_to_path(namespace),
|
|
63
|
+
"__version": version,
|
|
64
|
+
"__docker_name": docker_name,
|
|
65
|
+
"__pkg_name": f"{namespace_to_pkg_name(namespace)}-{solution_package_name}",
|
|
66
|
+
"__pkg_namespace": f"{namespace}.{solution_module_name}",
|
|
67
|
+
"__pkg_path": f"{namespace_to_path(namespace)}/{solution_module_name}",
|
|
68
|
+
"__repository_url": "",
|
|
69
|
+
"__appdata_directory": appdata_directory(),
|
|
70
|
+
"__python_version": f"{sys.version_info.major}.{sys.version_info.minor}",
|
|
71
|
+
"__saf_cli_version": saf_cli_version,
|
|
72
|
+
},
|
|
73
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright (C) 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"__solution_name": "my_solution",
|
|
3
|
+
"__solution_display_name": "My Solution",
|
|
4
|
+
"__ui_framework": "dash",
|
|
5
|
+
"__solution_module_name": "my_solution",
|
|
6
|
+
"__solution_package_name": "my-solution",
|
|
7
|
+
"__solution_definition_class_name": "MySolution",
|
|
8
|
+
"__solution_namespace": "saf.solutions",
|
|
9
|
+
"__solution_namespace_path": "saf/solutions",
|
|
10
|
+
"__version": "0.0.0",
|
|
11
|
+
"__docker_name": "my-solution_0-0-0",
|
|
12
|
+
"__pkg_name": "saf-solutions-my-solution",
|
|
13
|
+
"__pkg_namespace": "saf.solutions.my_solution",
|
|
14
|
+
"__repository_url": "",
|
|
15
|
+
"__appdata_directory": "",
|
|
16
|
+
"__python_version": "3.10",
|
|
17
|
+
"__saf_cli_version": ""
|
|
18
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright (C) 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
import shutil
|
|
23
|
+
import os
|
|
24
|
+
|
|
25
|
+
SOLUTION_UI_PATH = Path.cwd() / "src" / f"{{ cookiecutter.__solution_namespace_path }}" / f"{{ cookiecutter.__solution_module_name }}" / "ui"
|
|
26
|
+
SOLUTION_UI_TESTS_PATH = Path.cwd() / "tests" / "unit" / "test_solution_ui.py"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _remove_ui_files() -> None:
|
|
30
|
+
if "{{ cookiecutter.__ui_framework }}" != "dash": # pyright: ignore[reportUnnecessaryComparison]
|
|
31
|
+
shutil.rmtree(SOLUTION_UI_PATH)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _remove_ui_tests() -> None:
|
|
35
|
+
if "{{ cookiecutter.__ui_framework }}" != "dash": # pyright: ignore[reportUnnecessaryComparison]
|
|
36
|
+
SOLUTION_UI_TESTS_PATH.unlink()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _copy_poetry_lock():
|
|
40
|
+
if "{{ cookiecutter.__ui_framework }}" == "dash": # pyright: ignore[reportUnnecessaryComparison]
|
|
41
|
+
shutil.copy(os.path.join("lock_files", "dash", "poetry.lock"), ".")
|
|
42
|
+
else:
|
|
43
|
+
shutil.copy(os.path.join("lock_files", "no_ui", "poetry.lock"), ".")
|
|
44
|
+
shutil.rmtree("lock_files")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def main():
|
|
48
|
+
_remove_ui_files()
|
|
49
|
+
_copy_poetry_lock()
|
|
50
|
+
_remove_ui_tests()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
main()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.10",
|
|
3
|
+
"features": {
|
|
4
|
+
},
|
|
5
|
+
"onCreateCommand": "pip install packaging toml && python setup_environment.py -d all -f",
|
|
6
|
+
"postCreateCommand": "chmod +x /workspaces/{{ cookiecutter.__solution_name }}/.venv/bin/activate && sed -i '$a source /workspaces/{{ cookiecutter.__solution_name }}/.venv/bin/activate' ~/.bashrc && sed -i '$a source /workspaces/{{ cookiecutter.__solution_name }}/.venv/bin/activate' ~/.zshrc",
|
|
7
|
+
"postAttachCommand": "tox -e style",
|
|
8
|
+
"customizations": {
|
|
9
|
+
"vscode": {
|
|
10
|
+
"extensions": [
|
|
11
|
+
"davidanson.vscode-markdownlint",
|
|
12
|
+
"donjayamanne.python-environment-manager",
|
|
13
|
+
"donjayamanne.python-extension-pack",
|
|
14
|
+
"github.vscode-github-actions",
|
|
15
|
+
"github.vscode-pull-request-github",
|
|
16
|
+
"kevinrose.vsc-python-indent",
|
|
17
|
+
"mhutchie.git-graph",
|
|
18
|
+
"ms-python.debugpy",
|
|
19
|
+
"ms-python.python",
|
|
20
|
+
"ms-python.vscode-pylance",
|
|
21
|
+
"shd101wyy.markdown-preview-enhanced",
|
|
22
|
+
"vscode-icons-team.vscode-icons"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
DATABASE_LOCATION={{ cookiecutter.__appdata_directory }}/ansys/portal/{{ cookiecutter.__solution_name }}
|
|
2
|
+
PORTAL_DATABASE_TYPE=sqlite
|
|
3
|
+
PORTAL_PROJECT_DATABASE_LOCATION=${DATABASE_LOCATION}/projects.db
|
|
4
|
+
GLOW_SOLUTION_DEFINITION={{ cookiecutter.__solution_namespace }}.{{ cookiecutter.__solution_module_name }}.solution.definition
|
|
5
|
+
GLOW_UI_MODULE={{ cookiecutter.__solution_namespace }}.{{ cookiecutter.__solution_module_name }}.ui.app
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
[flake8]
|
|
2
|
+
exclude = venv, __init__.py, doc/_build, .venv, tests/**
|
|
3
|
+
select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403
|
|
4
|
+
count = True
|
|
5
|
+
max-complexity = 10
|
|
6
|
+
max-line-length = 120
|
|
7
|
+
statistics = True
|
|
8
|
+
per-file-ignores = preprocessing.py:F401
|
ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/labeler.yml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
documentation:
|
|
2
|
+
- changed-files:
|
|
3
|
+
- any-glob-to-any-file: ['doc/source/**/*']
|
|
4
|
+
maintenance:
|
|
5
|
+
- changed-files:
|
|
6
|
+
- any-glob-to-any-file: ['.github/**/*', '.flake8', 'pyproject.toml']
|
|
7
|
+
dependencies:
|
|
8
|
+
- changed-files:
|
|
9
|
+
- any-glob-to-any-file: ['pyproject.toml']
|
ansys/saf/cli/_solutions/templates/solution/{{cookiecutter.__solution_name}}/.github/labels.yml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
- name: bug
|
|
2
|
+
description: Something isn't working
|
|
3
|
+
color: d42a34
|
|
4
|
+
|
|
5
|
+
- name: dependencies
|
|
6
|
+
description: Related with project dependencies
|
|
7
|
+
color: ffc0cb
|
|
8
|
+
|
|
9
|
+
- name: documentation
|
|
10
|
+
description: Improvements or additions to documentation
|
|
11
|
+
color: 0677ba
|
|
12
|
+
|
|
13
|
+
- name: enhancement
|
|
14
|
+
description: New features or code improvements
|
|
15
|
+
color: FFD827
|
|
16
|
+
|
|
17
|
+
- name: good first issue
|
|
18
|
+
description: Easy to solve for newcomers
|
|
19
|
+
color: 62ca50
|
|
20
|
+
|
|
21
|
+
- name: maintenance
|
|
22
|
+
description: Package and maintenance related
|
|
23
|
+
color: f78c37
|
|
24
|
+
|
|
25
|
+
- name: release
|
|
26
|
+
description: Anything related to an incoming release
|
|
27
|
+
color: ffffff
|