[UPD] script Format

This commit is contained in:
Mathieu Benoit 2026-03-13 15:04:14 -04:00
parent bee6d50018
commit 36ae1d9beb
8 changed files with 171 additions and 227 deletions

View file

@ -96,9 +96,7 @@ def commit_by_directory():
run_git_command(f'cd "{config.path}" && git rm -r {directory}')
# Crée le commit
commit_message = (
f"[{mig_prefix_msg}] {directory}: Migration to {config.odoo_version}"
)
commit_message = f"[{mig_prefix_msg}] {directory}: Migration to {config.odoo_version}"
commit_result = run_git_command(
f'cd "{config.path}" && git commit -m "{commit_message}"'
)

View file

@ -10,28 +10,31 @@ def get_db_list_xmlrpc(odoo_url):
Retrieves the list of Odoo databases using the XML-RPC API.
"""
try:
common = xmlrpc.client.ServerProxy(f'{odoo_url}/xmlrpc/db')
common = xmlrpc.client.ServerProxy(f"{odoo_url}/xmlrpc/db")
db_list = common.list()
return db_list
except xmlrpc.client.Fault as e:
print(f"XML-RPC Error: {e.faultCode} - {e.faultString}", file=sys.stderr)
print(
f"XML-RPC Error: {e.faultCode} - {e.faultString}", file=sys.stderr
)
return []
except Exception as e:
print(f"Connection Error: {e}", file=sys.stderr)
return []
# --- CLI using Click ---
@click.command()
@click.option(
'--odoo-url',
default='http://localhost:8069',
help='URL of the Odoo server.',
show_default=True
"--odoo-url",
default="http://localhost:8069",
help="URL of the Odoo server.",
show_default=True,
)
@click.option(
'--raw',
"--raw",
is_flag=True,
help='Output one database per line, without extra formatting. Useful for scripting.'
help="Output one database per line, without extra formatting. Useful for scripting.",
)
def list_databases(odoo_url, raw=False):
"""
@ -56,5 +59,5 @@ def list_databases(odoo_url, raw=False):
# --- Script Execution ---
if __name__ == '__main__':
if __name__ == "__main__":
list_databases()

View file

