Merge branch 'develop'
- TODO support RobotLibre commands - Format all ignore zip and __pycache__ - TODO config better support private configuration
This commit is contained in:
commit
2400f4e6be
6 changed files with 120 additions and 46 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import Any, Dict, Literal, Mapping
|
||||||
|
|
||||||
CONFIG_FILE = "./script/todo/todo.json"
|
CONFIG_FILE = "./script/todo/todo.json"
|
||||||
CONFIG_OVERRIDE_FILE = "./private/todo/todo_override.json"
|
CONFIG_OVERRIDE_FILE = "./private/todo/todo_override.json"
|
||||||
|
|
@ -23,34 +24,74 @@ _logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ConfigFile:
|
class ConfigFile:
|
||||||
def get_config(self, lst_params):
|
def get_config(self, key_param: str):
|
||||||
# Open file
|
# Open file and update dct_data
|
||||||
config_file = CONFIG_FILE
|
dct_data_init = {}
|
||||||
if os.path.exists(CONFIG_OVERRIDE_FILE):
|
dct_data_second = {}
|
||||||
config_file = CONFIG_OVERRIDE_FILE
|
dct_data_final = {}
|
||||||
|
|
||||||
|
if os.path.exists(CONFIG_FILE):
|
||||||
|
with open(CONFIG_FILE) as cfg:
|
||||||
|
dct_data_init = json.load(cfg)
|
||||||
|
|
||||||
|
if os.path.exists(CONFIG_OVERRIDE_FILE):
|
||||||
|
with open(CONFIG_OVERRIDE_FILE) as cfg:
|
||||||
|
dct_data_second = json.load(cfg)
|
||||||
|
|
||||||
find_in_private = False
|
|
||||||
if os.path.exists(CONFIG_OVERRIDE_PRIVATE_FILE):
|
if os.path.exists(CONFIG_OVERRIDE_PRIVATE_FILE):
|
||||||
with open(CONFIG_OVERRIDE_PRIVATE_FILE) as cfg:
|
with open(CONFIG_OVERRIDE_PRIVATE_FILE) as cfg:
|
||||||
dct_data = json.load(cfg)
|
dct_data_final = json.load(cfg)
|
||||||
for param in lst_params:
|
|
||||||
if param in dct_data.keys():
|
|
||||||
find_in_private = True
|
|
||||||
dct_data = dct_data[param]
|
|
||||||
|
|
||||||
if not find_in_private:
|
dct_data_first_merge = self.deep_merge_with_lists(
|
||||||
with open(config_file) as cfg:
|
dct_data_init, dct_data_final, list_strategy="extend"
|
||||||
dct_data = json.load(cfg)
|
)
|
||||||
for param in lst_params:
|
dct_data = self.deep_merge_with_lists(
|
||||||
try:
|
dct_data_first_merge, dct_data_second, list_strategy="extend"
|
||||||
dct_data = dct_data[param]
|
)
|
||||||
except KeyError:
|
|
||||||
_logger.error(
|
return dct_data.get(key_param)
|
||||||
f"KeyError on file {config_file} with keys"
|
|
||||||
f" {lst_params}"
|
def get_config_value(self, lst_params: list):
|
||||||
)
|
dct_data = self.get_config(lst_params[0])
|
||||||
return {}
|
for param in lst_params[1:]:
|
||||||
|
if param in dct_data.keys():
|
||||||
|
find_in_private = True
|
||||||
|
dct_data = dct_data.get(param)
|
||||||
return dct_data
|
return dct_data
|
||||||
|
|
||||||
def get_logo_ascii_file_path(self):
|
def get_logo_ascii_file_path(self):
|
||||||
return LOGO_ASCII_FILE
|
return LOGO_ASCII_FILE
|
||||||
|
|
||||||
|
def deep_merge_with_lists(
|
||||||
|
self,
|
||||||
|
dest: Mapping[str, Any],
|
||||||
|
src: Mapping[str, Any],
|
||||||
|
list_strategy: Literal["replace", "extend"] = "replace",
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
result: Dict[str, Any] = {}
|
||||||
|
for k, v in dest.items():
|
||||||
|
result[k] = v.copy() if isinstance(v, dict) else v
|
||||||
|
|
||||||
|
for k, v in src.items():
|
||||||
|
if (
|
||||||
|
k in result
|
||||||
|
and isinstance(result[k], dict)
|
||||||
|
and isinstance(v, dict)
|
||||||
|
):
|
||||||
|
result[k] = self.deep_merge_with_lists(
|
||||||
|
result[k], v, list_strategy
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
k in result
|
||||||
|
and isinstance(result[k], list)
|
||||||
|
and isinstance(v, list)
|
||||||
|
and list_strategy == "extend"
|
||||||
|
):
|
||||||
|
# on étend : dest_list + src_list
|
||||||
|
result[k] = result[k] + v
|
||||||
|
elif k in result and isinstance(result[k], str):
|
||||||
|
if v:
|
||||||
|
result[k] = v
|
||||||
|
else:
|
||||||
|
result[k] = v
|
||||||
|
return result
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ def get_modified_files():
|
||||||
)
|
)
|
||||||
if has_space:
|
if has_space:
|
||||||
file_path = file_path_space
|
file_path = file_path_space
|
||||||
|
# Remove ignoring
|
||||||
|
if (
|
||||||
|
file_path.endswith(".zip")
|
||||||
|
or file_path.endswith(".tar.gz")
|
||||||
|
or file_path.endswith("__pycache__/")
|
||||||
|
):
|
||||||
|
continue
|
||||||
file_path = os.path.join(directory, file_path)
|
file_path = os.path.join(directory, file_path)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -397,7 +397,9 @@ class SeleniumLib(object):
|
||||||
return self.kdbx
|
return self.kdbx
|
||||||
print("Open KDBX")
|
print("Open KDBX")
|
||||||
# Open file
|
# Open file
|
||||||
chemin_fichier_kdbx = self.config_file.get_config(["kdbx", "path"])
|
chemin_fichier_kdbx = self.config_file.get_config_value(
|
||||||
|
["kdbx", "path"]
|
||||||
|
)
|
||||||
if not chemin_fichier_kdbx:
|
if not chemin_fichier_kdbx:
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
root.withdraw() # Hide the main window
|
root.withdraw() # Hide the main window
|
||||||
|
|
@ -409,7 +411,9 @@ class SeleniumLib(object):
|
||||||
# _logger.error(f"KDBX is not configured, please fill {CONFIG_FILE}")
|
# _logger.error(f"KDBX is not configured, please fill {CONFIG_FILE}")
|
||||||
return
|
return
|
||||||
|
|
||||||
mot_de_passe_kdbx = self.config_file.get_config(["kdbx", "password"])
|
mot_de_passe_kdbx = self.config_file.get_config_value(
|
||||||
|
["kdbx", "password"]
|
||||||
|
)
|
||||||
if not mot_de_passe_kdbx:
|
if not mot_de_passe_kdbx:
|
||||||
mot_de_passe_kdbx = getpass.getpass(
|
mot_de_passe_kdbx = getpass.getpass(
|
||||||
prompt="Entrez votre mot de passe : "
|
prompt="Entrez votre mot de passe : "
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
"prompt_description": "Test - Instance de base minimale",
|
"prompt_description": "Test - Instance de base minimale",
|
||||||
"makefile_cmd": "db_restore_erplibre_base_db_test",
|
"makefile_cmd": "db_restore_erplibre_base_db_test",
|
||||||
"database": "test"
|
"database": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_description": "Ouvrir RobotLibre \uD83E\uDD16 minimal",
|
||||||
|
"makefile_cmd": "robot_libre",
|
||||||
|
"database": "robotlibre"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_description": "Ouvrir RobotLibre \uD83E\uDD16 en activant la recherche",
|
||||||
|
"makefile_cmd": "robot_libre_all",
|
||||||
|
"database": "robotlibre"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"function": [
|
"function": [
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,9 @@ class TODO:
|
||||||
if self.kdbx:
|
if self.kdbx:
|
||||||
return self.kdbx
|
return self.kdbx
|
||||||
# Open file
|
# Open file
|
||||||
chemin_fichier_kdbx = self.config_file.get_config(["kdbx", "path"])
|
chemin_fichier_kdbx = self.config_file.get_config_value(
|
||||||
|
["kdbx", "path"]
|
||||||
|
)
|
||||||
if not chemin_fichier_kdbx:
|
if not chemin_fichier_kdbx:
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
root.withdraw() # Hide the main window
|
root.withdraw() # Hide the main window
|
||||||
|
|
@ -167,7 +169,9 @@ class TODO:
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
mot_de_passe_kdbx = self.config_file.get_config(["kdbx", "password"])
|
mot_de_passe_kdbx = self.config_file.get_config_value(
|
||||||
|
["kdbx", "password"]
|
||||||
|
)
|
||||||
if not mot_de_passe_kdbx:
|
if not mot_de_passe_kdbx:
|
||||||
mot_de_passe_kdbx = getpass.getpass(
|
mot_de_passe_kdbx = getpass.getpass(
|
||||||
prompt="Entrez votre mot de passe : "
|
prompt="Entrez votre mot de passe : "
|
||||||
|
|
@ -191,7 +195,7 @@ class TODO:
|
||||||
kp = self.get_kdbx()
|
kp = self.get_kdbx()
|
||||||
if not kp:
|
if not kp:
|
||||||
return
|
return
|
||||||
nom_configuration = self.config_file.get_config(
|
nom_configuration = self.config_file.get_config_value(
|
||||||
["kdbx_config", "openai", "kdbx_key"]
|
["kdbx_config", "openai", "kdbx_key"]
|
||||||
)
|
)
|
||||||
entry = kp.find_entries_by_title(nom_configuration, first=True)
|
entry = kp.find_entries_by_title(nom_configuration, first=True)
|
||||||
|
|
@ -209,7 +213,7 @@ class TODO:
|
||||||
def prompt_execute(self):
|
def prompt_execute(self):
|
||||||
help_info = """Commande :
|
help_info = """Commande :
|
||||||
[1] Run - Exécuter et installer une instance
|
[1] Run - Exécuter et installer une instance
|
||||||
[2] Exec - Automatisation - Démonstration des fonctions développées
|
[2] Automatisation - Démonstration des fonctions développées
|
||||||
[3] Mise à jour - Update all developed staging source code
|
[3] Mise à jour - Update all developed staging source code
|
||||||
[4] Code - Outil pour développeur
|
[4] Code - Outil pour développeur
|
||||||
[5] Doc - Recherche de documentation
|
[5] Doc - Recherche de documentation
|
||||||
|
|
@ -408,11 +412,16 @@ class TODO:
|
||||||
|
|
||||||
makefile_cmd = dct_instance.get("makefile_cmd")
|
makefile_cmd = dct_instance.get("makefile_cmd")
|
||||||
if makefile_cmd and not ignore_makefile:
|
if makefile_cmd and not ignore_makefile:
|
||||||
self.executer_commande_live(
|
status = self.executer_commande_live(
|
||||||
f"make {makefile_cmd}",
|
f"make {makefile_cmd}",
|
||||||
source_erplibre=False,
|
source_erplibre=False,
|
||||||
single_source_erplibre=True,
|
single_source_erplibre=True,
|
||||||
)
|
)
|
||||||
|
if status:
|
||||||
|
_logger.error(
|
||||||
|
f"Status {status} - exit execute_from_configuration"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if exec_run_db:
|
if exec_run_db:
|
||||||
db_name = dct_instance.get("database")
|
db_name = dct_instance.get("database")
|
||||||
|
|
@ -440,7 +449,7 @@ class TODO:
|
||||||
# TODO proposer le déploiement à distance
|
# TODO proposer le déploiement à distance
|
||||||
# TODO proposer l'exécution de docker
|
# TODO proposer l'exécution de docker
|
||||||
# TODO proposer la création de docker
|
# TODO proposer la création de docker
|
||||||
lst_instance = self.config_file.get_config(["instance"])
|
lst_instance = self.config_file.get_config("instance")
|
||||||
help_info = self.fill_help_info(lst_instance)
|
help_info = self.fill_help_info(lst_instance)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -469,7 +478,7 @@ class TODO:
|
||||||
print("Commande non trouvée 🤖!")
|
print("Commande non trouvée 🤖!")
|
||||||
|
|
||||||
def prompt_execute_fonction(self):
|
def prompt_execute_fonction(self):
|
||||||
lst_instance = self.config_file.get_config(["function"])
|
lst_instance = self.config_file.get_config("function")
|
||||||
help_info = self.fill_help_info(lst_instance)
|
help_info = self.fill_help_info(lst_instance)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -501,7 +510,7 @@ class TODO:
|
||||||
# TODO faire la mise à jour de ERPLibre
|
# TODO faire la mise à jour de ERPLibre
|
||||||
# TODO faire l'upgrade d'un odoo vers un autre
|
# TODO faire l'upgrade d'un odoo vers un autre
|
||||||
|
|
||||||
lst_instance = self.config_file.get_config(["update_from_makefile"])
|
lst_instance = self.config_file.get_config("update_from_makefile")
|
||||||
dct_upgrade_odoo_database = {
|
dct_upgrade_odoo_database = {
|
||||||
"prompt_description": "Upgrade Odoo - Migration Database",
|
"prompt_description": "Upgrade Odoo - Migration Database",
|
||||||
}
|
}
|
||||||
|
|
@ -549,7 +558,7 @@ class TODO:
|
||||||
# [0] Retour
|
# [0] Retour
|
||||||
# """
|
# """
|
||||||
|
|
||||||
lst_instance = self.config_file.get_config(["code_from_makefile"])
|
lst_instance = self.config_file.get_config("code_from_makefile")
|
||||||
dct_upgrade_odoo_database = {
|
dct_upgrade_odoo_database = {
|
||||||
"prompt_description": "Upgrade Module",
|
"prompt_description": "Upgrade Module",
|
||||||
}
|
}
|
||||||
|
|
@ -785,7 +794,9 @@ class TODO:
|
||||||
with open("./.erplibre-version") as f:
|
with open("./.erplibre-version") as f:
|
||||||
source_odoo = f.read()
|
source_odoo = f.read()
|
||||||
if not source_odoo:
|
if not source_odoo:
|
||||||
_logger.error(f"You cannot execute Odoo command if no version is installed. Command : {commande}")
|
_logger.error(
|
||||||
|
f"You cannot execute Odoo command if no version is installed. Command : {commande}"
|
||||||
|
)
|
||||||
return -1
|
return -1
|
||||||
commande = (
|
commande = (
|
||||||
f"source ./.venv.{source_odoo}/bin/activate && {commande}"
|
f"source ./.venv.{source_odoo}/bin/activate && {commande}"
|
||||||
|
|
|
||||||
|
|
@ -76,17 +76,18 @@ class TodoUpgrade:
|
||||||
def execute_module_upgrade(self):
|
def execute_module_upgrade(self):
|
||||||
print("Welcome to Odoo module upgrade processus with ERPLibre 🤖")
|
print("Welcome to Odoo module upgrade processus with ERPLibre 🤖")
|
||||||
|
|
||||||
with open(UPGRADE_DATABASE_CONFIG_LOG, "r") as f:
|
if os.path.exists(UPGRADE_DATABASE_CONFIG_LOG):
|
||||||
try:
|
with open(UPGRADE_DATABASE_CONFIG_LOG, "r") as f:
|
||||||
old_dct_progression = json.load(f)
|
try:
|
||||||
self.dct_progression = old_dct_progression
|
old_dct_progression = json.load(f)
|
||||||
self.lst_command_executed = old_dct_progression.get(
|
self.dct_progression = old_dct_progression
|
||||||
"command_executed"
|
self.lst_command_executed = old_dct_progression.get(
|
||||||
)
|
"command_executed"
|
||||||
except json.decoder.JSONDecodeError:
|
)
|
||||||
print(
|
except json.decoder.JSONDecodeError:
|
||||||
f'⚠️ The config file "{UPGRADE_DATABASE_CONFIG_LOG}" is invalid, ignore it.'
|
print(
|
||||||
)
|
f'⚠️ The config file "{UPGRADE_DATABASE_CONFIG_LOG}" is invalid, ignore it.'
|
||||||
|
)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"Migrate a directory repo to migrate all module, or select a directory module."
|
"Migrate a directory repo to migrate all module, or select a directory module."
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue