[FIX] core: missing doc for some subcommands

Run `odoo-bin help`, you'll notice that some descriptions are missing,
this commit fixes that.

Run `odoo-bin shell --help`, you'll notice that the `usage:` line says
`odoo-bin [options]` instead of `odoo-bin shell [options]`. Other
commands that depend on the server cli are broken too. Fix those too.

closes odoo/odoo#121085

X-original-commit: 9c6bac741ff437564e7dbe4d0aa8dbd307b71f8d
Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
This commit is contained in:
Julien Castiaux
2023-06-06 11:44:58 +02:00
parent eda66f0560
commit 27865152bb
12 changed files with 83 additions and 71 deletions
+18 -18
View File
@@ -1,33 +1,33 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import os
import sys
import textwrap
from pathlib import Path
from odoo.tools import cloc, config
from . import Command
class Cloc(Command):
"""\
Odoo cloc is a tool to count the number of relevant lines written in
Python, Javascript or XML. This can be used as rough metric for pricing
maintenance of customizations.
It has two modes of operation, either by providing a path:
odoo-bin cloc -p module_path
Or by providing the name of a database:
odoo-bin cloc --addons-path=dirs -d database
In the latter mode, only the custom code is accounted for.
"""
""" Count lines of code per modules """
def run(self, args):
parser = argparse.ArgumentParser(
prog="%s cloc" % sys.argv[0].split(os.path.sep)[-1],
description=textwrap.dedent(self.__doc__),
prog=f'{Path(sys.argv[0]).name} {self.name}',
description="""\
Odoo cloc is a tool to count the number of relevant lines written in
Python, Javascript or XML. This can be used as rough metric for pricing
maintenance of customizations.
It has two modes of operation, either by providing a path:
odoo-bin cloc -p module_path
Or by providing the name of a database:
odoo-bin cloc --addons-path=dirs -d database
In the latter mode, only the custom code is accounted for.
""",
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('--database', '-d', dest="database", help="Database name")
+23 -13
View File
@@ -1,8 +1,8 @@
from __future__ import print_function
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import sys
import os
from os.path import join as joinpath, isdir
import sys
from pathlib import Path
import odoo
from odoo.modules import get_modules, get_module_path, initialize_sys_path
@@ -14,17 +14,27 @@ class Command:
cls.name = cls.name or cls.__name__.lower()
commands[cls.name] = cls
ODOO_HELP = """\
Odoo CLI, use '{odoo_bin} --help' for regular server options.
Available commands:
{command_list}
Use '{odoo_bin} <command> --help' for individual command help."""
class Help(Command):
"""Display the list of available commands"""
""" Display the list of available commands """
def run(self, args):
print("Available commands:\n")
names = list(commands)
padding = max([len(k) for k in names]) + 2
for k in sorted(names):
name = k.ljust(padding, ' ')
doc = (commands[k].__doc__ or '').strip()
print(" %s%s" % (name, doc))
print("\nUse '%s <command> --help' for individual command help." % sys.argv[0].split(os.path.sep)[-1])
padding = max([len(cmd) for cmd in commands]) + 2
command_list = "\n ".join([
" {}{}".format(name.ljust(padding), (command.__doc__ or "").strip())
for name, command in sorted(commands.items())
])
print(ODOO_HELP.format( # pylint: disable=bad-builtin
odoo_bin=Path(sys.argv[0]).name,
command_list=command_list
))
def main():
args = sys.argv[1:]
@@ -45,7 +55,7 @@ def main():
logging.disable(logging.CRITICAL)
initialize_sys_path()
for module in get_modules():
if isdir(joinpath(get_module_path(module), 'cli')):
if (Path(get_module_path(module)) / 'cli').is_dir():
__import__('odoo.addons.' + module)
logging.disable(logging.NOTSET)
command = args[0]
+7 -5
View File
@@ -1,10 +1,11 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import io
import urllib.parse
import sys
import zipfile
from functools import partial
from pathlib import Path
from sys import argv, stdout, stderr
import requests
@@ -13,9 +14,10 @@ from .server import report_configuration
from ..service.db import dump_db, exp_drop, exp_db_exist, exp_duplicate_database, exp_rename, restore_db
from ..tools import config
eprint = partial(print, file=stderr, flush=True)
eprint = partial(print, file=sys.stderr, flush=True)
class Db(Command):
""" Create, drop, dump, load databases """
name = 'db'
def run(self, cmdargs):
@@ -25,8 +27,8 @@ class Db(Command):
all filestore-aware.
"""
parser = argparse.ArgumentParser(
prog="%s %s" % (Path(argv[0]).name, self.name),
description=self.__doc__
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__.strip()
)
parser.add_argument('-c', '--config')
parser.add_argument('-D', '--data-dir')
@@ -146,7 +148,7 @@ class Db(Command):
def dump(self, args):
if args.dump_path == '-':
dump_db(args.database, stdout.buffer)
dump_db(args.database, sys.stdout.buffer)
else:
with open(args.dump_path, 'wb') as f:
dump_db(args.database, f)
+3 -4
View File
@@ -1,12 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import os
import requests
import sys
import tempfile
import zipfile
from pathlib import Path
from . import Command
@@ -63,7 +62,7 @@ class Deploy(Command):
def run(self, cmdargs):
parser = argparse.ArgumentParser(
prog="%s deploy" % sys.argv[0].split(os.path.sep)[-1],
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__
)
parser.add_argument('path', help="Path of the module to deploy")
+5 -4
View File
@@ -1,8 +1,10 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import os
import secrets
import sys
import textwrap
from pathlib import Path
from passlib.hash import pbkdf2_sha512
@@ -11,8 +13,7 @@ from odoo.tools import config
class GenProxyToken(Command):
def __init__(self):
self.command_name = "genproxytoken"
""" Generate and (re)set proxy access token in config file """
def generate_token(self, length=16):
token = secrets.token_hex(int(length / 2))
@@ -21,8 +22,8 @@ class GenProxyToken(Command):
def run(self, cmdargs):
parser = argparse.ArgumentParser(
prog="%s %s" % (sys.argv[0].split(os.path.sep)[-1], self.command_name),
description="Generate and (re)set proxy access token in config file"
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__.strip()
)
parser.add_argument('-c', '--config', type=str, help="Specify an alternate config file")
parser.add_argument('--token-length', type=int, help="Token Length", default=16)
+2 -2
View File
@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import optparse
import sys
from pathlib import Path
import odoo
@@ -17,6 +16,7 @@ class Neutralize(Command):
def run(self, args):
parser = odoo.tools.config.parser
parser.prog = f'{Path(sys.argv[0]).name} {self.name}'
group = optparse.OptionGroup(parser, "Neutralize", "Neutralize the database specified by the `-d` argument.")
group.add_option("--stdout", action="store_true", dest="to_stdout",
help="Output the neutralization SQL instead of applying it")
+7 -5
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from contextlib import nullcontext
import time
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import fnmatch
import logging
import optparse
import sys
import time
from contextlib import nullcontext
from pathlib import Path
from unittest.mock import patch
import odoo
@@ -14,9 +14,11 @@ _logger = logging.getLogger(__name__)
class Populate(Command):
""" Inject fake data inside a database for testing """
def run(self, cmdargs):
parser = odoo.tools.config.parser
parser.prog = f'{Path(sys.argv[0]).name} {self.name}'
group = optparse.OptionGroup(parser, "Populate Configuration")
group.add_option("--size", dest="population_size",
help="Populate database with auto-generated data. Value should be the population size: small, medium or large",
+3 -4
View File
@@ -1,10 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import os
import re
import sys
from pathlib import Path
import jinja2
@@ -16,7 +15,7 @@ class Scaffold(Command):
def run(self, cmdargs):
# TODO: bash completion file
parser = argparse.ArgumentParser(
prog="%s scaffold" % sys.argv[0].split(os.path.sep)[-1],
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__,
epilog=self.epilog(),
)
+2 -1
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
"""
@@ -17,6 +16,7 @@ import logging
import os
import re
import sys
from pathlib import Path
from psycopg2 import ProgrammingError, errorcodes
@@ -175,4 +175,5 @@ def main(args):
class Server(Command):
"""Start the odoo server (default command)"""
def run(self, args):
odoo.tools.config.parser.prog = f'{Path(sys.argv[0]).name} {self.name}'
main(args)
+2 -3
View File
@@ -1,12 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from __future__ import print_function
import code
import logging
import os
import signal
import sys
from pathlib import Path
import odoo
from odoo.tools import config
@@ -56,6 +54,7 @@ class Shell(Command):
supported_shells = ['ipython', 'ptpython', 'bpython', 'python']
def init(self, args):
config.parser.prog = f'{Path(sys.argv[0]).name} {self.name}'
config.parse_config(args)
odoo.cli.server.report_configuration()
odoo.service.server.start(preload=[], stop=True)
+6 -6
View File
@@ -1,11 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import glob
import itertools
import os
import sys
from pathlib import Path
import odoo
from . import Command
@@ -15,7 +14,7 @@ from odoo.service.db import _create_empty_database, DatabaseExists
class Start(Command):
"""Quick start the Odoo server for your project"""
""" Quickly start the odoo server with default options """
def get_module_list(self, path):
mods = itertools.chain.from_iterable(
@@ -25,9 +24,10 @@ class Start(Command):
return [mod.split(os.path.sep)[-2] for mod in mods]
def run(self, cmdargs):
odoo.tools.config.parser.prog = f'{Path(sys.argv[0]).name} {self.name}'
parser = argparse.ArgumentParser(
prog="%s start" % sys.argv[0].split(os.path.sep)[-1],
description=self.__doc__
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__.strip(),
)
parser.add_argument('--path', default=".",
help="Directory where your project's modules are stored (will autodetect from current dir)")
+5 -6
View File
@@ -1,19 +1,18 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import argparse
import glob
import json
import os
import re
import sys
from pathlib import Path
from . import Command
from odoo.modules.module import MANIFEST_NAMES
class TSConfig(Command):
"""Generates tsconfig files for javascript code"""
def __init__(self):
self.command_name = "tsconfig"
""" Generates tsconfig files for javascript code """
def get_module_list(self, path):
return [
@@ -35,8 +34,8 @@ class TSConfig(Command):
def run(self, cmdargs):
parser = argparse.ArgumentParser(
prog="%s %s" % (sys.argv[0].split(os.path.sep)[-1], self.command_name),
description=self.__doc__
prog=f'{Path(sys.argv[0]).name} {self.name}',
description=self.__doc__.strip()
)
parser.add_argument('--addons-path', type=str, nargs=1, dest="paths")
args = parser.parse_args(args=cmdargs)