Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type stub generator for operations. #817

Merged
merged 10 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 50 additions & 7 deletions pyinfra/api/arguments.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Callable, Iterable, Mapping

from pyinfra import context, logger

from .util import get_call_location, memoize
Expand All @@ -6,34 +8,42 @@
"_sudo": {
"description": "Execute/apply any changes with ``sudo``.",
"default": lambda config: config.SUDO,
"type": bool,
},
"_sudo_user": {
"description": "Execute/apply any changes with ``sudo`` as a non-root user.",
"default": lambda config: config.SUDO_USER,
"type": bool,
},
"_use_sudo_login": {
"description": "Execute ``sudo`` with a login shell.",
"default": lambda config: config.USE_SUDO_LOGIN,
"type": bool,
},
"_use_sudo_password": {
"description": "Whether to use a password with ``sudo`` (will ask).",
"default": lambda config: config.USE_SUDO_PASSWORD,
"type": bool,
},
"_preserve_sudo_env": {
"description": "Preserve the shell environment when using ``sudo``.",
"default": lambda config: config.PRESERVE_SUDO_ENV,
"type": bool,
},
"_su_user": {
"description": "Execute/apply any changes with ``su``.",
"default": lambda config: config.SU_USER,
"type": bool,
},
"_use_su_login": {
"description": "Execute ``su`` with a login shell.",
"default": lambda config: config.USE_SU_LOGIN,
"type": bool,
},
"_preserve_su_env": {
"description": "Preserve the shell environment when using ``su``.",
"default": lambda config: config.PRESERVE_SU_ENV,
"type": bool,
},
"_su_shell": {
"description": (
Expand All @@ -42,14 +52,17 @@
"has nologin/similar as their login shell."
),
"default": lambda config: config.SU_SHELL,
"type": str,
},
"_doas": {
"description": "Execute/apply any changes with ``doas``.",
"defailt": lambda config: config.DOAS,
"type": bool,
},
"_doas_user": {
"description": "Execute/apply any changes with ``doas`` as a non-root user.",
"default": lambda config: config.DOAS_USER,
"type": bool,
},
}

Expand All @@ -71,51 +84,81 @@ def generate_env(config, value):
"_shell_executable": {
"description": "The shell to use. Defaults to ``sh`` (Unix) or ``cmd`` (Windows).",
"default": lambda config: config.SHELL,
"type": str,
},
"_chdir": {
"description": "Directory to switch to before executing the command.",
"type": str,
},
"_env": {
"description": "Dictionary of environment variables to set.",
"handler": generate_env,
"type": Mapping[str, str],
},
"_success_exit_codes": {
"description": "List of exit codes to consider a success.",
"default": lambda config: [0],
"type": Iterable[int],
},
"_timeout": {
"description": "Timeout for *each* command executed during the operation.",
"type": int,
}, # TODO not sure
"_get_pty": {
"description": "Whether to get a pseudoTTY when executing any commands.",
"type": bool,
},
"_stdin": {
"description": "String or buffer to send to the stdin of any commands.",
"type": str, # TODO don't know the type for buffer
},
"_timeout": "Timeout for *each* command executed during the operation.",
"_get_pty": "Whether to get a pseudoTTY when executing any commands.",
"_stdin": "String or buffer to send to the stdin of any commands.",
}

meta_kwargs = {
# NOTE: name is the only non-_-prefixed argument
"name": {
"description": "Name of the operation.",
"type": str,
},
"_ignore_errors": {
"description": "Ignore errors when executing the operation.",
"default": lambda config: config.IGNORE_ERRORS,
"type": bool,
},
"_precondition": "Command to execute & check before the operation commands begin.",
"_postcondition": "Command to execute & check after the operation commands complete.",
"_on_success": "Callback function to execute on success.",
"_on_error": "Callback function to execute on error.",
"_precondition": {
"description": "Command to execute & check before the operation commands begin.",
"type": str,
}, # TODO not sure
"_postcondition": {
"description": "Command to execute & check after the operation commands complete.",
"type": str,
}, # TODO not sure
"_on_success": {
"description": "Callback function to execute on success.",
"type": Callable,
}, # TODO not sure if arguments can be typed too
"_on_error": {
"description": "Callback function to execute on error.",
"type": Callable,
}, # TODO not sure if arguments can be typed too
}

# Execution kwargs are global - ie must be identical for every host
execution_kwargs = {
"_parallel": {
"description": "Run this operation in batches of hosts.",
"default": lambda config: config.PARALLEL,
"type": bool,
},
"_run_once": {
"description": "Only execute this operation once, on the first host to see it.",
"default": lambda config: False,
"type": bool,
},
"_serial": {
"description": "Run this operation host by host, rather than in parallel.",
"default": lambda config: False,
"type": bool,
},
}