@ -151,8 +151,7 @@ Use --production-ready for /srv/git (requires root).
type=int,
default=DEFAULT_JOBS,
help=(
"Parallel jobs for init/remote/push"
f" (default: {DEFAULT_JOBS})"
"Parallel jobs for init/remote/push" f" (default: {DEFAULT_JOBS})"
),
)
parser.add_argument(
@ -247,11 +246,7 @@ def get_erplibre_root_project(erplibre_root):
capture_output=True,
text=True,
)
revision = (
result.stdout.strip()
if result.returncode == 0
else "master"
)
revision = result.stdout.strip() if result.returncode == 0 else "master"
return {
"name": ERPLIBRE_REPO_NAME,
@ -278,19 +273,13 @@ async def _init_single_bare_repo(git_path, project, semaphore):
return "skipped"
_logger.info(f" Creating: {bare_path}")
_, err, rc = await _run_git(
"git", "init", "--bare", bare_path
)
_, err, rc = await _run_git("git", "init", "--bare", bare_path)
if rc != 0:
_logger.warning(
f" Init failed: {bare_path}: {err.strip()}"
)
_logger.warning(f" Init failed: {bare_path}: {err.strip()}")
return "error"
# Enable git daemon export
export_file = os.path.join(
bare_path, "git-daemon-export-ok"
)
export_file = os.path.join(bare_path, "git-daemon-export-ok")
open(export_file, "w").close()
# Allow pushing from shallow clones
@ -312,10 +301,7 @@ async def init_bare_repos(git_path, projects, jobs):
semaphore = asyncio.Semaphore(jobs)
results = await asyncio.gather(
*[
_init_single_bare_repo(git_path, p, semaphore)
for p in projects
]
*[_init_single_bare_repo(git_path, p, semaphore) for p in projects]
)
created = results.count("created")
@ -352,9 +338,7 @@ async def _add_single_remote(
):
"""Add or update remote for a single repo (async)."""
async with semaphore:
repo_path = os.path.join(
erplibre_root, project["path"]
)
repo_path = os.path.join(erplibre_root, project["path"])
if not os.path.isdir(repo_path):
_logger.warning(f" Not found: {repo_path}")
return "error"
@ -368,9 +352,7 @@ async def _add_single_remote(
)
# Check if remote already exists
stdout, _, _ = await _run_git(
"git", "-C", repo_path, "remote"
)
stdout, _, _ = await _run_git("git", "-C", repo_path, "remote")
existing_remotes = stdout.strip().split("\n")
if remote_name in existing_remotes:
@ -403,8 +385,7 @@ async def _add_single_remote(
)
if rc != 0:
_logger.warning(
f" add failed for"
f" {project['path']}: {err.strip()}"
f" add failed for" f" {project['path']}: {err.strip()}"
)
return "error"
_logger.info(f" Added: {project['path']}")
@ -447,10 +428,7 @@ async def add_remotes(
added = results.count("added")
updated = results.count("updated")
errors = results.count("error")
print(
f"Remotes: {added} added, {updated} updated,"
f" {errors} errors"
)
print(f"Remotes: {added} added, {updated} updated," f" {errors} errors")
# --- Async workers for push ---
@ -458,9 +436,7 @@ async def add_remotes(
async def _is_detached_head(repo_path):
"""Check if a repo is in detached HEAD state."""
_, _, rc = await _run_git(
"git", "-C", repo_path, "symbolic-ref", "HEAD"
)
_, _, rc = await _run_git("git", "-C", repo_path, "symbolic-ref", "HEAD")
return rc != 0
@ -471,9 +447,7 @@ async def _checkout_manifest_branch(repo_path, revision):
on the exact commit. We create/checkout a local branch
matching the manifest revision so git push works.
"""
branch = (
revision.split("/")[-1] if "/" in revision else revision
)
branch = revision.split("/")[-1] if "/" in revision else revision
# Check if local branch already exists
_, _, rc = await _run_git(
@ -485,9 +459,7 @@ async def _checkout_manifest_branch(repo_path, revision):
f"refs/heads/{branch}",
)
if rc == 0:
await _run_git(
"git", "-C", repo_path, "checkout", branch
)
await _run_git("git", "-C", repo_path, "checkout", branch)
else:
await _run_git(
"git",
@ -514,9 +486,7 @@ async def _update_bare_head(git_path, project):
revision = project.get("revision", "")
if not revision:
return
branch = (
revision.split("/")[-1] if "/" in revision else revision
)
branch = revision.split("/")[-1] if "/" in revision else revision
await _run_git(
"git",
"-C",
@ -529,20 +499,10 @@ async def _update_bare_head(git_path, project):
async def _try_unshallow(repo_path, project, remote_name):
"""Try to unshallow a repo by fetching full history."""
shallow_file = os.path.join(
repo_path, ".git", "shallow"
)
_logger.info(
f" Unshallowing {project['path']}..."
)
stdout, _, _ = await _run_git(
"git", "-C", repo_path, "remote"
)
remotes = [
r
for r in stdout.strip().split("\n")
if r and r != remote_name
]
shallow_file = os.path.join(repo_path, ".git", "shallow")
_logger.info(f" Unshallowing {project['path']}...")
stdout, _, _ = await _run_git("git", "-C", repo_path, "remote")
remotes = [r for r in stdout.strip().split("\n") if r and r != remote_name]
manifest_remote = project.get("remote", "")
if manifest_remote in remotes:
remotes.remove(manifest_remote)
@ -562,9 +522,7 @@ async def _try_unshallow(repo_path, project, remote_name):
except asyncio.TimeoutError:
continue
if not os.path.exists(shallow_file):
_logger.info(
f" Unshallowed via {try_remote}"
)
_logger.info(f" Unshallowed via {try_remote}")
return
if os.path.exists(shallow_file):
_logger.warning(
@ -585,30 +543,22 @@ async def _push_single_repo(
):
"""Push a single repo to local remote (async)."""
async with semaphore:
repo_path = os.path.join(
erplibre_root, project["path"]
)
repo_path = os.path.join(erplibre_root, project["path"])
if not os.path.isdir(repo_path):
_logger.warning(f" Not found: {repo_path}")
return "error", False
# Handle shallow repos
shallow_file = os.path.join(
repo_path, ".git", "shallow"
)
shallow_file = os.path.join(repo_path, ".git", "shallow")
if os.path.exists(shallow_file):
if unshallow:
await _try_unshallow(
repo_path, project, remote_name
)
await _try_unshallow(repo_path, project, remote_name)
else:
# Enable shallow push on bare repo
repo_name = project["name"]
if not repo_name.endswith(".git"):
repo_name += ".git"
bare_path = os.path.join(
git_path, repo_name
)
bare_path = os.path.join(git_path, repo_name)
if os.path.isdir(bare_path):
await _run_git(
"git",
@ -618,19 +568,14 @@ async def _push_single_repo(
"receive.shallowUpdate",
"true",
)
_logger.info(
f" Shallow push for"
f" {project['path']}"
)
_logger.info(f" Shallow push for" f" {project['path']}")
# Handle detached HEAD: checkout manifest branch
did_checkout = False
if await _is_detached_head(repo_path):
revision = project.get("revision", "")
if revision:
branch = await _checkout_manifest_branch(
repo_path, revision
)
branch = await _checkout_manifest_branch(repo_path, revision)
_logger.info(
f" Checkout {branch} for"
f" {project['path']}"
@ -663,9 +608,7 @@ async def _push_single_repo(
"push",
remote_name,
]
_, err, rc = await _run_git(
*cmd, timeout=120
)
_, err, rc = await _run_git(*cmd, timeout=120)
if rc != 0:
_logger.warning(
f" Push failed for"
@ -675,14 +618,10 @@ async def _push_single_repo(
return "error", did_checkout
else:
await _update_bare_head(git_path, project)
_logger.info(
f" Pushed: {project['path']}"
)
_logger.info(f" Pushed: {project['path']}")
return "pushed", did_checkout
except asyncio.TimeoutError:
_logger.warning(
f" Timeout pushing {project['path']}"
)
_logger.warning(f" Timeout pushing {project['path']}")
return "error", did_checkout
@ -744,8 +683,7 @@ def print_clone_commands(git_path, projects, port):
if clone_path == ".":
clone_path = "erplibre"
lines.append(
f" git clone {base_url}/{repo_name}"
f" {clone_path}"
f" git clone {base_url}/{repo_name}" f" {clone_path}"
)
lines.sort()
for line in lines:

View file

@ -26,17 +26,10 @@ def get_pull_request_repo(
parsed_url = parse(upstream_url)
status, user = gh.user.get()
user_name = (
user["login"] if not organization_name else organization_name
)
status, lst_pull = (
gh.repos[user_name][parsed_url.repo].pulls.get()
)
user_name = user["login"] if not organization_name else organization_name
status, lst_pull = gh.repos[user_name][parsed_url.repo].pulls.get()
if type(lst_pull) is dict:
print(
f"For url {upstream_url},"
f" got {lst_pull.get('message')}"
)
print(f"For url {upstream_url}," f" got {lst_pull.get('message')}")
return False
else:
for pull in lst_pull:
@ -53,26 +46,21 @@ def fork_repo(
parsed_url = parse(upstream_url)
status, user = gh.user.get()
user_name = (
user["login"] if not organization_name else organization_name
)
status, forked_repo = (
gh.repos[user_name][parsed_url.repo].get()
)
user_name = user["login"] if not organization_name else organization_name
status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
if status == 404:
status, upstream_repo = (
gh.repos[parsed_url.owner][parsed_url.repo].get()
)
status, upstream_repo = gh.repos[parsed_url.owner][
parsed_url.repo
].get()
if status == 404:
print("Unable to find repo %s" % upstream_url)
exit(1)
args = {}
if organization_name:
args["organization"] = organization_name
status, forked_repo = (
gh.repos[parsed_url.owner][parsed_url.repo]
.forks.post(**args)
)
status, forked_repo = gh.repos[parsed_url.owner][
parsed_url.repo
].forks.post(**args)
if status == 404:
print(
f"{Fore.RED}Error{Style.RESET_ALL} when forking"
@ -82,23 +70,16 @@ def fork_repo(
else:
try:
print(
"Forked %s to %s"
% (upstream_url, forked_repo["html_url"])
"Forked %s to %s" % (upstream_url, forked_repo["html_url"])
)
except Exception as e:
print(e)
print(forked_repo)
print(upstream_url)
elif status == 202:
print(
"Forked repo %s already exists"
% forked_repo["full_name"]
)
print("Forked repo %s already exists" % forked_repo["full_name"])
elif status != 200:
print(
"Status not supported: %s - %s"
% (status, forked_repo)
)
print("Status not supported: %s - %s" % (status, forked_repo))
exit(1)
@ -110,9 +91,7 @@ def add_and_fetch_remote(
"""
try:
working_repo = Repo(repo_info.relative_path)
if repo_info.organization in [
a.name for a in working_repo.remotes
]:
if repo_info.organization in [a.name for a in working_repo.remotes]:
print(
f'Remote "{repo_info.organization}" already exist'
f" in {repo_info.relative_path}"
@ -122,8 +101,7 @@ def add_and_fetch_remote(
print(f"New repo {repo_info.relative_path}")
if not root_repo:
print(
"Missing git repository to root for repo"
f" {repo_info.path}"
"Missing git repository to root for repo" f" {repo_info.path}"
)
return
if branch_name:
@ -149,16 +127,14 @@ def add_and_fetch_remote(
# Add remote
upstream_remote = retry(
wait_exponential_multiplier=1000, stop_max_delay=15000
)(working_repo.create_remote)(
repo_info.organization, repo_info.url_https
)
)(working_repo.create_remote)(repo_info.organization, repo_info.url_https)
print(
'Remote "%s" created for %s'
% (repo_info.organization, repo_info.url_https)
)
# Fetch the remote
retry(
wait_exponential_multiplier=1000, stop_max_delay=15000
)(upstream_remote.fetch)()
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch
)()
print('Remote "%s" fetched' % repo_info.organization)

View file

@ -26,7 +26,9 @@ _logger = logging.getLogger(__name__)
PROJECT_NAME = os.path.basename(os.getcwd())
IDEA_PATH = "./.idea"
DEFAULT_ODOO_BIN = "./odoo/odoo-bin" # Need this to replace static configuration
DEFAULT_ODOO_BIN = (
"./odoo/odoo-bin" # Need this to replace static configuration
)
IDEA_MISC = os.path.join(IDEA_PATH, "misc.xml")
IDEA_WORKSPACE = os.path.join(IDEA_PATH, "workspace.xml")
VCS_WORKSPACE = os.path.join(IDEA_PATH, "vcs.xml")

View file

@ -2,7 +2,9 @@
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
installed_modules = env["ir.module.module"].search([('state', '=', 'installed')])
installed_modules = env["ir.module.module"].search(
[("state", "=", "installed")]
)
print("Installed modules:")

View file

@ -10,18 +10,20 @@ print("Running a script in the Odoo shell!")
# ERROR: insert or update on table "discuss_channel_member" violates foreign key constraint "discuss_channel_member_channel_id_fkey"
# DÉTAIL : Key (channel_id)=(3) is not present in table "discuss_channel".
env.cr.execute("""
env.cr.execute(
"""
ALTER TABLE discuss_channel
DROP CONSTRAINT discuss_channel_channel_type_not_null;
""")
"""
)
env.cr.commit()
#env.cr.execute("SELECT to_regclass('public.discuss_channel');")
#print("table:", env.cr.fetchone())
# env.cr.execute("SELECT to_regclass('public.discuss_channel');")
# print("table:", env.cr.fetchone())
#print(
# print(
# "model discuss.channel:",
# env["ir.model"].search([("model", "=", "discuss.channel")]),
#)
# )
print("End fix migration with update mail postgresql 17 to postgresql 18.")

View file

@ -393,7 +393,9 @@ class TODO:
odoo_version_input = ""
while odoo_version_input not in install_commands:
if odoo_version_input:
print(f"{t('Error, cannot understand value')} '{odoo_version_input}'")
print(
f"{t('Error, cannot understand value')} '{odoo_version_input}'"
)
str_input_dyn_odoo_version = (
f"💬 {t('Choose a version:')}\n\t"
+ "\n\t".join([a[1] for a in install_commands.values()])
@ -417,7 +419,9 @@ class TODO:
cmd_intern, shell=True, executable="/bin/bash", check=True
)
except subprocess.CalledProcessError as e:
print(f"{t('The Bash script failed with return code')} {e.returncode}.")
print(
f"{t('The Bash script failed with return code')} {e.returncode}."
)
print("Wait after installation and open projects by terminal.")
print("make open_terminal")
self.restart_script(str(e))
@ -464,9 +468,7 @@ class TODO:
bash_command = instance.get("bash_command")
if bash_command:
print(f"{t('Will execute:')} {bash_command}")
self.execute.exec_command_live(
bash_command, source_erplibre=False
)
self.execute.exec_command_live(bash_command, source_erplibre=False)
command = instance.get("Command:")
if command:
@ -525,7 +527,9 @@ class TODO:
int_cmd = int(status)
if 1 < int_cmd <= init_len:
cmd_no_found = False
status = click.confirm(t("Do you want a new instance?"))
status = click.confirm(
t("Do you want a new instance?")
)
instance = choices[int_cmd - 1]
self.execute_from_configuration(
instance,
@ -612,15 +616,9 @@ class TODO:
print(t("Command not found !"))
def prompt_execute_deploy(self):
print(
f"🤖 {t('Deploy ERPLibre to a local directory!')}"
)
print(f"🤖 {t('Deploy ERPLibre to a local directory!')}")
choices = [
{
"prompt_description": t(
"Clone ERPLibre locally (git clone)"
)
},
{"prompt_description": t("Clone ERPLibre locally (git clone)")},
]
help_info = self.fill_help_info(choices)
@ -637,16 +635,12 @@ class TODO:
def _deploy_clone_erplibre(self):
default_path = os.path.expanduser("~/erplibre")
target_path = (
input(
t("Target directory path (default: ~/erplibre): ")
).strip()
input(t("Target directory path (default: ~/erplibre): ")).strip()
or default_path
)
target_path = os.path.expanduser(target_path)
if os.path.exists(target_path):
print(
f"{t('Directory already exists: ')}{target_path}"
)
print(f"{t('Directory already exists: ')}{target_path}")
return
print(t("Cloning ERPLibre..."))
cmd = (
@ -656,13 +650,8 @@ class TODO:
)
print(f"{t('Will execute:')} {cmd}")
try:
self.execute.exec_command_live(
cmd, source_erplibre=False
)
print(
f"{t('ERPLibre cloned successfully to: ')}"
f"{target_path}"
)
self.execute.exec_command_live(cmd, source_erplibre=False)
print(f"{t('ERPLibre cloned successfully to: ')}" f"{target_path}")
except Exception as e:
print(f"{t('Error cloning ERPLibre: ')}{e}")
@ -762,18 +751,19 @@ class TODO:
def _git_add_remote(self):
remote_name = (
input(t("Remote name (default: localhost): ")).strip() or "localhost"
input(t("Remote name (default: localhost): ")).strip()
or "localhost"
)
remote_url = input(t("Repository address (e.g.: git://192.168.1.100/my-repo.git): ")).strip()
remote_url = input(
t("Repository address (e.g.: git://192.168.1.100/my-repo.git): ")
).strip()
if not remote_url:
print(t("Repository address is required!"))
return
cmd = f"git remote add {remote_name} {remote_url}"
print(f"{t('Will execute:')} {cmd}")
try:
self.execute.exec_command_live(
cmd, source_erplibre=False
)
self.execute.exec_command_live(cmd, source_erplibre=False)
print(t("Remote added successfully!"))
except Exception as e:
print(f"{t('Error adding remote: ')}{e}")
@ -781,8 +771,16 @@ class TODO:
def prompt_execute_git_local_server(self):
print(f"🤖 {t('Manage local git repository server!')}")
choices = [
{"prompt_description": t("Deploy a local git server (~/.git-server)")},
{"prompt_description": t("Deploy a production git server (/srv/git, root required)")},
{
"prompt_description": t(
"Deploy a local git server (~/.git-server)"
)
},
{
"prompt_description": t(
"Deploy a production git server (/srv/git, root required)"
)
},
]
help_info = self.fill_help_info(choices)
@ -806,7 +804,11 @@ class TODO:
)
print(f"🤖 {mode}")
choices = [
{"prompt_description": t("Run all (init + remote + push + serve)")},
{
"prompt_description": t(
"Run all (init + remote + push + serve)"
)
},
{"prompt_description": t("Init - Create bare repos")},
{"prompt_description": t("Remote - Add local remotes")},
{"prompt_description": t("Push - Push to local server")},
@ -863,8 +865,16 @@ class TODO:
print(f"🤖 {t('AI assistant tools for development!')}")
choices = [
{"prompt_description": t("Configure Claude Code configurations")},
{"prompt_description": t("Add an automation with Claude in todo.py")},
{"prompt_description": t("RTK - CLI proxy to reduce LLM token consumption")},
{
"prompt_description": t(
"Add an automation with Claude in todo.py"
)
},
{
"prompt_description": t(
"RTK - CLI proxy to reduce LLM token consumption"
)
},
]
help_info = self.fill_help_info(choices)
@ -891,11 +901,7 @@ class TODO:
"Todo Add Command - Add a command to todo.py menu"
)
},
{
"prompt_description": t(
"Show installed custom commands"
)
},
{"prompt_description": t("Show installed custom commands")},
]
help_info = self.fill_help_info(choices)
@ -926,9 +932,7 @@ class TODO:
print(t("No custom commands found in ~/.claude/commands/"))
return
files = sorted(
f
for f in os.listdir(commands_dir)
if f.endswith(".md")
f for f in os.listdir(commands_dir) if f.endswith(".md")
)
if not files:
print(t("No custom commands found in ~/.claude/commands/"))
@ -944,10 +948,7 @@ class TODO:
name = f[:-3] # remove .md
print(f" /{name:<30} {date_str}")
print("-" * 50)
print(
f"{t('Total:')}"
f" {len(files)}"
)
print(f"{t('Total:')}" f" {len(files)}")
def _setup_claude_command(
self, command_name, template_filename, personalize=False
@ -996,14 +997,10 @@ class TODO:
print(f"{t('Error creating file: ')}{e}")
def _claude_add_automation(self):
description = input(
t("Description of the command to add: ")
).strip()
description = input(t("Description of the command to add: ")).strip()
if not description:
return
command = input(
t("Bash command to execute: ")
).strip()
command = input(t("Bash command to execute: ")).strip()
if not command:
return
section = (
@ -1013,9 +1010,7 @@ class TODO:
or "git"
)
section_key = f"{section}_from_makefile"
config_path = os.path.join(
os.path.dirname(__file__), "todo.json"
)
config_path = os.path.join(os.path.dirname(__file__), "todo.json")
try:
with open(config_path) as f:
config = json.load(f)
@ -1086,7 +1081,11 @@ class TODO:
def prompt_execute_database(self):
print(f"🤖 {t('Make changes to databases!')}")
choices = [
{"prompt_description": t("Download database to create backup (.zip)")},
{
"prompt_description": t(
"Download database to create backup (.zip)"
)
},
{"prompt_description": t("Restore from backup (.zip)")},
{"prompt_description": t("Create backup (.zip)")},
]
@ -1134,7 +1133,9 @@ class TODO:
print(t("Git daemon process killed."))
def prompt_execute_rtk(self):
print(f"🤖 {t('Manage RTK (Rust Token Killer) for token optimization!')}")
print(
f"🤖 {t('Manage RTK (Rust Token Killer) for token optimization!')}"
)
choices = [
{"prompt_description": t("Install RTK")},
{"prompt_description": t("Check RTK version")},
@ -1170,7 +1171,11 @@ class TODO:
choices = [
{"prompt_description": t("curl - Automatic install script")},
{"prompt_description": t("brew - Homebrew (macOS/Linux)")},
{"prompt_description": t("cargo - Build from source (Rust required)")},
{
"prompt_description": t(
"cargo - Build from source (Rust required)"
)
},
]
help_info = self.fill_help_info(choices)
status = click.prompt(help_info)
@ -1323,7 +1328,11 @@ class TODO:
def prompt_execute_security(self):
print(f"🤖 {t('Dependency security audit!')}")
choices = [
{"prompt_description": t("pip-audit - Check vulnerabilities on Python environments")},
{
"prompt_description": t(
"pip-audit - Check vulnerabilities on Python environments"
)
},
]
help_info = self.fill_help_info(choices)
@ -1368,12 +1377,16 @@ class TODO:
return
# Database name
db_name = input(t("Temporary database name (default: test_todo_tmp): ")).strip()
db_name = input(
t("Temporary database name (default: test_todo_tmp): ")
).strip()
if not db_name:
db_name = "test_todo_tmp"
# Extra modules
extra_modules = input(t("Extra modules to install (comma-separated, empty for none): ")).strip()
extra_modules = input(
t("Extra modules to install (comma-separated, empty for none): ")
).strip()
# Log level
log_level = input(t("Log level (default: test): ")).strip()
@ -1395,9 +1408,7 @@ class TODO:
)
# Step 2: Install modules
print(
f"\n--- {t('Installing modules')}: {modules_to_install} ---"
)
print(f"\n--- {t('Installing modules')}: {modules_to_install} ---")
cmd_install = (
f"./script/addons/install_addons.sh"
f" {db_name} {modules_to_install}"
@ -1433,12 +1444,16 @@ class TODO:
# Step 4: Cleanup
lang = get_lang()
keep_input = input(t("Keep the temporary database? (y/N): ")).strip().lower()
keep_input = (
input(t("Keep the temporary database? (y/N): ")).strip().lower()
)
keep = keep_input in (("o", "oui") if lang == "fr" else ("y", "yes"))
if keep:
print(f"{t('Database kept')}: {db_name}")
else:
print(f"\n--- {t('Cleaning up temporary database')} '{db_name}' ---")
print(
f"\n--- {t('Cleaning up temporary database')} '{db_name}' ---"
)
cmd_drop = f"./odoo_bin.sh db --drop --database {db_name}"
self.execute.exec_command_live(
cmd_drop,
@ -1460,7 +1475,9 @@ class TODO:
if status_code == 0:
print(f"\n{t('All unit tests passed')}")
else:
print(f"\n{t('Some unit tests failed, exit code')}: {status_code}")
print(
f"\n{t('Some unit tests failed, exit code')}: {status_code}"
)
def execute_pip_audit(self):
versions, installed_versions, odoo_installed_version = (
@ -1495,7 +1512,11 @@ class TODO:
}
if not environments:
print(t("No installed environment found. Install an Odoo version first."))
print(
t(
"No installed environment found. Install an Odoo version first."
)
)
return
# Show selection menu
@ -1508,7 +1529,9 @@ class TODO:
env_input = ""
while env_input not in environments and env_input != "0":
if env_input:
print(f"{t('Error, cannot understand value')}" f" '{env_input}'")
print(
f"{t('Error, cannot understand value')}" f" '{env_input}'"
)
env_input = input(str_input).strip()
if env_input == "0":