Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 17 additions & 5 deletions robotpy_installer/cli_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def run(
no_resolve: bool,
local: bool,
cache_root: typing.Optional[pathlib.Path],
assume_yes: bool = False,
):
if main_file.parent == pathlib.Path.home():
print_err(
Expand Down Expand Up @@ -228,7 +229,7 @@ def run(

robot_filename = main_file.name

if not large and not self._check_large_files(project_path):
if not large and not self._check_large_files(project_path, assume_yes):
return 1

project = None
Expand Down Expand Up @@ -291,6 +292,7 @@ def run(
no_install,
force_install,
no_uninstall,
assume_yes,
)

if not self._do_deploy(ssh, debug, nc, nc_ds, robot_filename, project_path):
Expand Down Expand Up @@ -351,7 +353,7 @@ def _generate_build_data(self, project_path: pathlib.Path) -> dict:

return deploy_data

def _check_large_files(self, robot_path: pathlib.Path):
def _check_large_files(self, robot_path: pathlib.Path, assume_yes: bool = False):
large_sz = 250000

large_files = []
Expand All @@ -365,7 +367,7 @@ def _check_large_files(self, robot_path: pathlib.Path):
for fname, sz in sorted(large_files):
print_err(f"- {fname} ({sz} bytes)")

if not yesno("Upload anyways?"):
if not assume_yes and not yesno("Upload anyways?"):
return False

return True
Expand Down Expand Up @@ -398,6 +400,7 @@ def _ensure_requirements(
no_install: bool,
force_install: bool,
no_uninstall: bool,
assume_yes: bool = False,
):
python_exists = False
python_invalid: typing.Union[bool, str] = False
Expand Down Expand Up @@ -438,7 +441,7 @@ def _ensure_requirements(
f"and install Python {rm}.{rmn}.\n"
)

if not yesno("Reinstall Python"):
if not assume_yes and not yesno("Reinstall Python"):
raise Error("User declined reinstallation")

if python_exists:
Expand Down Expand Up @@ -492,7 +495,7 @@ def _ensure_requirements(
"If you do not wish to do this, specify --no-install as a deploy argument, or answer 'n'.\n"
)

if not yesno(prompt):
if not assume_yes and not yesno(prompt):
requirements_installed = True

if (
Expand Down Expand Up @@ -783,6 +786,13 @@ def __init__(self, parser: argparse.ArgumentParser):
help="Override RobotPy installer cache location; defaults to /opt/blocks/cache",
)

parser.add_argument(
"--yes",
action="store_true",
default=False,
help="If specified, do not ask any interactive questions; assume 'yes' and deploy unattended",
)

self._packages_in_cache: typing.Optional[pypackages.Packages] = None
self._robot_packages: typing.Optional[pypackages.Packages] = None

Expand All @@ -798,6 +808,7 @@ def run(
force_install: bool,
large: bool,
cache_root: typing.Optional[pathlib.Path],
yes: bool = False,
):
return Deploy.run(
self,
Expand All @@ -820,4 +831,5 @@ def run(
no_resolve=False,
local=True,
cache_root=cache_root,
assume_yes=yes,
)
67 changes: 67 additions & 0 deletions tests/test_local_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,73 @@ def test_local_deploy_installer_subcommand_is_registered():
assert ("local-deploy", LocalDeploy) in Installer.subcommands


def test_local_deploy_parser_has_yes_option():
parser = argparse.ArgumentParser()
LocalDeploy(parser)

args = parser.parse_args([])
assert args.yes is False

args = parser.parse_args(["--yes"])
assert args.yes is True


def test_local_deploy_yes_does_not_prompt_on_requirements_mismatch(tmp_path):
deploy = LocalDeploy(argparse.ArgumentParser())
main_file = tmp_path / "robot.py"
main_file.write_text("print('robot')")

fake_project = MagicMock()
fake_project.get_install_list.return_value = ["robotpy"]
fake_project.are_requirements_met.side_effect = [
(False, ["robotpy missing"]),
(True, []),
(True, []),
]
fake_project.get_deploy_list.return_value = ["robotpy"]

fake_installer = MagicMock()
fake_installer.is_python_installed.return_value = True
fake_installer.get_python_version.return_value = required_pyversion
fake_installer.connect_to_robot.return_value.__enter__.return_value = (
LocalController()
)
fake_installer.connect_to_robot.return_value.__exit__.return_value = None

with (
patch("robotpy_installer.cli_deploy.pyproject.load", return_value=fake_project),
patch(
"robotpy_installer.cli_deploy.RobotpyInstaller", return_value=fake_installer
),
patch.object(deploy, "_get_robot_packages", return_value={}),
patch.object(deploy, "_get_cached_packages", return_value={}),
patch.object(deploy, "_do_deploy", return_value=True),
patch(
"robotpy_installer.cli_deploy.robot_utils.uninstall_cpp_java",
return_value=True,
),
patch("robotpy_installer.cli_deploy.yesno") as fake_yesno,
):
result = deploy.run(
main_file=main_file,
project_path=tmp_path,
debug=False,
ignore_image_version=False,
no_install=False,
no_uninstall=False,
force_install=False,
large=False,
cache_root=None,
yes=True,
)

assert result == 0
fake_yesno.assert_not_called()
fake_installer.pip_install.assert_called_once_with(
False, False, False, False, [], ["robotpy"]
)


def test_deploy_run_has_no_suppress_no_verify_warning_argument():
assert "suppress_no_verify_warning" not in inspect.signature(Deploy.run).parameters

Expand Down
Loading