From b901b0fe15294eda03c5eb5fa3b40857fd3f8a98 Mon Sep 17 00:00:00 2001 From: Javier Izquierdo Hernandez Date: Mon, 16 Sep 2024 11:59:56 +0200 Subject: [PATCH 1/3] Adding style check call --- manager/manager/lint/linter.py | 6 +-- manager/manager/lint/pylint_checker_style.py | 32 +++++++++++++ manager/manager/manager.py | 47 ++++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 manager/manager/lint/pylint_checker_style.py diff --git a/manager/manager/lint/linter.py b/manager/manager/lint/linter.py index 54492df..3700133 100644 --- a/manager/manager/lint/linter.py +++ b/manager/manager/lint/linter.py @@ -50,7 +50,7 @@ def append_rating_if_missing(self, result): return result - def evaluate_code(self, code, exercise_id, ros_version, warnings=False): + def evaluate_code(self, code, exercise_id, ros_version, warnings=False, py_lint_source="pylint_checker.py"): try: code = re.sub(r'from HAL import HAL', 'from hal import HAL', code) code = re.sub(r'from GUI import GUI', 'from gui import GUI', code) @@ -76,9 +76,9 @@ def evaluate_code(self, code, exercise_id, ros_version, warnings=False): command = "" if "humble" in str(ros_version): - command = f"export PYTHONPATH=$PYTHONPATH:/RoboticsAcademy/exercises/static/exercises/{exercise_id}/python_template/ros2_humble; python3 RoboticsAcademy/src/manager/manager/lint/pylint_checker.py" + command = f"export PYTHONPATH=$PYTHONPATH:/RoboticsAcademy/exercises/static/exercises/{exercise_id}/python_template/ros2_humble; python3 RoboticsAcademy/src/manager/manager/lint/{py_lint_source}" else: - command = f"export PYTHONPATH=$PYTHONPATH:/RoboticsAcademy/exercises/static/exercises/{exercise_id}/python_template/ros1_noetic; python3 RoboticsAcademy/src/manager/manager/lint/pylint_checker.py" + command = f"export PYTHONPATH=$PYTHONPATH:/RoboticsAcademy/exercises/static/exercises/{exercise_id}/python_template/ros1_noetic; python3 RoboticsAcademy/src/manager/manager/lint/{py_lint_source}" ret = subprocess.run( command, diff --git a/manager/manager/lint/pylint_checker_style.py b/manager/manager/lint/pylint_checker_style.py new file mode 100644 index 0000000..feccb3d --- /dev/null +++ b/manager/manager/lint/pylint_checker_style.py @@ -0,0 +1,32 @@ +import tempfile +import subprocess +import os + +# Read user code +code = open('user_code.py') +python_code = code.read() +code.close() + +# Create temp file +code_file = tempfile.NamedTemporaryFile(delete=False) +code_file.write(python_code.encode()) +code_file.seek(0) +code_file.close() + +options = f"{code_file.name} --enable=similarities --disable=C0114,C0116,C0411,E0401,R0022,W0012 --max-line-length 80 --reports=y" + +# Run pylint using subprocess +result = subprocess.run(['pylint'] + options.split(), capture_output=True, text=True) + +# Process pylint exit +stdout = result.stdout + +# Clean temp files +if os.path.exists(code_file.name): + os.remove(code_file.name) + +# Replace tmp file name with user_code +output = stdout.replace(code_file.name, "user_code") # For tmp/**** +output = output.replace(code_file.name.replace("/tmp/",""), "user_code") # For **** + +print(output) \ No newline at end of file diff --git a/manager/manager/manager.py b/manager/manager/manager.py index b84a147..33b9873 100644 --- a/manager/manager/manager.py +++ b/manager/manager/manager.py @@ -284,6 +284,53 @@ def add_frequency_control(self, code): code = code + frequency_control_code_post return code + def on_style_check_application(self, event): + def find_docker_console(): + """Search console in docker different of /dev/pts/0""" + pts_consoles = [f"/dev/pts/{dev}" for dev in os.listdir('/dev/pts/') if dev.isdigit()] + consoles = [] + for console in pts_consoles: + if console != "/dev/pts/0": + try: + # Search if it's a console + with open(console, 'w') as f: + f.write("") + consoles.append(console) + except Exception: + # Continue searching + continue + + # raise Exception("No active console other than /dev/pts/0") + return consoles + + code_path = "/workspace/code/exercise.py" + # Extract app config + app_cfg = event.kwargs.get("data", {}) + try: + if app_cfg["type"] == "bt-studio": + return + except Exception: + pass + + exercise_id = app_cfg["exercise_id"] + code = app_cfg["code"] + + # Make code backwards compatible + code = code.replace("from GUI import GUI", "import GUI") + code = code.replace("from HAL import HAL", "import HAL") + + # Create executable app + errors = self.linter.evaluate_code(code, exercise_id, self.ros_version, py_lint_source="pylint_checker_style.py") + + if errors == "": + errors = "No errors found" + + console_path = find_docker_console() + for i in console_path: + with open(i, 'w') as console: + console.write(errors + "\n\n") + + raise Exception(errors) def on_run_application(self, event): def find_docker_console(): From ed5404d70a0e1401d55a6eaf06add635531600c1 Mon Sep 17 00:00:00 2001 From: Javier Izquierdo Hernandez Date: Mon, 16 Sep 2024 12:26:15 +0200 Subject: [PATCH 2/3] Adding transitonless transition --- manager/manager/manager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/manager/manager/manager.py b/manager/manager/manager.py index 33b9873..18182f5 100644 --- a/manager/manager/manager.py +++ b/manager/manager/manager.py @@ -113,6 +113,13 @@ class Manager: "dest": "idle", "before": "on_disconnect", }, + # Style check + { + "trigger": "style_check", + "source": "*", + "dest": "*", + "before": "on_style_check_application", + }, ] def __init__(self, host: str, port: int): From 22f6475f9c3d8d0c3f84d144ba8157509e072829 Mon Sep 17 00:00:00 2001 From: Javier Izquierdo Hernandez Date: Wed, 18 Sep 2024 21:27:53 +0200 Subject: [PATCH 3/3] Working prototype --- manager/manager/lint/pylint_checker_style.py | 2 +- manager/manager/manager.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/manager/manager/lint/pylint_checker_style.py b/manager/manager/lint/pylint_checker_style.py index feccb3d..bad58b6 100644 --- a/manager/manager/lint/pylint_checker_style.py +++ b/manager/manager/lint/pylint_checker_style.py @@ -13,7 +13,7 @@ code_file.seek(0) code_file.close() -options = f"{code_file.name} --enable=similarities --disable=C0114,C0116,C0411,E0401,R0022,W0012 --max-line-length 80 --reports=y" +options = f"{code_file.name} --enable=similarities --disable=C0114,C0116,C0411,E0401,R0022,W0012 --max-line-length=80 --reports=y" # Run pylint using subprocess result = subprocess.run(['pylint'] + options.split(), capture_output=True, text=True) diff --git a/manager/manager/manager.py b/manager/manager/manager.py index 18182f5..11758c2 100644 --- a/manager/manager/manager.py +++ b/manager/manager/manager.py @@ -310,7 +310,6 @@ def find_docker_console(): # raise Exception("No active console other than /dev/pts/0") return consoles - code_path = "/workspace/code/exercise.py" # Extract app config app_cfg = event.kwargs.get("data", {}) try: