[UPD] script Format
This commit is contained in:
parent
bee6d50018
commit
36ae1d9beb
8 changed files with 171 additions and 227 deletions
|
|
@ -96,9 +96,7 @@ def commit_by_directory():
|
||||||
run_git_command(f'cd "{config.path}" && git rm -r {directory}')
|
run_git_command(f'cd "{config.path}" && git rm -r {directory}')
|
||||||
|
|
||||||
# Crée le commit
|
# Crée le commit
|
||||||
commit_message = (
|
commit_message = f"[{mig_prefix_msg}] {directory}: Migration to {config.odoo_version}"
|
||||||
f"[{mig_prefix_msg}] {directory}: Migration to {config.odoo_version}"
|
|
||||||
)
|
|
||||||
commit_result = run_git_command(
|
commit_result = run_git_command(
|
||||||
f'cd "{config.path}" && git commit -m "{commit_message}"'
|
f'cd "{config.path}" && git commit -m "{commit_message}"'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -10,28 +10,31 @@ def get_db_list_xmlrpc(odoo_url):
|
||||||
Retrieves the list of Odoo databases using the XML-RPC API.
|
Retrieves the list of Odoo databases using the XML-RPC API.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
common = xmlrpc.client.ServerProxy(f'{odoo_url}/xmlrpc/db')
|
common = xmlrpc.client.ServerProxy(f"{odoo_url}/xmlrpc/db")
|
||||||
db_list = common.list()
|
db_list = common.list()
|
||||||
return db_list
|
return db_list
|
||||||
except xmlrpc.client.Fault as e:
|
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 []
|
return []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Connection Error: {e}", file=sys.stderr)
|
print(f"Connection Error: {e}", file=sys.stderr)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# --- CLI using Click ---
|
# --- CLI using Click ---
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option(
|
@click.option(
|
||||||
'--odoo-url',
|
"--odoo-url",
|
||||||
default='http://localhost:8069',
|
default="http://localhost:8069",
|
||||||
help='URL of the Odoo server.',
|
help="URL of the Odoo server.",
|
||||||
show_default=True
|
show_default=True,
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'--raw',
|
"--raw",
|
||||||
is_flag=True,
|
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):
|
def list_databases(odoo_url, raw=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -56,5 +59,5 @@ def list_databases(odoo_url, raw=False):
|
||||||
|
|
||||||
|
|
||||||
# --- Script Execution ---
|
# --- Script Execution ---
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
list_databases()
|
list_databases()
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,7 @@ Use --production-ready for /srv/git (requires root).
|
||||||
type=int,
|
type=int,
|
||||||
default=DEFAULT_JOBS,
|
default=DEFAULT_JOBS,
|
||||||
help=(
|
help=(
|
||||||
"Parallel jobs for init/remote/push"
|
"Parallel jobs for init/remote/push" f" (default: {DEFAULT_JOBS})"
|
||||||
f" (default: {DEFAULT_JOBS})"
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
|
@ -247,11 +246,7 @@ def get_erplibre_root_project(erplibre_root):
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
revision = (
|
revision = result.stdout.strip() if result.returncode == 0 else "master"
|
||||||
result.stdout.strip()
|
|
||||||
if result.returncode == 0
|
|
||||||
else "master"
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"name": ERPLIBRE_REPO_NAME,
|
"name": ERPLIBRE_REPO_NAME,
|
||||||
|
|
@ -278,19 +273,13 @@ async def _init_single_bare_repo(git_path, project, semaphore):
|
||||||
return "skipped"
|
return "skipped"
|
||||||
|
|
||||||
_logger.info(f" Creating: {bare_path}")
|
_logger.info(f" Creating: {bare_path}")
|
||||||
_, err, rc = await _run_git(
|
_, err, rc = await _run_git("git", "init", "--bare", bare_path)
|
||||||
"git", "init", "--bare", bare_path
|
|
||||||
)
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
_logger.warning(
|
_logger.warning(f" Init failed: {bare_path}: {err.strip()}")
|
||||||
f" Init failed: {bare_path}: {err.strip()}"
|
|
||||||
)
|
|
||||||
return "error"
|
return "error"
|
||||||
|
|
||||||
# Enable git daemon export
|
# Enable git daemon export
|
||||||
export_file = os.path.join(
|
export_file = os.path.join(bare_path, "git-daemon-export-ok")
|
||||||
bare_path, "git-daemon-export-ok"
|
|
||||||
)
|
|
||||||
open(export_file, "w").close()
|
open(export_file, "w").close()
|
||||||
|
|
||||||
# Allow pushing from shallow clones
|
# Allow pushing from shallow clones
|
||||||
|
|
@ -312,10 +301,7 @@ async def init_bare_repos(git_path, projects, jobs):
|
||||||
semaphore = asyncio.Semaphore(jobs)
|
semaphore = asyncio.Semaphore(jobs)
|
||||||
|
|
||||||
results = await asyncio.gather(
|
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")
|
created = results.count("created")
|
||||||
|
|
@ -352,9 +338,7 @@ async def _add_single_remote(
|
||||||
):
|
):
|
||||||
"""Add or update remote for a single repo (async)."""
|
"""Add or update remote for a single repo (async)."""
|
||||||
async with semaphore:
|
async with semaphore:
|
||||||
repo_path = os.path.join(
|
repo_path = os.path.join(erplibre_root, project["path"])
|
||||||
erplibre_root, project["path"]
|
|
||||||
)
|
|
||||||
if not os.path.isdir(repo_path):
|
if not os.path.isdir(repo_path):
|
||||||
_logger.warning(f" Not found: {repo_path}")
|
_logger.warning(f" Not found: {repo_path}")
|
||||||
return "error"
|
return "error"
|
||||||
|
|
@ -368,9 +352,7 @@ async def _add_single_remote(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if remote already exists
|
# Check if remote already exists
|
||||||
stdout, _, _ = await _run_git(
|
stdout, _, _ = await _run_git("git", "-C", repo_path, "remote")
|
||||||
"git", "-C", repo_path, "remote"
|
|
||||||
)
|
|
||||||
existing_remotes = stdout.strip().split("\n")
|
existing_remotes = stdout.strip().split("\n")
|
||||||
|
|
||||||
if remote_name in existing_remotes:
|
if remote_name in existing_remotes:
|
||||||
|
|
@ -403,8 +385,7 @@ async def _add_single_remote(
|
||||||
)
|
)
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
_logger.warning(
|
_logger.warning(
|
||||||
f" add failed for"
|
f" add failed for" f" {project['path']}: {err.strip()}"
|
||||||
f" {project['path']}: {err.strip()}"
|
|
||||||
)
|
)
|
||||||
return "error"
|
return "error"
|
||||||
_logger.info(f" Added: {project['path']}")
|
_logger.info(f" Added: {project['path']}")
|
||||||
|
|
@ -447,10 +428,7 @@ async def add_remotes(
|
||||||
added = results.count("added")
|
added = results.count("added")
|
||||||
updated = results.count("updated")
|
updated = results.count("updated")
|
||||||
errors = results.count("error")
|
errors = results.count("error")
|
||||||
print(
|
print(f"Remotes: {added} added, {updated} updated," f" {errors} errors")
|
||||||
f"Remotes: {added} added, {updated} updated,"
|
|
||||||
f" {errors} errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# --- Async workers for push ---
|
# --- Async workers for push ---
|
||||||
|
|
@ -458,9 +436,7 @@ async def add_remotes(
|
||||||
|
|
||||||
async def _is_detached_head(repo_path):
|
async def _is_detached_head(repo_path):
|
||||||
"""Check if a repo is in detached HEAD state."""
|
"""Check if a repo is in detached HEAD state."""
|
||||||
_, _, rc = await _run_git(
|
_, _, rc = await _run_git("git", "-C", repo_path, "symbolic-ref", "HEAD")
|
||||||
"git", "-C", repo_path, "symbolic-ref", "HEAD"
|
|
||||||
)
|
|
||||||
return rc != 0
|
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
|
on the exact commit. We create/checkout a local branch
|
||||||
matching the manifest revision so git push works.
|
matching the manifest revision so git push works.
|
||||||
"""
|
"""
|
||||||
branch = (
|
branch = revision.split("/")[-1] if "/" in revision else revision
|
||||||
revision.split("/")[-1] if "/" in revision else revision
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if local branch already exists
|
# Check if local branch already exists
|
||||||
_, _, rc = await _run_git(
|
_, _, rc = await _run_git(
|
||||||
|
|
@ -485,9 +459,7 @@ async def _checkout_manifest_branch(repo_path, revision):
|
||||||
f"refs/heads/{branch}",
|
f"refs/heads/{branch}",
|
||||||
)
|
)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
await _run_git(
|
await _run_git("git", "-C", repo_path, "checkout", branch)
|
||||||
"git", "-C", repo_path, "checkout", branch
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await _run_git(
|
await _run_git(
|
||||||
"git",
|
"git",
|
||||||
|
|
@ -514,9 +486,7 @@ async def _update_bare_head(git_path, project):
|
||||||
revision = project.get("revision", "")
|
revision = project.get("revision", "")
|
||||||
if not revision:
|
if not revision:
|
||||||
return
|
return
|
||||||
branch = (
|
branch = revision.split("/")[-1] if "/" in revision else revision
|
||||||
revision.split("/")[-1] if "/" in revision else revision
|
|
||||||
)
|
|
||||||
await _run_git(
|
await _run_git(
|
||||||
"git",
|
"git",
|
||||||
"-C",
|
"-C",
|
||||||
|
|
@ -529,20 +499,10 @@ async def _update_bare_head(git_path, project):
|
||||||
|
|
||||||
async def _try_unshallow(repo_path, project, remote_name):
|
async def _try_unshallow(repo_path, project, remote_name):
|
||||||
"""Try to unshallow a repo by fetching full history."""
|
"""Try to unshallow a repo by fetching full history."""
|
||||||
shallow_file = os.path.join(
|
shallow_file = os.path.join(repo_path, ".git", "shallow")
|
||||||
repo_path, ".git", "shallow"
|
_logger.info(f" Unshallowing {project['path']}...")
|
||||||
)
|
stdout, _, _ = await _run_git("git", "-C", repo_path, "remote")
|
||||||
_logger.info(
|
remotes = [r for r in stdout.strip().split("\n") if r and r != remote_name]
|
||||||
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", "")
|
manifest_remote = project.get("remote", "")
|
||||||
if manifest_remote in remotes:
|
if manifest_remote in remotes:
|
||||||
remotes.remove(manifest_remote)
|
remotes.remove(manifest_remote)
|
||||||
|
|
@ -562,9 +522,7 @@ async def _try_unshallow(repo_path, project, remote_name):
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
continue
|
continue
|
||||||
if not os.path.exists(shallow_file):
|
if not os.path.exists(shallow_file):
|
||||||
_logger.info(
|
_logger.info(f" Unshallowed via {try_remote}")
|
||||||
f" Unshallowed via {try_remote}"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
if os.path.exists(shallow_file):
|
if os.path.exists(shallow_file):
|
||||||
_logger.warning(
|
_logger.warning(
|
||||||
|
|
@ -585,30 +543,22 @@ async def _push_single_repo(
|
||||||
):
|
):
|
||||||
"""Push a single repo to local remote (async)."""
|
"""Push a single repo to local remote (async)."""
|
||||||
async with semaphore:
|
async with semaphore:
|
||||||
repo_path = os.path.join(
|
repo_path = os.path.join(erplibre_root, project["path"])
|
||||||
erplibre_root, project["path"]
|
|
||||||
)
|
|
||||||
if not os.path.isdir(repo_path):
|
if not os.path.isdir(repo_path):
|
||||||
_logger.warning(f" Not found: {repo_path}")
|
_logger.warning(f" Not found: {repo_path}")
|
||||||
return "error", False
|
return "error", False
|
||||||
|
|
||||||
# Handle shallow repos
|
# Handle shallow repos
|
||||||
shallow_file = os.path.join(
|
shallow_file = os.path.join(repo_path, ".git", "shallow")
|
||||||
repo_path, ".git", "shallow"
|
|
||||||
)
|
|
||||||
if os.path.exists(shallow_file):
|
if os.path.exists(shallow_file):
|
||||||
if unshallow:
|
if unshallow:
|
||||||
await _try_unshallow(
|
await _try_unshallow(repo_path, project, remote_name)
|
||||||
repo_path, project, remote_name
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Enable shallow push on bare repo
|
# Enable shallow push on bare repo
|
||||||
repo_name = project["name"]
|
repo_name = project["name"]
|
||||||
if not repo_name.endswith(".git"):
|
if not repo_name.endswith(".git"):
|
||||||
repo_name += ".git"
|
repo_name += ".git"
|
||||||
bare_path = os.path.join(
|
bare_path = os.path.join(git_path, repo_name)
|
||||||
git_path, repo_name
|
|
||||||
)
|
|
||||||
if os.path.isdir(bare_path):
|
if os.path.isdir(bare_path):
|
||||||
await _run_git(
|
await _run_git(
|
||||||
"git",
|
"git",
|
||||||
|
|
@ -618,19 +568,14 @@ async def _push_single_repo(
|
||||||
"receive.shallowUpdate",
|
"receive.shallowUpdate",
|
||||||
"true",
|
"true",
|
||||||
)
|
)
|
||||||
_logger.info(
|
_logger.info(f" Shallow push for" f" {project['path']}")
|
||||||
f" Shallow push for"
|
|
||||||
f" {project['path']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Handle detached HEAD: checkout manifest branch
|
# Handle detached HEAD: checkout manifest branch
|
||||||
did_checkout = False
|
did_checkout = False
|
||||||
if await _is_detached_head(repo_path):
|
if await _is_detached_head(repo_path):
|
||||||
revision = project.get("revision", "")
|
revision = project.get("revision", "")
|
||||||
if revision:
|
if revision:
|
||||||
branch = await _checkout_manifest_branch(
|
branch = await _checkout_manifest_branch(repo_path, revision)
|
||||||
repo_path, revision
|
|
||||||
)
|
|
||||||
_logger.info(
|
_logger.info(
|
||||||
f" Checkout {branch} for"
|
f" Checkout {branch} for"
|
||||||
f" {project['path']}"
|
f" {project['path']}"
|
||||||
|
|
@ -663,9 +608,7 @@ async def _push_single_repo(
|
||||||
"push",
|
"push",
|
||||||
remote_name,
|
remote_name,
|
||||||
]
|
]
|
||||||
_, err, rc = await _run_git(
|
_, err, rc = await _run_git(*cmd, timeout=120)
|
||||||
*cmd, timeout=120
|
|
||||||
)
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
_logger.warning(
|
_logger.warning(
|
||||||
f" Push failed for"
|
f" Push failed for"
|
||||||
|
|
@ -675,14 +618,10 @@ async def _push_single_repo(
|
||||||
return "error", did_checkout
|
return "error", did_checkout
|
||||||
else:
|
else:
|
||||||
await _update_bare_head(git_path, project)
|
await _update_bare_head(git_path, project)
|
||||||
_logger.info(
|
_logger.info(f" Pushed: {project['path']}")
|
||||||
f" Pushed: {project['path']}"
|
|
||||||
)
|
|
||||||
return "pushed", did_checkout
|
return "pushed", did_checkout
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
_logger.warning(
|
_logger.warning(f" Timeout pushing {project['path']}")
|
||||||
f" Timeout pushing {project['path']}"
|
|
||||||
)
|
|
||||||
return "error", did_checkout
|
return "error", did_checkout
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -744,8 +683,7 @@ def print_clone_commands(git_path, projects, port):
|
||||||
if clone_path == ".":
|
if clone_path == ".":
|
||||||
clone_path = "erplibre"
|
clone_path = "erplibre"
|
||||||
lines.append(
|
lines.append(
|
||||||
f" git clone {base_url}/{repo_name}"
|
f" git clone {base_url}/{repo_name}" f" {clone_path}"
|
||||||
f" {clone_path}"
|
|
||||||
)
|
)
|
||||||
lines.sort()
|
lines.sort()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,10 @@ def get_pull_request_repo(
|
||||||
parsed_url = parse(upstream_url)
|
parsed_url = parse(upstream_url)
|
||||||
|
|
||||||
status, user = gh.user.get()
|
status, user = gh.user.get()
|
||||||
user_name = (
|
user_name = user["login"] if not organization_name else organization_name
|
||||||
user["login"] if not organization_name else organization_name
|
status, lst_pull = gh.repos[user_name][parsed_url.repo].pulls.get()
|
||||||
)
|
|
||||||
status, lst_pull = (
|
|
||||||
gh.repos[user_name][parsed_url.repo].pulls.get()
|
|
||||||
)
|
|
||||||
if type(lst_pull) is dict:
|
if type(lst_pull) is dict:
|
||||||
print(
|
print(f"For url {upstream_url}," f" got {lst_pull.get('message')}")
|
||||||
f"For url {upstream_url},"
|
|
||||||
f" got {lst_pull.get('message')}"
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
for pull in lst_pull:
|
for pull in lst_pull:
|
||||||
|
|
@ -53,26 +46,21 @@ def fork_repo(
|
||||||
parsed_url = parse(upstream_url)
|
parsed_url = parse(upstream_url)
|
||||||
|
|
||||||
status, user = gh.user.get()
|
status, user = gh.user.get()
|
||||||
user_name = (
|
user_name = user["login"] if not organization_name else organization_name
|
||||||
user["login"] if not organization_name else organization_name
|
status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
|
||||||
)
|
|
||||||
status, forked_repo = (
|
|
||||||
gh.repos[user_name][parsed_url.repo].get()
|
|
||||||
)
|
|
||||||
if status == 404:
|
if status == 404:
|
||||||
status, upstream_repo = (
|
status, upstream_repo = gh.repos[parsed_url.owner][
|
||||||
gh.repos[parsed_url.owner][parsed_url.repo].get()
|
parsed_url.repo
|
||||||
)
|
].get()
|
||||||
if status == 404:
|
if status == 404:
|
||||||
print("Unable to find repo %s" % upstream_url)
|
print("Unable to find repo %s" % upstream_url)
|
||||||
exit(1)
|
exit(1)
|
||||||
args = {}
|
args = {}
|
||||||
if organization_name:
|
if organization_name:
|
||||||
args["organization"] = organization_name
|
args["organization"] = organization_name
|
||||||
status, forked_repo = (
|
status, forked_repo = gh.repos[parsed_url.owner][
|
||||||
gh.repos[parsed_url.owner][parsed_url.repo]
|
parsed_url.repo
|
||||||
.forks.post(**args)
|
].forks.post(**args)
|
||||||
)
|
|
||||||
if status == 404:
|
if status == 404:
|
||||||
print(
|
print(
|
||||||
f"{Fore.RED}Error{Style.RESET_ALL} when forking"
|
f"{Fore.RED}Error{Style.RESET_ALL} when forking"
|
||||||
|
|
@ -82,23 +70,16 @@ def fork_repo(
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
print(
|
print(
|
||||||
"Forked %s to %s"
|
"Forked %s to %s" % (upstream_url, forked_repo["html_url"])
|
||||||
% (upstream_url, forked_repo["html_url"])
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
print(forked_repo)
|
print(forked_repo)
|
||||||
print(upstream_url)
|
print(upstream_url)
|
||||||
elif status == 202:
|
elif status == 202:
|
||||||
print(
|
print("Forked repo %s already exists" % forked_repo["full_name"])
|
||||||
"Forked repo %s already exists"
|
|
||||||
% forked_repo["full_name"]
|
|
||||||
)
|
|
||||||
elif status != 200:
|
elif status != 200:
|
||||||
print(
|
print("Status not supported: %s - %s" % (status, forked_repo))
|
||||||
"Status not supported: %s - %s"
|
|
||||||
% (status, forked_repo)
|
|
||||||
)
|
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -110,9 +91,7 @@ def add_and_fetch_remote(
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
working_repo = Repo(repo_info.relative_path)
|
working_repo = Repo(repo_info.relative_path)
|
||||||
if repo_info.organization in [
|
if repo_info.organization in [a.name for a in working_repo.remotes]:
|
||||||
a.name for a in working_repo.remotes
|
|
||||||
]:
|
|
||||||
print(
|
print(
|
||||||
f'Remote "{repo_info.organization}" already exist'
|
f'Remote "{repo_info.organization}" already exist'
|
||||||
f" in {repo_info.relative_path}"
|
f" in {repo_info.relative_path}"
|
||||||
|
|
@ -122,8 +101,7 @@ def add_and_fetch_remote(
|
||||||
print(f"New repo {repo_info.relative_path}")
|
print(f"New repo {repo_info.relative_path}")
|
||||||
if not root_repo:
|
if not root_repo:
|
||||||
print(
|
print(
|
||||||
"Missing git repository to root for repo"
|
"Missing git repository to root for repo" f" {repo_info.path}"
|
||||||
f" {repo_info.path}"
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if branch_name:
|
if branch_name:
|
||||||
|
|
@ -149,16 +127,14 @@ def add_and_fetch_remote(
|
||||||
# Add remote
|
# Add remote
|
||||||
upstream_remote = retry(
|
upstream_remote = retry(
|
||||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||||
)(working_repo.create_remote)(
|
)(working_repo.create_remote)(repo_info.organization, repo_info.url_https)
|
||||||
repo_info.organization, repo_info.url_https
|
|
||||||
)
|
|
||||||
print(
|
print(
|
||||||
'Remote "%s" created for %s'
|
'Remote "%s" created for %s'
|
||||||
% (repo_info.organization, repo_info.url_https)
|
% (repo_info.organization, repo_info.url_https)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fetch the remote
|
# Fetch the remote
|
||||||
retry(
|
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
upstream_remote.fetch
|
||||||
)(upstream_remote.fetch)()
|
)()
|
||||||
print('Remote "%s" fetched' % repo_info.organization)
|
print('Remote "%s" fetched' % repo_info.organization)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ _logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
PROJECT_NAME = os.path.basename(os.getcwd())
|
PROJECT_NAME = os.path.basename(os.getcwd())
|
||||||
IDEA_PATH = "./.idea"
|
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_MISC = os.path.join(IDEA_PATH, "misc.xml")
|
||||||
IDEA_WORKSPACE = os.path.join(IDEA_PATH, "workspace.xml")
|
IDEA_WORKSPACE = os.path.join(IDEA_PATH, "workspace.xml")
|
||||||
VCS_WORKSPACE = os.path.join(IDEA_PATH, "vcs.xml")
|
VCS_WORKSPACE = os.path.join(IDEA_PATH, "vcs.xml")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
|
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
# 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:")
|
print("Installed modules:")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
# 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".
|
# DÉTAIL : Key (channel_id)=(3) is not present in table "discuss_channel".
|
||||||
|
|
||||||
env.cr.execute("""
|
env.cr.execute(
|
||||||
|
"""
|
||||||
ALTER TABLE discuss_channel
|
ALTER TABLE discuss_channel
|
||||||
DROP CONSTRAINT discuss_channel_channel_type_not_null;
|
DROP CONSTRAINT discuss_channel_channel_type_not_null;
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
env.cr.commit()
|
env.cr.commit()
|
||||||
|
|
||||||
#env.cr.execute("SELECT to_regclass('public.discuss_channel');")
|
# env.cr.execute("SELECT to_regclass('public.discuss_channel');")
|
||||||
#print("table:", env.cr.fetchone())
|
# print("table:", env.cr.fetchone())
|
||||||
|
|
||||||
#print(
|
# print(
|
||||||
# "model discuss.channel:",
|
# "model discuss.channel:",
|
||||||
# env["ir.model"].search([("model", "=", "discuss.channel")]),
|
# env["ir.model"].search([("model", "=", "discuss.channel")]),
|
||||||
#)
|
# )
|
||||||
|
|
||||||
print("End fix migration with update mail postgresql 17 to postgresql 18.")
|
print("End fix migration with update mail postgresql 17 to postgresql 18.")
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,9 @@ class TODO:
|
||||||
odoo_version_input = ""
|
odoo_version_input = ""
|
||||||
while odoo_version_input not in install_commands:
|
while odoo_version_input not in install_commands:
|
||||||
if odoo_version_input:
|
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 = (
|
str_input_dyn_odoo_version = (
|
||||||
f"💬 {t('Choose a version:')}\n\t"
|
f"💬 {t('Choose a version:')}\n\t"
|
||||||
+ "\n\t".join([a[1] for a in install_commands.values()])
|
+ "\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
|
cmd_intern, shell=True, executable="/bin/bash", check=True
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError as e:
|
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("Wait after installation and open projects by terminal.")
|
||||||
print("make open_terminal")
|
print("make open_terminal")
|
||||||
self.restart_script(str(e))
|
self.restart_script(str(e))
|
||||||
|
|
@ -464,9 +468,7 @@ class TODO:
|
||||||
bash_command = instance.get("bash_command")
|
bash_command = instance.get("bash_command")
|
||||||
if bash_command:
|
if bash_command:
|
||||||
print(f"{t('Will execute:')} {bash_command}")
|
print(f"{t('Will execute:')} {bash_command}")
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(bash_command, source_erplibre=False)
|
||||||
bash_command, source_erplibre=False
|
|
||||||
)
|
|
||||||
|
|
||||||
command = instance.get("Command:")
|
command = instance.get("Command:")
|
||||||
if command:
|
if command:
|
||||||
|
|
@ -525,7 +527,9 @@ class TODO:
|
||||||
int_cmd = int(status)
|
int_cmd = int(status)
|
||||||
if 1 < int_cmd <= init_len:
|
if 1 < int_cmd <= init_len:
|
||||||
cmd_no_found = False
|
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]
|
instance = choices[int_cmd - 1]
|
||||||
self.execute_from_configuration(
|
self.execute_from_configuration(
|
||||||
instance,
|
instance,
|
||||||
|
|
@ -612,15 +616,9 @@ class TODO:
|
||||||
print(t("Command not found !"))
|
print(t("Command not found !"))
|
||||||
|
|
||||||
def prompt_execute_deploy(self):
|
def prompt_execute_deploy(self):
|
||||||
print(
|
print(f"🤖 {t('Deploy ERPLibre to a local directory!')}")
|
||||||
f"🤖 {t('Deploy ERPLibre to a local directory!')}"
|
|
||||||
)
|
|
||||||
choices = [
|
choices = [
|
||||||
{
|
{"prompt_description": t("Clone ERPLibre locally (git clone)")},
|
||||||
"prompt_description": t(
|
|
||||||
"Clone ERPLibre locally (git clone)"
|
|
||||||
)
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
help_info = self.fill_help_info(choices)
|
help_info = self.fill_help_info(choices)
|
||||||
|
|
||||||
|
|
@ -637,16 +635,12 @@ class TODO:
|
||||||
def _deploy_clone_erplibre(self):
|
def _deploy_clone_erplibre(self):
|
||||||
default_path = os.path.expanduser("~/erplibre")
|
default_path = os.path.expanduser("~/erplibre")
|
||||||
target_path = (
|
target_path = (
|
||||||
input(
|
input(t("Target directory path (default: ~/erplibre): ")).strip()
|
||||||
t("Target directory path (default: ~/erplibre): ")
|
|
||||||
).strip()
|
|
||||||
or default_path
|
or default_path
|
||||||
)
|
)
|
||||||
target_path = os.path.expanduser(target_path)
|
target_path = os.path.expanduser(target_path)
|
||||||
if os.path.exists(target_path):
|
if os.path.exists(target_path):
|
||||||
print(
|
print(f"{t('Directory already exists: ')}{target_path}")
|
||||||
f"{t('Directory already exists: ')}{target_path}"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
print(t("Cloning ERPLibre..."))
|
print(t("Cloning ERPLibre..."))
|
||||||
cmd = (
|
cmd = (
|
||||||
|
|
@ -656,13 +650,8 @@ class TODO:
|
||||||
)
|
)
|
||||||
print(f"{t('Will execute:')} {cmd}")
|
print(f"{t('Will execute:')} {cmd}")
|
||||||
try:
|
try:
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||||
cmd, source_erplibre=False
|
print(f"{t('ERPLibre cloned successfully to: ')}" f"{target_path}")
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"{t('ERPLibre cloned successfully to: ')}"
|
|
||||||
f"{target_path}"
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{t('Error cloning ERPLibre: ')}{e}")
|
print(f"{t('Error cloning ERPLibre: ')}{e}")
|
||||||
|
|
||||||
|
|
@ -762,18 +751,19 @@ class TODO:
|
||||||
|
|
||||||
def _git_add_remote(self):
|
def _git_add_remote(self):
|
||||||
remote_name = (
|
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:
|
if not remote_url:
|
||||||
print(t("Repository address is required!"))
|
print(t("Repository address is required!"))
|
||||||
return
|
return
|
||||||
cmd = f"git remote add {remote_name} {remote_url}"
|
cmd = f"git remote add {remote_name} {remote_url}"
|
||||||
print(f"{t('Will execute:')} {cmd}")
|
print(f"{t('Will execute:')} {cmd}")
|
||||||
try:
|
try:
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||||
cmd, source_erplibre=False
|
|
||||||
)
|
|
||||||
print(t("Remote added successfully!"))
|
print(t("Remote added successfully!"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{t('Error adding remote: ')}{e}")
|
print(f"{t('Error adding remote: ')}{e}")
|
||||||
|
|
@ -781,8 +771,16 @@ class TODO:
|
||||||
def prompt_execute_git_local_server(self):
|
def prompt_execute_git_local_server(self):
|
||||||
print(f"🤖 {t('Manage local git repository server!')}")
|
print(f"🤖 {t('Manage local git repository server!')}")
|
||||||
choices = [
|
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)
|
help_info = self.fill_help_info(choices)
|
||||||
|
|
||||||
|
|
@ -806,7 +804,11 @@ class TODO:
|
||||||
)
|
)
|
||||||
print(f"🤖 {mode}")
|
print(f"🤖 {mode}")
|
||||||
choices = [
|
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("Init - Create bare repos")},
|
||||||
{"prompt_description": t("Remote - Add local remotes")},
|
{"prompt_description": t("Remote - Add local remotes")},
|
||||||
{"prompt_description": t("Push - Push to local server")},
|
{"prompt_description": t("Push - Push to local server")},
|
||||||
|
|
@ -863,8 +865,16 @@ class TODO:
|
||||||
print(f"🤖 {t('AI assistant tools for development!')}")
|
print(f"🤖 {t('AI assistant tools for development!')}")
|
||||||
choices = [
|
choices = [
|
||||||
{"prompt_description": t("Configure Claude Code configurations")},
|
{"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)
|
help_info = self.fill_help_info(choices)
|
||||||
|
|
||||||
|
|
@ -891,11 +901,7 @@ class TODO:
|
||||||
"Todo Add Command - Add a command to todo.py menu"
|
"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)
|
help_info = self.fill_help_info(choices)
|
||||||
|
|
||||||
|
|
@ -926,9 +932,7 @@ class TODO:
|
||||||
print(t("No custom commands found in ~/.claude/commands/"))
|
print(t("No custom commands found in ~/.claude/commands/"))
|
||||||
return
|
return
|
||||||
files = sorted(
|
files = sorted(
|
||||||
f
|
f for f in os.listdir(commands_dir) if f.endswith(".md")
|
||||||
for f in os.listdir(commands_dir)
|
|
||||||
if f.endswith(".md")
|
|
||||||
)
|
)
|
||||||
if not files:
|
if not files:
|
||||||
print(t("No custom commands found in ~/.claude/commands/"))
|
print(t("No custom commands found in ~/.claude/commands/"))
|
||||||
|
|
@ -944,10 +948,7 @@ class TODO:
|
||||||
name = f[:-3] # remove .md
|
name = f[:-3] # remove .md
|
||||||
print(f" /{name:<30} {date_str}")
|
print(f" /{name:<30} {date_str}")
|
||||||
print("-" * 50)
|
print("-" * 50)
|
||||||
print(
|
print(f"{t('Total:')}" f" {len(files)}")
|
||||||
f"{t('Total:')}"
|
|
||||||
f" {len(files)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _setup_claude_command(
|
def _setup_claude_command(
|
||||||
self, command_name, template_filename, personalize=False
|
self, command_name, template_filename, personalize=False
|
||||||
|
|
@ -996,14 +997,10 @@ class TODO:
|
||||||
print(f"{t('Error creating file: ')}{e}")
|
print(f"{t('Error creating file: ')}{e}")
|
||||||
|
|
||||||
def _claude_add_automation(self):
|
def _claude_add_automation(self):
|
||||||
description = input(
|
description = input(t("Description of the command to add: ")).strip()
|
||||||
t("Description of the command to add: ")
|
|
||||||
).strip()
|
|
||||||
if not description:
|
if not description:
|
||||||
return
|
return
|
||||||
command = input(
|
command = input(t("Bash command to execute: ")).strip()
|
||||||
t("Bash command to execute: ")
|
|
||||||
).strip()
|
|
||||||
if not command:
|
if not command:
|
||||||
return
|
return
|
||||||
section = (
|
section = (
|
||||||
|
|
@ -1013,9 +1010,7 @@ class TODO:
|
||||||
or "git"
|
or "git"
|
||||||
)
|
)
|
||||||
section_key = f"{section}_from_makefile"
|
section_key = f"{section}_from_makefile"
|
||||||
config_path = os.path.join(
|
config_path = os.path.join(os.path.dirname(__file__), "todo.json")
|
||||||
os.path.dirname(__file__), "todo.json"
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
with open(config_path) as f:
|
with open(config_path) as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|
@ -1086,7 +1081,11 @@ class TODO:
|
||||||
def prompt_execute_database(self):
|
def prompt_execute_database(self):
|
||||||
print(f"🤖 {t('Make changes to databases!')}")
|
print(f"🤖 {t('Make changes to databases!')}")
|
||||||
choices = [
|
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("Restore from backup (.zip)")},
|
||||||
{"prompt_description": t("Create backup (.zip)")},
|
{"prompt_description": t("Create backup (.zip)")},
|
||||||
]
|
]
|
||||||
|
|
@ -1134,7 +1133,9 @@ class TODO:
|
||||||
print(t("Git daemon process killed."))
|
print(t("Git daemon process killed."))
|
||||||
|
|
||||||
def prompt_execute_rtk(self):
|
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 = [
|
choices = [
|
||||||
{"prompt_description": t("Install RTK")},
|
{"prompt_description": t("Install RTK")},
|
||||||
{"prompt_description": t("Check RTK version")},
|
{"prompt_description": t("Check RTK version")},
|
||||||
|
|
@ -1170,7 +1171,11 @@ class TODO:
|
||||||
choices = [
|
choices = [
|
||||||
{"prompt_description": t("curl - Automatic install script")},
|
{"prompt_description": t("curl - Automatic install script")},
|
||||||
{"prompt_description": t("brew - Homebrew (macOS/Linux)")},
|
{"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)
|
help_info = self.fill_help_info(choices)
|
||||||
status = click.prompt(help_info)
|
status = click.prompt(help_info)
|
||||||
|
|
@ -1323,7 +1328,11 @@ class TODO:
|
||||||
def prompt_execute_security(self):
|
def prompt_execute_security(self):
|
||||||
print(f"🤖 {t('Dependency security audit!')}")
|
print(f"🤖 {t('Dependency security audit!')}")
|
||||||
choices = [
|
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)
|
help_info = self.fill_help_info(choices)
|
||||||
|
|
||||||
|
|
@ -1368,12 +1377,16 @@ class TODO:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Database name
|
# 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:
|
if not db_name:
|
||||||
db_name = "test_todo_tmp"
|
db_name = "test_todo_tmp"
|
||||||
|
|
||||||
# Extra modules
|
# 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
|
||||||
log_level = input(t("Log level (default: test): ")).strip()
|
log_level = input(t("Log level (default: test): ")).strip()
|
||||||
|
|
@ -1395,9 +1408,7 @@ class TODO:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Step 2: Install modules
|
# Step 2: Install modules
|
||||||
print(
|
print(f"\n--- {t('Installing modules')}: {modules_to_install} ---")
|
||||||
f"\n--- {t('Installing modules')}: {modules_to_install} ---"
|
|
||||||
)
|
|
||||||
cmd_install = (
|
cmd_install = (
|
||||||
f"./script/addons/install_addons.sh"
|
f"./script/addons/install_addons.sh"
|
||||||
f" {db_name} {modules_to_install}"
|
f" {db_name} {modules_to_install}"
|
||||||
|
|
@ -1433,12 +1444,16 @@ class TODO:
|
||||||
|
|
||||||
# Step 4: Cleanup
|
# Step 4: Cleanup
|
||||||
lang = get_lang()
|
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"))
|
keep = keep_input in (("o", "oui") if lang == "fr" else ("y", "yes"))
|
||||||
if keep:
|
if keep:
|
||||||
print(f"{t('Database kept')}: {db_name}")
|
print(f"{t('Database kept')}: {db_name}")
|
||||||
else:
|
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}"
|
cmd_drop = f"./odoo_bin.sh db --drop --database {db_name}"
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(
|
||||||
cmd_drop,
|
cmd_drop,
|
||||||
|
|
@ -1460,7 +1475,9 @@ class TODO:
|
||||||
if status_code == 0:
|
if status_code == 0:
|
||||||
print(f"\n✅ {t('All unit tests passed')}")
|
print(f"\n✅ {t('All unit tests passed')}")
|
||||||
else:
|
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):
|
def execute_pip_audit(self):
|
||||||
versions, installed_versions, odoo_installed_version = (
|
versions, installed_versions, odoo_installed_version = (
|
||||||
|
|
@ -1495,7 +1512,11 @@ class TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
if not environments:
|
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
|
return
|
||||||
|
|
||||||
# Show selection menu
|
# Show selection menu
|
||||||
|
|
@ -1508,7 +1529,9 @@ class TODO:
|
||||||
env_input = ""
|
env_input = ""
|
||||||
while env_input not in environments and env_input != "0":
|
while env_input not in environments and env_input != "0":
|
||||||
if env_input:
|
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()
|
env_input = input(str_input).strip()
|
||||||
|
|
||||||
if env_input == "0":
|
if env_input == "0":
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue