From 2fda80ed5456fd4185c2231e020cc9892acad79d Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 08:55:04 -0500 Subject: [PATCH 01/11] get rid of colorama and instead use rich --- src/cloudmesh/installer/installer.py | 64 ++++++++++++++++++---------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/src/cloudmesh/installer/installer.py b/src/cloudmesh/installer/installer.py index 466120b..cad9d1c 100644 --- a/src/cloudmesh/installer/installer.py +++ b/src/cloudmesh/installer/installer.py @@ -150,7 +150,10 @@ from cloudmesh.common.systeminfo import os_is_windows from cloudmesh.installer.__version__ import version as installer_version from cloudmesh.installer.bundle import * -from colorama import Fore, Style +# from colorama import Fore, Style +from rich.text import Text +from rich import print + from docopt import docopt from ordered_set import OrderedSet from tabulate import tabulate @@ -192,7 +195,8 @@ def run(command, verbose=True): except subprocess.CalledProcessError as err: if verbose: print() - print(Fore.RED + f"ERROR: {err}") + # print(Fore.RED + f"ERROR: {err}") + print(f"ERROR: {err}", style="bold red") sys.exit(1) return output.decode("utf-8") @@ -274,13 +278,16 @@ def url(repo, protocol="https"): return f"{prefix}cloudmesh/{repo}" @staticmethod - def error_color(error="ERROR"): + def error_color(error="ERROR") -> str: if error == "ERROR": - color = Fore.RED + # color = Fore.RED + color = "bold red" elif error == "WARNING": - color = Fore.MAGENTA + # color = Fore.MAGENTA + color = "bold magenta" elif error == "INFO": - color = Fore.MAGENTA + # color = Fore.MAGENTA + color = "bold magenta" else: color = "" return color @@ -304,7 +311,8 @@ def clone(repos, error="INFO", protocol="https"): color = Git.error_color(error) print( - color + f" {error}: not downloaded as repo already exists." + f" {error}: not downloaded as repo already exists.", + style=color, ) @staticmethod @@ -324,14 +332,17 @@ def command(repos, name, ok_msg="nothing to commit, working tree clean", r=False try: os.chdir(repo) except FileNotFoundError: - print(Fore.RED + "ERROR:", repo, "not found") + # print(Fore.RED + "ERROR:", repo, "not found") + print("ERROR:", repo, "not found", style="bold red") result = run(f"git {name}", verbose=False) if ok_msg in result: - print(Fore.GREEN + "... ok") + # print(Fore.GREEN + "... ok") + print("... ok", style="bold green") else: print() - print(Fore.RED + result) + # print(Fore.RED + result) + print(result, style="bold red") os.chdir("../") @staticmethod @@ -344,15 +355,18 @@ def _command(repos, command, ok_msg="Uploading", verbose=False, r=False): try: os.chdir(repo) except FileNotFoundError: - print(Fore.RED + "ERROR:", repo, "not found") + # print(Fore.RED + "ERROR:", repo, "not found") + print("ERROR:", repo, "not found", style="bold red") result = run(f"{command}", verbose=False) if ok_msg in result: - print(Fore.GREEN + "... ok") + # print(Fore.GREEN + "... ok") + print("... ok", style="bold green") else: print() - print(Fore.RED + result) + # print(Fore.RED + result) + print(result, style="bold red") if verbose: print() @@ -426,18 +440,20 @@ def install(repos, dev=False, protocol="https"): def yn_question(msg): while True: - query = input(Fore.RED + msg) + print(msg, style="bold red") + query = input() answer = query.lower().strip() if query == "" or answer not in ["yes", "n"]: print("Please answer with yes/n!") else: break - print(Fore.RESET) + # print(Fore.RESET) return answer == "yes" def RED(msg): - print(Fore.RED + msg + Fore.RESET) + # print(Fore.RED + msg + Fore.RESET) + print(msg, style="bold red") def ERROR(msg): @@ -490,7 +506,9 @@ def bundle_list(repos): def bundle_elements(bundle): - block = Fore.BLUE + f"\n{bundle}:\n" + Fore.RESET + # block = Fore.BLUE + f"\n{bundle}:\n" + Fore.RESET + block = Text(f"\n{bundle}:\n", style="blue") + # block = "[blue]\n" + f"{bundle}:\n" + "[/blue]" elements = " ".join(repos[bundle]) block = block + textwrap.indent( textwrap.fill(elements, 70, break_on_hyphens=False), " " @@ -624,7 +642,7 @@ def _get_bundles(): native = hasattr(sys, "real_prefix") executable = sys.executable if native: - banner(WARNING, c=Fore.RED) + banner(WARNING, color="red") print() RED( "You are likely not running in a venv. " @@ -649,7 +667,8 @@ def _get_bundles(): packages = repos[bundle] for package in packages: - undefined = Fore.RED + "not found" + Style.RESET_ALL + # undefined = Fore.RED + "not found" + Style.RESET_ALL + undefined = Text("not found", style="red") entry = [ package, undefined, # "git": @@ -843,7 +862,7 @@ def _get_bundles(): environment = arguments["--venv"] print() - banner(WARNING, c=Fore.RED) + banner(WARNING, c="red") RED( textwrap.dedent( @@ -892,7 +911,7 @@ def _get_bundles(): print(f" found -> {egg}") else: print() - banner(WARNING, c=Fore.RED) + banner(WARNING, c="red") RED( textwrap.dedent( @@ -911,8 +930,7 @@ def _get_bundles(): print() if not yn_question( - Fore.RED - + "WARNING: Removing listed files. Do you really want to continue. yes/n)? " + "WARNING: Removing listed files. Do you really want to continue. yes/n)? " ): sys.exit(1) From cce3bc11ba94676ae6754e60bd8fb72caa537961 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:05:02 -0500 Subject: [PATCH 02/11] add rich --- src/cloudmesh/installer/installer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cloudmesh/installer/installer.py b/src/cloudmesh/installer/installer.py index cad9d1c..c8e81bc 100644 --- a/src/cloudmesh/installer/installer.py +++ b/src/cloudmesh/installer/installer.py @@ -151,6 +151,7 @@ from cloudmesh.installer.__version__ import version as installer_version from cloudmesh.installer.bundle import * # from colorama import Fore, Style +from rich.console import Console as RichConsole from rich.text import Text from rich import print @@ -163,6 +164,9 @@ debug = False benchmark = False +console = RichConsole() +print = console.print + def os_is_pi(): """ From 1d1f8f87ea5dfd4d7dfaa1ae9a2212fb84194779 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:05:50 -0500 Subject: [PATCH 03/11] add rich --- src/cloudmesh/installer/installer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cloudmesh/installer/installer.py b/src/cloudmesh/installer/installer.py index c8e81bc..c45d735 100644 --- a/src/cloudmesh/installer/installer.py +++ b/src/cloudmesh/installer/installer.py @@ -153,7 +153,6 @@ # from colorama import Fore, Style from rich.console import Console as RichConsole from rich.text import Text -from rich import print from docopt import docopt from ordered_set import OrderedSet From 2f0116faa0adb51251ee0ca50fd5e24f5b55fe12 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:07:18 -0500 Subject: [PATCH 04/11] add test --- workflows/python-package-conda.yml | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 workflows/python-package-conda.yml diff --git a/workflows/python-package-conda.yml b/workflows/python-package-conda.yml new file mode 100644 index 0000000..69b4d3b --- /dev/null +++ b/workflows/python-package-conda.yml @@ -0,0 +1,99 @@ +name: Python Package using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.12 + uses: actions/setup-python@v3 + with: + python-version: '3.12' + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + + - name: Add extra channels + run: | + conda config --add channels conda-forge + conda config --add channels defaults + + - name: Install dependencies + run: | + conda env update --file environment.yml --name base + - name: Lint with flake8 + run: | + conda install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 --exclude deprecated . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 --exclude deprecated . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + + - name: Install current Python library + run: | + source activate base # Activate the conda environment + pip install -e . # Install the current Python library in editable mode + # pip install cloudmesh-vpn + - name: Test with pytest + run: | + conda install pytest + source activate base & pytest tests -rsx + + +# build-windows: +# runs-on: windows-latest +# strategy: +# max-parallel: 5 +# +# steps: +# # - uses: actions/checkout@v3 +# # - name: Set up Python 3.10 +# # uses: conda-incubator/setup-miniconda@v2 +# # with: +# # miniconda-version: "latest" +# - uses: actions/checkout@v3 +# - name: Set up Python 3.12 +# uses: actions/setup-python@v3 +# with: +# python-version: '3.12' +# # - name: Add conda to system path +# # run: | +# # # $CONDA is an environment variable pointing to the root of the miniconda directory +# # echo $CONDA/bin >> $GITHUB_PATH +# # - name: Add extra channels +# # run: | +# # conda config --add channels conda-forge +# # conda config --add channels defaults +# +# # - name: Install dependencies +# # run: | +# # conda env update --file environment.yml --name base +# - name: set up env3 +# run: | +# python -m venv ENV3 +# +# - name: Lint with flake8 +# run: | +# .\ENV3\Scripts\activate.ps1 +# pip install flake8 +# # stop the build if there are Python syntax errors or undefined names +# flake8 --exclude deprecated . --count --select=E9,F63,F7,F82 --show-source --statistics +# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide +# flake8 --exclude deprecated . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics +# +# - name: Install current Python library +# run: | +# .\ENV3\Scripts\activate.ps1 +# pip install -e . # Install the current Python library in editable mode +# pip install cloudmesh-vpn +# - name: Test with pytest +# run: | +# .\ENV3\Scripts\activate.ps1 +# pip install pytest +# pytest tests -rsx From 8392005f8871d25244bac277a1dd73b83e78fd9e Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:10:46 -0500 Subject: [PATCH 05/11] add test --- {workflows => .github/workflows}/python-package-conda.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {workflows => .github/workflows}/python-package-conda.yml (100%) diff --git a/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml similarity index 100% rename from workflows/python-package-conda.yml rename to .github/workflows/python-package-conda.yml From f06033154c9492e8401eacce226c4fad8040ec12 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:13:31 -0500 Subject: [PATCH 06/11] test --- .github/workflows/python-package-conda.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 69b4d3b..e22665a 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -24,9 +24,9 @@ jobs: conda config --add channels conda-forge conda config --add channels defaults - - name: Install dependencies - run: | - conda env update --file environment.yml --name base + # - name: Install dependencies + # run: | + # conda env update --file environment.yml --name base - name: Lint with flake8 run: | conda install flake8 From b2d260e3f3a25c8cbc59c2b626badec5a44e87b7 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:30:01 -0500 Subject: [PATCH 07/11] fix version --- src/cloudmesh/installer/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cloudmesh/installer/installer.py b/src/cloudmesh/installer/installer.py index c45d735..a77e77c 100644 --- a/src/cloudmesh/installer/installer.py +++ b/src/cloudmesh/installer/installer.py @@ -148,7 +148,7 @@ from cloudmesh.common.util import banner from cloudmesh.common.util import readfile from cloudmesh.common.systeminfo import os_is_windows -from cloudmesh.installer.__version__ import version as installer_version +from cloudmesh.installer import __version__ as installer_version from cloudmesh.installer.bundle import * # from colorama import Fore, Style from rich.console import Console as RichConsole From 6f6ecd9818aaa93c642927a6096edaddb177e2a2 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Tue, 9 Jan 2024 02:00:13 -0500 Subject: [PATCH 08/11] fix dependencies --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d4b4ed1..6f5736f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ dependencies = [ "toml", "docopt", "ordered_set", + "rich", "cloudmesh-common", ] From 1652eea44d72a4ccda4a81568b596d9ef30bc2dd Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:11:01 -0500 Subject: [PATCH 09/11] add rich table --- src/cloudmesh/installer/installer.py | 41 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/cloudmesh/installer/installer.py b/src/cloudmesh/installer/installer.py index a77e77c..18a983e 100644 --- a/src/cloudmesh/installer/installer.py +++ b/src/cloudmesh/installer/installer.py @@ -141,7 +141,7 @@ from pprint import pprint import platform -import colorama +# import colorama import requests from cloudmesh.common.StopWatch import StopWatch from cloudmesh.common.console import Console @@ -153,6 +153,7 @@ # from colorama import Fore, Style from rich.console import Console as RichConsole from rich.text import Text +from rich.table import Table from docopt import docopt from ordered_set import OrderedSet @@ -493,7 +494,7 @@ def get_all_repos(): def check_for_bundle(bundle): if bundle is None: - ERROR("No bundle specified.") + ERROR("No bundle specified.") sys.exit(1) elif not ((bundle in repos) or (bundle in ["cloudmesh", "all"])): ERROR(f"The bundle `{bundle}` does not exist") @@ -508,15 +509,22 @@ def bundle_list(repos): return result -def bundle_elements(bundle): - # block = Fore.BLUE + f"\n{bundle}:\n" + Fore.RESET - block = Text(f"\n{bundle}:\n", style="blue") - # block = "[blue]\n" + f"{bundle}:\n" + "[/blue]" - elements = " ".join(repos[bundle]) - block = block + textwrap.indent( - textwrap.fill(elements, 70, break_on_hyphens=False), " " - ) - return block +def bundle_elements(bundle) -> Table: + table = Table(title="Cloudmesh Bundles", + show_lines=True, + # show_header=True, + header_style="black", + title_style="bold black", + ) + + table.add_column("Bundle", style="cyan") + table.add_column("Repos", style="magenta") + + for bundle in repos: + repos_list = repos[bundle] + if repos_list: # check if the list is not empty + table.add_row(bundle, ', '.join(repos_list)) # add the repos as a comma-separated list + return table def main(): @@ -536,7 +544,7 @@ def main(): if arguments["--ssh"]: protocol = "ssh" - colorama.init(autoreset=True) + # colorama.init(autoreset=True) if debug: banner("BEGIN ARGUMENTS") @@ -611,12 +619,9 @@ def _get_bundles(): elif arguments["list"] and not arguments["BUNDLE"] and not arguments["--git"]: if not arguments["--short"]: - banner("Cloudmesh Bundles") - block = "" - for bundle in repos: - block = block + bundle_elements(bundle) - - print(block) + # banner("Cloudmesh Bundles") + table = bundle_elements(bundle) + print(table) else: print(bundle_list(repos)) From 36925b00bab0948a5875e5548249ef0cc7a1512a Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:50:42 -0500 Subject: [PATCH 10/11] fix test --- tests/test_installer.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_installer.py b/tests/test_installer.py index a20a91d..fd95792 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -60,8 +60,11 @@ def test_non_existing(self): print("PWD:", os.getcwd()) cmd = "cloudmesh-installer git clone WRONG" - result = Shell.run(cmd) - assert True + try: + result = Shell.run(cmd) + assert False + except RuntimeError: + assert True def test_clone_community(self): banner("test_clone_community") From de84af371ecdfdd36db361d92245665ca86302e9 Mon Sep 17 00:00:00 2001 From: "J.P" <70083705+stapmoshun@users.noreply.github.com> Date: Sun, 14 Jan 2024 14:00:46 -0500 Subject: [PATCH 11/11] fix test --- tests/test_installer.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/test_installer.py b/tests/test_installer.py index fd95792..a1ac1db 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -8,7 +8,6 @@ import os import pytest -from cloudmesh.common.util import readfile from cloudmesh.common.Shell import Shell from cloudmesh.common.util import banner @@ -31,7 +30,7 @@ def test_create_dir(self): def test_version(self): banner("test_version") - cmd = "cloudmesh-installer version" + cmd = "cmsi version" result = Shell.run(cmd) print(result) print() @@ -41,7 +40,7 @@ def test_info(self): banner("test_info") print("PWD:", os.getcwd()) - cmd = "cloudmesh-installer info" + cmd = "cmsi info" result = Shell.run(cmd) print(result) print() @@ -50,7 +49,7 @@ def test_info(self): def test_list(self): banner("list") - cmd = "cloudmesh-installer list" + cmd = "cmsi list" result = Shell.run(cmd) print(result) assert "cloudmesh-common" in result @@ -59,7 +58,7 @@ def test_non_existing(self): banner("test_non_existing") print("PWD:", os.getcwd()) - cmd = "cloudmesh-installer git clone WRONG" + cmd = "cmsi git clone WRONG" try: result = Shell.run(cmd) assert False @@ -70,7 +69,7 @@ def test_clone_community(self): banner("test_clone_community") print("PWD:", os.getcwd()) - cmd = "cloudmesh-installer git clone community" + cmd = "cmsi git clone community" result = Shell.run(cmd) print(result) assert os.path.isdir("cloudmesh-community.github.io") @@ -79,7 +78,7 @@ def test_clone_cms(self): banner("test_clone_cms") print("PWD:", os.getcwd()) - cmd = "cloudmesh-installer git clone cms" + cmd = "cmsi git clone cms" result = Shell.run(cmd) print("RESULT:", result) @@ -99,10 +98,15 @@ def test_install_cms(self): banner("test_install_cms") print("PWD:", os.getcwd()) - cmd = "cloudmesh-installer install cms" + cmd = "cmsi install cms" result = Shell.run(cmd) print("RESULT:", result) - assert os.path.isdir("cloudmesh-cmd5/cloudmesh_cmd5.egg-info") + # Try to import the module and check if it raises an ImportError + try: + import cloudmesh.shell + assert True + except ImportError: + assert False def test_cms_help(self): banner("test_cms_help")