diff --git a/dem/cli/command/export_cmd.py b/dem/cli/command/export_cmd.py new file mode 100644 index 0000000..405cea7 --- /dev/null +++ b/dem/cli/command/export_cmd.py @@ -0,0 +1,55 @@ +"""export CLI command implementation.""" +# dem/cli/command/export_cmd.py + + +import re +from dem.core.dev_env_setup import DevEnvLocalSetup +from dem.cli.console import stderr +import json, os + +def check_is_directory(param: str): + if None != param: + return(os.path.isdir(param)) + else: + return False + +def check_is_path_contains_spec_char(param: str): + special_chars=re.compile('[~/\^]') + if None != param: + if None != special_chars.search(param): + return True + else: + return False + else: + return False + +def create_exported_dev_env_json(dev_env_name: str,dev_env_json: str,given_path: str): + + file_name=None + file_path=None + + if True == check_is_directory(given_path): + file_name=dev_env_name + file_path=given_path+"/" + elif True == check_is_path_contains_spec_char(given_path): + file_name="" + file_path=given_path + elif None != given_path: + file_name=given_path + file_path="" + else: + file_name=dev_env_name + file_path="" + + exported_file = open(file_path+file_name, "w") + json.dump(dev_env_json, exported_file, indent=4) + exported_file.close() + +def execute(dev_env_name: str, path_to_export: str) -> None: + dev_env_local_setup = DevEnvLocalSetup() + dev_env_name_to_export = dev_env_local_setup.get_dev_env_by_name(dev_env_name) + + if dev_env_name_to_export is not None: + create_exported_dev_env_json(dev_env_name,dev_env_name_to_export.__dict__,path_to_export) + else: + stderr.print("[red]Error: The input Development Environment does not exist.[/]") \ No newline at end of file diff --git a/dem/cli/main.py b/dem/cli/main.py index f338957..4258008 100644 --- a/dem/cli/main.py +++ b/dem/cli/main.py @@ -4,7 +4,7 @@ import typer, importlib.metadata from dem import __command__, __app_name__ from dem.cli.command import info_cmd, list_cmd, pull_cmd, create_cmd, modify_cmd, delete_cmd, \ - rename_cmd, clone_cmd, run_cmd + rename_cmd, clone_cmd, run_cmd, export_cmd from dem.cli.console import stdout typer_cli = typer.Typer(rich_markup_mode="rich") @@ -62,6 +62,14 @@ def create(dev_env_name: str = typer.Argument(..., """ create_cmd.execute(dev_env_name) +@typer_cli.command() +def export(dev_env_name: str = typer.Argument(...,help="Name of the Development Environment to export."), + path_to_export: str = typer.Argument(None,help="Path where to extract the Dev Env.")) -> None: + """ + Export the Development Environment. + """ + export_cmd.execute(dev_env_name,path_to_export) + @typer_cli.command() def rename(dev_env_name: str = typer.Argument(...,help="Name of the Development Environment to rename."), new_dev_env_name: str = typer.Argument(...,help="The new name.")) -> None: diff --git a/tests/cli/test_export_cmd.py b/tests/cli/test_export_cmd.py new file mode 100644 index 0000000..cb8b78e --- /dev/null +++ b/tests/cli/test_export_cmd.py @@ -0,0 +1,91 @@ +"""Tests for the export CLI command.""" +# tests/cli/test_export_cmd.py + +# Unit under test: +from mock import patch +import dem.cli.main as main +import dem.cli.command.export_cmd as export_cmd + +# Test framework +import io +from typer.testing import CliRunner +from unittest.mock import MagicMock +from rich.console import Console + +## Global test variables +# In order to test stdout and stderr separately, the stderr can't be mixed into +# the stdout. +runner = CliRunner(mix_stderr=False) + +@patch("dem.cli.command.export_cmd.open") +@patch("dem.cli.command.export_cmd.os.path.isdir") +def test_create_exported_dev_env_json(mock_os_path_isdir,mock_open): + # Test setup + dev_env_name = "dev_env_name" + dev_env_json = { + "name": "Cica", + "tools": [ + { + "type": "build system", + "image_name": "axemsolutions/make_gnu_arm", + "image_version": "latest" + }] + } + given_path = "home" + mock_os_path_isdir.return_value = False + fake_opened_file = MagicMock() + mock_open.return_value = fake_opened_file + + # Run unit under test + export_cmd.create_exported_dev_env_json(dev_env_name,dev_env_json,given_path) + fake_opened_file.write.assert_called() + fake_opened_file.close.assert_called() + mock_open.assert_called_with(given_path , "w") + mock_os_path_isdir.assert_called() + + + mock_os_path_isdir.return_value = True + export_cmd.create_exported_dev_env_json(dev_env_name,dev_env_json,given_path) + fake_opened_file.write.assert_called() + fake_opened_file.close.assert_called() + mock_open.assert_called_with( given_path+"/"+dev_env_name , "w") + mock_os_path_isdir.assert_called() + + mock_os_path_isdir.return_value = False + given_path = "/home/axem" + export_cmd.create_exported_dev_env_json(dev_env_name,dev_env_json,given_path) + fake_opened_file.write.assert_called() + fake_opened_file.close.assert_called() + mock_open.assert_called_with( given_path , "w") + mock_os_path_isdir.assert_called() + + mock_os_path_isdir.return_value = False + given_path = None + export_cmd.create_exported_dev_env_json(dev_env_name,dev_env_json,given_path) + fake_opened_file.write.assert_called() + fake_opened_file.close.assert_called() + mock_open.assert_called_with( dev_env_name , "w") + mock_os_path_isdir.assert_called() + + + +def test_wo_path(): + + # Run unit under test + runner_result = runner.invoke(main.typer_cli, ["export", "Cica"]) + + # Check expectations + assert 0 == runner_result.exit_code + +def test_with_invalid_devenv(): + + # Run unit under test + runner_result = runner.invoke(main.typer_cli, ["export", ""]) + + # Check expectations + assert 0 == runner_result.exit_code + + console = Console(file=io.StringIO()) + console.print("[red]Error: The input Development Environment does not exist.[/]") + assert console.file.getvalue() == runner_result.stderr +