From a5001783f71d98c303ca62c918a07839e4befa2a Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Mon, 15 Mar 2021 09:20:31 +1000 Subject: [PATCH 1/3] ensureVenv.py: As Python virtual environements hard-code the path where they were created in their activation script, dedetect if the venv has been copied to another location and if so ask the user if the environment should be recreated at the new location or to abort. --- venvUtils/ensureVenv.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/venvUtils/ensureVenv.py b/venvUtils/ensureVenv.py index 3256fdfba4d..a42b3bd31c4 100644 --- a/venvUtils/ensureVenv.py +++ b/venvUtils/ensureVenv.py @@ -21,6 +21,29 @@ venv_python_version_path: str = os.path.join(venv_path, "python_version") +def verifyExistingVenvPath(): + """ + Verifies that the Python virtual environment at c{VENV_PATH} was actually created at that location, + and not just copied or moved there. + """ + # Activate the Python virtual environement and capture the content of the VIRTUAL_ENV environment variable. + existingPath = subprocess.check_output( + [ + os.path.join(venv_path, "scripts", "activate.bat"), + "&&", + "call", "echo", "%VIRTUAL_ENV%", + ], + shell=True, + ).decode('utf8').rstrip() + existingPath = os.path.normpath(existingPath) + expectedPath = os.path.normpath(venv_path) + if existingPath != expectedPath: + print(f"Python virtual environment originally created at {existingPath},") + print(f"Then moved or copied to {expectedPath}.") + return False + return True + + def askYesNoQuestion(message: str) -> bool: """ Displays the given message to the user and accepts y or n as input. @@ -101,6 +124,16 @@ def ensureVenvAndRequirements(): if not os.path.exists(venv_path): print("Virtual environment does not exist.") return createVenvAndPopulate() + if not verifyExistingVenvPath(): + if askYesNoQuestion( + "A Python virtual environement cannot be activated from a different location " + "to where it was originally created.\n" + "Should the virtual environment be recreated with the updated location?" + ): + return createVenvAndPopulate() + else: + print("Aborting") + sys.exit(1) if ( not os.path.exists(venv_python_version_path) or not os.path.exists(venv_orig_requirements_path) From 01316fbe8b1b17047c21f2472a6bf19a2de0ce87 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Mon, 15 Mar 2021 09:55:20 +1000 Subject: [PATCH 2/3] buildSystemNotes: mention that the virtual environment will be recreated if it has been moved from its original place of creation. --- devDocs/buildSystemNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/devDocs/buildSystemNotes.md b/devDocs/buildSystemNotes.md index 432b0515e5f..8d8a10225b5 100644 --- a/devDocs/buildSystemNotes.md +++ b/devDocs/buildSystemNotes.md @@ -18,6 +18,7 @@ Version numbers for dependencies should be used to lock in a version. The virtual environment is recreated if it is outdated, either due to: - Python version. - `pip` requirements. +- It was originally created at a different location to where it is now. The user is consulted before modifying / removing a virtual environment that can't be identified as having been created by NVDA's build system. From 8e262864f78d587bb961a22aa92575195f6870e0 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Mon, 15 Mar 2021 10:25:27 +1000 Subject: [PATCH 3/3] Address review actions. --- venvUtils/ensureVenv.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/venvUtils/ensureVenv.py b/venvUtils/ensureVenv.py index a42b3bd31c4..cd123e3bf7b 100644 --- a/venvUtils/ensureVenv.py +++ b/venvUtils/ensureVenv.py @@ -26,7 +26,7 @@ def verifyExistingVenvPath(): Verifies that the Python virtual environment at c{VENV_PATH} was actually created at that location, and not just copied or moved there. """ - # Activate the Python virtual environement and capture the content of the VIRTUAL_ENV environment variable. + # Activate the Python virtual environment and capture the content of the VIRTUAL_ENV environment variable. existingPath = subprocess.check_output( [ os.path.join(venv_path, "scripts", "activate.bat"), @@ -34,7 +34,7 @@ def verifyExistingVenvPath(): "call", "echo", "%VIRTUAL_ENV%", ], shell=True, - ).decode('utf8').rstrip() + ).decode('oem').rstrip() existingPath = os.path.normpath(existingPath) expectedPath = os.path.normpath(venv_path) if existingPath != expectedPath: @@ -126,7 +126,7 @@ def ensureVenvAndRequirements(): return createVenvAndPopulate() if not verifyExistingVenvPath(): if askYesNoQuestion( - "A Python virtual environement cannot be activated from a different location " + "A Python virtual environment cannot be activated from a different location " "to where it was originally created.\n" "Should the virtual environment be recreated with the updated location?" ):