Expand Down
2 changes: 1 addition & 1 deletion pyinfra/operations/apk.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


@operation(is_idempotent=False)
def upgrade(available=False):
def upgrade(available: bool = False):
"""
Upgrades all apk packages.

Expand Down
95 changes: 95 additions & 0 deletions pyinfra/operations/apk.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import typing

def upgrade(
available: bool = False,
_sudo: typing.Optional[bool] = None,
_sudo_user: typing.Optional[bool] = None,
_use_sudo_login: typing.Optional[bool] = None,
_use_sudo_password: typing.Optional[bool] = None,
_preserve_sudo_env: typing.Optional[bool] = None,
_su_user: typing.Optional[bool] = None,
_use_su_login: typing.Optional[bool] = None,
_preserve_su_env: typing.Optional[bool] = None,
_su_shell: typing.Optional[str] = None,
_doas: typing.Optional[bool] = None,
_doas_user: typing.Optional[bool] = None,
_shell_executable: typing.Optional[str] = None,
_chdir: typing.Optional[str] = None,
_env: typing.Optional[typing.Mapping[str, str]] = None,
_success_exit_codes: typing.Optional[typing.Iterable[int]] = None,
_timeout: typing.Optional[int] = None,
_get_pty: typing.Optional[bool] = None,
_stdin: typing.Optional[str] = None,
name: typing.Optional[str] = None,
_ignore_errors: typing.Optional[bool] = None,
_precondition: typing.Optional[str] = None,
_postcondition: typing.Optional[str] = None,
_on_success: typing.Optional[typing.Callable] = None,
_on_error: typing.Optional[typing.Callable] = None,
_parallel: typing.Optional[bool] = None,
_run_once: typing.Optional[bool] = None,
_serial: typing.Optional[bool] = None,
): ...
def update(
_sudo: typing.Optional[bool] = None,
_sudo_user: typing.Optional[bool] = None,
_use_sudo_login: typing.Optional[bool] = None,
_use_sudo_password: typing.Optional[bool] = None,
_preserve_sudo_env: typing.Optional[bool] = None,
_su_user: typing.Optional[bool] = None,
_use_su_login: typing.Optional[bool] = None,
_preserve_su_env: typing.Optional[bool] = None,
_su_shell: typing.Optional[str] = None,
_doas: typing.Optional[bool] = None,
_doas_user: typing.Optional[bool] = None,
_shell_executable: typing.Optional[str] = None,
_chdir: typing.Optional[str] = None,
_env: typing.Optional[typing.Mapping[str, str]] = None,
_success_exit_codes: typing.Optional[typing.Iterable[int]] = None,
_timeout: typing.Optional[int] = None,
_get_pty: typing.Optional[bool] = None,
_stdin: typing.Optional[str] = None,
name: typing.Optional[str] = None,
_ignore_errors: typing.Optional[bool] = None,
_precondition: typing.Optional[str] = None,
_postcondition: typing.Optional[str] = None,
_on_success: typing.Optional[typing.Callable] = None,
_on_error: typing.Optional[typing.Callable] = None,
_parallel: typing.Optional[bool] = None,
_run_once: typing.Optional[bool] = None,
_serial: typing.Optional[bool] = None,
): ...
def packages(
packages=None,
present=True,
latest=False,
update=False,
upgrade=False,
_sudo: typing.Optional[bool] = None,
_sudo_user: typing.Optional[bool] = None,
_use_sudo_login: typing.Optional[bool] = None,
_use_sudo_password: typing.Optional[bool] = None,
_preserve_sudo_env: typing.Optional[bool] = None,
_su_user: typing.Optional[bool] = None,
_use_su_login: typing.Optional[bool] = None,
_preserve_su_env: typing.Optional[bool] = None,
_su_shell: typing.Optional[str] = None,
_doas: typing.Optional[bool] = None,
_doas_user: typing.Optional[bool] = None,
_shell_executable: typing.Optional[str] = None,
_chdir: typing.Optional[str] = None,
_env: typing.Optional[typing.Mapping[str, str]] = None,
_success_exit_codes: typing.Optional[typing.Iterable[int]] = None,
_timeout: typing.Optional[int] = None,
_get_pty: typing.Optional[bool] = None,
_stdin: typing.Optional[str] = None,
name: typing.Optional[str] = None,
_ignore_errors: typing.Optional[bool] = None,
_precondition: typing.Optional[str] = None,
_postcondition: typing.Optional[str] = None,
_on_success: typing.Optional[typing.Callable] = None,
_on_error: typing.Optional[typing.Callable] = None,
_parallel: typing.Optional[bool] = None,
_run_once: typing.Optional[bool] = None,
_serial: typing.Optional[bool] = None,
): ...
Loading