From 69431e17c935ec2a12de814786949d47f0e3eb12 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Wed, 19 Aug 2026 08:11:12 -0400 Subject: [PATCH] =?UTF-8?q?[FIX]=20script=20todo:=20configurer=20le=20proj?= =?UTF-8?q?et=20PyCharm=20avec=20le=20venv,=20et=20r=C3=A9essayer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deux défauts empêchaient le .idea d'exister. La configuration d'abord : « make pycharm_configure » lance le script avec le python SYSTÈME, qui n'a pas xmltodict — « ModuleNotFoundError », mesuré. update_env_version.pycharm_update() l'appelle depuis .venv.erplibre ; la cible make et l'étape font désormais pareil. L'ouverture ensuite : la première tentative sur un dépôt neuf peut n'écrire aucun .idea, son configurateur d'interpréteur plantant sur « homeDir is null », là où la suivante l'écrit en 25 s — constaté sur deux VM. L'étape retente donc une fois, en gardant les deux journaux. Vérifié sur erplibre-ubuntu-2604-gnome, caches effacés : erplibre.iml, misc.xml, modules.xml, vcs.xml, et 0 processus survivant. --- EN --- Two defects kept .idea from existing. The configuration first: "make pycharm_configure" runs the script with the SYSTEM python, which lacks xmltodict — "ModuleNotFoundError", measured. update_env_version.pycharm_update() calls it from .venv.erplibre; the make target and the step now do the same. The open next: the first attempt on a fresh repo can write no .idea at all, its interpreter configurator dying on "homeDir is null", where the next one writes it in 25 s — seen on two VMs. The step therefore retries once, keeping both logs. Verified on erplibre-ubuntu-2604-gnome with caches wiped: erplibre.iml, misc.xml, modules.xml, vcs.xml, and 0 surviving processes. Assisted-by: Claude Opus 5 --- Makefile | 7 ++++- script/todo/todo.py | 20 ++++++++++-- script/todo/todo_i18n.py | 4 +++ test/test_qemu_desktop_tools.py | 55 ++++++++++++++++++++++++++++----- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 6b7e893..6ac6eff 100644 --- a/Makefile +++ b/Makefile @@ -384,4 +384,9 @@ pycharm_open: .PHONY: pycharm_configure pycharm_configure: - ./script/ide/pycharm_configuration.py --init +# Le venv du dépôt, et non le python système : le script importe xmltodict, qui +# vit dans .venv.erplibre. Appelé directement, il s'arrête sur +# « ModuleNotFoundError: No module named 'xmltodict' » — et c'est cette cible +# que le message d'échec de l'installation recommande. update_env_version. +# pycharm_update() l'appelle déjà ainsi : une seule autorité. + ./.venv.erplibre/bin/python ./script/ide/pycharm_configuration.py --init diff --git a/script/todo/todo.py b/script/todo/todo.py index 33cab8c..b302720 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -5779,9 +5779,17 @@ class TODO: "sudo sysctl -q -p /etc/sysctl.d/60-erplibre-inotify.conf " f'2>/dev/null; echo " {t("inotify watches raised for the IDE")}"; ' "fi; " + # DEUX tentatives, et c'est mesuré : la première ouverture d'un + # dépôt neuf indexe 212 000 fichiers, plante son configurateur + # d'interpréteur (« PythonSdkConfigurator - homeDir is null ») et + # n'écrit AUCUN .idea, même au bout de cinq minutes. La seconde, sur + # les caches que la première a laissés, l'écrit en 25 secondes — + # constaté sur deux VM différentes. + ": > /tmp/pycharm-first-run.log; " + "for attempt in 1 2; do " 'PYCHARM_VM_OPTIONS="$HOME/.pycharm-headless.vmoptions" ' f"setsid xvfb-run -a pycharm {el_dir} " - "> /tmp/pycharm-first-run.log 2>&1 & " + ">> /tmp/pycharm-first-run.log 2>&1 & " "pid=$!; ok=0; " f"for i in $(seq 1 {self._QEMU_PYCHARM_OPEN_TRIES}); do " f"if ls {el_dir}/.idea/*.iml >/dev/null 2>&1 && " @@ -5814,6 +5822,9 @@ class TODO: f'echo " {t("closing what survived the first open:")} $left"; ' 'pkill -u "$(id -u)" -x ' '"pycharm|cef_server|fsnotifier|Xvfb" 2>/dev/null; sleep 2; }; ' + '[ "$ok" = 1 ] && break; ' + f'echo " {t("no project yet, second try on the warm caches")}"; ' + "done; " '[ "$ok" = 1 ]; fi; fi; } && ' f'echo " {t("project created, the install will configure it")}" ' f'|| echo " ⚠ {t("no .idea: open PyCharm once, then")} ' @@ -6669,7 +6680,12 @@ class TODO: # pycharm_update() n'avait alors rien à configurer. open_step = ( self._qemu_pycharm_project_cmd(prod) - + "make pycharm_configure || true; " + # Le venv du dépôt, comme le fait update_env_version. + # pycharm_update() : le script importe xmltodict, absent du python + # système. Mesuré : « make pycharm_configure » s'arrêtait sur + # « No module named 'xmltodict' ». + + "./.venv.erplibre/bin/python " + "./script/ide/pycharm_configuration.py --init || true; " if "pycharm" in (tools or ()) else "" ) diff --git a/script/todo/todo_i18n.py b/script/todo/todo_i18n.py index 6db8b81..cdb7ad2 100644 --- a/script/todo/todo_i18n.py +++ b/script/todo/todo_i18n.py @@ -2260,6 +2260,10 @@ TRANSLATIONS = { "line": {"fr": "ligne", "en": "line"}, "free space": {"fr": "libre", "en": "free"}, "silent": {"fr": "silence", "en": "silent"}, + "no project yet, second try on the warm caches": { + "fr": "pas de projet encore ; seconde tentative sur les caches chauds", + "en": "no project yet, second try on the warm caches", + }, "already there, download skipped": { "fr": "déjà présent, téléchargement évité", "en": "already there, download skipped", diff --git a/test/test_qemu_desktop_tools.py b/test/test_qemu_desktop_tools.py index 230b0ec..889c0f4 100644 --- a/test/test_qemu_desktop_tools.py +++ b/test/test_qemu_desktop_tools.py @@ -180,14 +180,24 @@ class TestToolRemoteCommand(unittest.TestCase): script.index("PyCharm"), script.index("make install_os") ) - def test_the_install_owns_the_project_configuration(self): - """update_env_version.pycharm_update() lance déjà le script, et sait se - taire sans .idea. Doubler l'appel n'écrivait qu'une erreur dans le - journal d'une VM neuve.""" + def test_the_configuration_is_asked_for_because_the_install_was_too_early( + self, + ): + """Le contraire de ce que ce test exigeait avant, et pour une raison + mesurée : pycharm_update() teste « os.path.exists('.idea') » et se tait + quand le projet n'existe pas encore. Or il s'exécute PENDANT + l'installation, alors que PyCharm ne s'ouvrira qu'après. Personne ne + configurait donc le projet — « Missing ./.idea path » dans le journal + d'une VM neuve. On le demande maintenant explicitement, après + l'ouverture.""" script = self.todo._qemu_erplibre_remote_cmd( "develop", None, False, "gnome", "", "deb", ("pycharm",) ) - self.assertNotIn("pycharm_configuration", script) + self.assertIn("pycharm_configuration.py --init", script) + self.assertLess( + script.index("xvfb-run"), + script.index("pycharm_configuration.py"), + ) def test_a_failing_tool_never_masks_a_failing_install(self): """Le code de sortie doit rester celui de l'installation : c'est lui que @@ -640,6 +650,37 @@ class TestPycharmFirstOpen(unittest.TestCase): script.index("make install_os"), script.index("xvfb-run") ) + def test_the_configuration_uses_the_repo_venv(self): + """Le script importe xmltodict, qui vit dans .venv.erplibre. Appelé par + le python système — ce que faisait « make pycharm_configure » — il + s'arrête sur « No module named 'xmltodict' », mesuré sur la VM. + update_env_version.pycharm_update() l'appelle déjà avec le venv.""" + script = self.todo._qemu_erplibre_remote_cmd( + "develop", None, False, "gnome", "", "deb", ("pycharm",) + ) + self.assertIn( + "./.venv.erplibre/bin/python" + " ./script/ide/pycharm_configuration.py --init", + script, + ) + # « make pycharm_configure » reste cité dans le message d'aide — la + # cible est réparée, elle aussi — mais n'est plus ce qu'on EXÉCUTE. + self.assertNotIn("&& make pycharm_configure", script) + self.assertNotIn("; make pycharm_configure", script) + + def test_the_open_gets_a_second_chance(self): + """Mesuré sur deux VM : la première ouverture d'un dépôt neuf peut + n'écrire AUCUN .idea — son configurateur d'interpréteur plante + (« homeDir is null ») — là où la suivante l'écrit en 25 s.""" + self.assertIn("for attempt in 1 2", self.cmd) + self.assertIn('[ "$ok" = 1 ] && break', self.cmd) + + def test_both_attempts_keep_their_log(self): + """Tronquer à chaque tentative effacerait la trace de la première, la + seule qui porte la cause.""" + self.assertIn(": > /tmp/pycharm-first-run.log", self.cmd) + self.assertIn(">> /tmp/pycharm-first-run.log", self.cmd) + def test_the_configuration_is_asked_for_after_the_open(self): """L'installation est déjà passée quand le .idea naît : pycharm_update() n'avait rien à configurer, donc on le demande explicitement.""" @@ -658,9 +699,9 @@ class TestPycharmFirstOpen(unittest.TestCase): script = self.todo._qemu_erplibre_remote_cmd( "develop", None, False, "gnome", "", "deb", ("pycharm", "mobile") ) - self.assertIn("make pycharm_configure || true", script) + self.assertIn("pycharm_configuration.py --init || true", script) self.assertLess( - script.index("make pycharm_configure"), + script.index("pycharm_configuration.py"), script.index("ERPLibre mobile"), )