Merge branch 'develop'

- todo command sshfs and git path
- add mobile script run test
- fix todo upgrade get_odoo_version
This commit is contained in:
Mathieu Benoit 2026-03-29 14:51:25 -04:00
commit c4f49f1b97
5 changed files with 188 additions and 3 deletions

13
mobile/run_tests.sh Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
if [[ ! -d "./mobile/erplibre_home_mobile" ]]; then
echo "Please, run installation ./mobile/install_mobile_dev.sh before run this script ./mobile/run_tests.sh"
exit 1
fi
cd mobile/erplibre_home_mobile
npm install
npm test
cd -

View file

@ -56,6 +56,10 @@
{
"prompt_description_key": "Configure git local editor to vim",
"bash_command": "git config --global core.editor \"vim\""
},
{
"prompt_description_key": "Generate git patch to /tmp",
"bash_command": "PATCH=\"/tmp/patch_$(date +%Y%m%d_%H%M%S).patch\"; git -C \"$(pwd)\" diff HEAD > \"$PATCH\" && printf \"\\n✓ Patch created: %s\\n\\n=== Guide to apply the patch ===\\n Check compatibility : git apply --check %s\\n Apply (git) : git apply %s\\n Apply (patch) : patch -p1 < %s\\n Revert (git) : git apply -R %s\\n\" \"$PATCH\" \"$PATCH\" \"$PATCH\" \"$PATCH\" \"$PATCH\""
}
]
}

View file

@ -619,6 +619,7 @@ class TODO:
print(f"🤖 {t('Deploy ERPLibre to a local directory!')}")
choices = [
{"prompt_description": t("Clone ERPLibre locally (git clone)")},
{"prompt_description": t("Configure sshfs")},
]
help_info = self.fill_help_info(choices)
@ -629,6 +630,8 @@ class TODO:
return False
elif status == "1":
self._deploy_clone_erplibre()
elif status == "2":
self._configure_sshfs()
else:
print(t("Command not found !"))
@ -655,6 +658,110 @@ class TODO:
except Exception as e:
print(f"{t('Error cloning ERPLibre: ')}{e}")
def _configure_sshfs(self):
import getpass
import re
from datetime import datetime
print(f"\n{t('SSH address input method')}")
print(f"[1] {t('Manual entry')}")
print(f"[2] {t('From ~/.ssh/config')}")
choice = input(t("Your choice (1/2): ")).strip()
user = None
hostname = None
ssh_name = None
if choice == "2":
ssh_config_path = os.path.expanduser("~/.ssh/config")
hosts = []
if os.path.exists(ssh_config_path):
current_host = None
current_info = {}
with open(ssh_config_path) as f:
for line in f:
line = line.strip()
if line.lower().startswith("host "):
host_val = line.split(None, 1)[1].strip()
if host_val != "*":
if current_host:
hosts.append((current_host, current_info))
current_host = host_val
current_info = {}
elif current_host:
key = line.split(None, 1)
if len(key) == 2:
k = key[0].lower()
v = key[1].strip()
if k == "hostname":
current_info["hostname"] = v
elif k == "user":
current_info["user"] = v
if current_host:
hosts.append((current_host, current_info))
if not hosts:
print(t("No SSH hosts found in ~/.ssh/config"))
return
print()
for i, (host, info) in enumerate(hosts, 1):
hn = info.get("hostname", host)
u = info.get("user", "")
desc = host
if hn != host:
desc += f" ({hn})"
if u:
desc += f" [{u}]"
print(f"[{i}] {desc}")
sel = input(t("Select SSH host number: ")).strip()
try:
idx = int(sel) - 1
if idx < 0 or idx >= len(hosts):
print(t("Invalid selection!"))
return
except ValueError:
print(t("Invalid selection!"))
return
host_name, host_info = hosts[idx]
hostname = host_info.get("hostname", host_name)
user = host_info.get("user", getpass.getuser())
ssh_name = host_name
target = f"{host_name}:/"
else:
ssh_host = input(
t("SSH host (e.g.: user@192.168.1.100): ")
).strip()
if not ssh_host:
print(t("SSH host is required!"))
return
if "@" in ssh_host:
user, hostname = ssh_host.split("@", 1)
else:
hostname = ssh_host
user = getpass.getuser()
ssh_name = hostname
target = f"{user}@{hostname}:/"
safe_name = re.sub(r"[^a-zA-Z0-9_-]", "_", ssh_name)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
mount_point = f"/tmp/sshfs_{safe_name}_{timestamp}"
os.makedirs(mount_point, exist_ok=True)
cmd = f"sshfs {target} {mount_point}"
print(f"{t('Mounting sshfs on: ')}{mount_point}")
print(f"{t('Will execute:')} {cmd}")
try:
self.execute.exec_command_live(cmd, source_erplibre=False)
print(f"{t('Mounted on: ')}{mount_point}")
print(f"mount | grep sshfs")
print(f"{t('To unmount: ')}" f"fusermount -u {mount_point}")
print(f"nautilus {mount_point}/home/{user}")
except Exception as e:
print(f"{t('Error mounting sshfs: ')}{e}")
def prompt_execute_code(self):
print(f"🤖 {t('What do you need for development?')}")
# help_info = """Commande :

View file

@ -137,6 +137,62 @@ TRANSLATIONS = {
"fr": "Erreur lors du clonage d'ERPLibre : ",
"en": "Error cloning ERPLibre: ",
},
"Configure sshfs": {
"fr": "Configurer sshfs",
"en": "Configure sshfs",
},
"SSH address input method": {
"fr": "Méthode de saisie de l'adresse SSH",
"en": "SSH address input method",
},
"Manual entry": {
"fr": "Saisie manuelle",
"en": "Manual entry",
},
"From ~/.ssh/config": {
"fr": "Depuis ~/.ssh/config",
"en": "From ~/.ssh/config",
},
"Your choice (1/2): ": {
"fr": "Votre choix (1/2) : ",
"en": "Your choice (1/2): ",
},
"No SSH hosts found in ~/.ssh/config": {
"fr": "Aucun hôte SSH trouvé dans ~/.ssh/config",
"en": "No SSH hosts found in ~/.ssh/config",
},
"Select SSH host number: ": {
"fr": "Numéro de l'hôte SSH à sélectionner : ",
"en": "Select SSH host number: ",
},
"Invalid selection!": {
"fr": "Sélection invalide!",
"en": "Invalid selection!",
},
"SSH host (e.g.: user@192.168.1.100): ": {
"fr": "Hôte SSH (ex: user@192.168.1.100) : ",
"en": "SSH host (e.g.: user@192.168.1.100): ",
},
"SSH host is required!": {
"fr": "L'hôte SSH est requis!",
"en": "SSH host is required!",
},
"Mounting sshfs on: ": {
"fr": "Montage sshfs sur : ",
"en": "Mounting sshfs on: ",
},
"Mounted on: ": {
"fr": "Monté sur : ",
"en": "Mounted on: ",
},
"To unmount: ": {
"fr": "Pour démonter : ",
"en": "To unmount: ",
},
"Error mounting sshfs: ": {
"fr": "Erreur lors du montage sshfs : ",
"en": "Error mounting sshfs: ",
},
# RTK (Rust Token Killer)
"Manage RTK (Rust Token Killer) for token optimization!": {
"fr": "Gérer RTK (Rust Token Killer) pour optimiser les tokens!",
@ -617,6 +673,10 @@ TRANSLATIONS = {
"fr": "Configuration git local par vim",
"en": "Configure git local editor to vim",
},
"Generate git patch to /tmp": {
"fr": "Générer une patch git dans /tmp",
"en": "Generate git patch to /tmp",
},
"Git editor configured to vim successfully!": {
"fr": "Éditeur git configuré sur vim avec succès!",
"en": "Git editor configured to vim successfully!",

View file

@ -10,6 +10,7 @@ import shutil
import sys
import zipfile
from uuid import uuid4
from script.todo.version_manager import get_odoo_version
import click
import todo_file_browser
@ -530,7 +531,7 @@ class TodoUpgrade:
# print("What is your actual Odoo version?")
lst_version, lst_version_installed, odoo_installed_version = (
self.todo.get_odoo_version()
get_odoo_version()
)
lst_odoo_version = [
@ -1815,7 +1816,7 @@ class TodoUpgrade:
# Expect odoo_version like 12.0
lst_version, lst_version_installed, odoo_installed_version = (
self.todo.get_odoo_version()
get_odoo_version()
)
if odoo_installed_version != f"odoo{int_odoo_version}.0":
print(
@ -1838,7 +1839,7 @@ class TodoUpgrade:
# if os.path.exists(venv_oca_path):
# return
lst_version, lst_version_installed, odoo_installed_version = (
self.todo.get_odoo_version()
get_odoo_version()
)
extract_version = f"{next_version}.0"
dct_erplibre_info = [