diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d0a9893d5e45d5c05ff63f967924cdb091334810_LmdpdGxhYi1jaS55bWw=..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_LmdpdGxhYi1jaS55bWw= 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,10 +5,8 @@ project: xcg/ci-templates - file: deploy-doc.gitlab-ci.yaml project: xcg/ci-templates -- file: shell-lint.gitlab-ci.yaml - project: xcg/ci-templates variables: TAG_LATEST: branch/default DOCKER_IMAGE: xcgd/odoo_scripts HTML_DOC_SOURCES: doc/_build/html @@ -10,12 +8,8 @@ variables: TAG_LATEST: branch/default DOCKER_IMAGE: xcgd/odoo_scripts HTML_DOC_SOURCES: doc/_build/html - SH_SCRIPTS: create_archive start - -checkbashisms: - allow_failure: true import_jsonrpc_odoo11_test: stage: test @@ -33,6 +27,7 @@ ODOO_TYPE: odoo11 before_script: - pip3 install $CI_PROJECT_DIR --disable-pip-version-check --no-cache-dir + - apt update && apt install zsh -yq script: - sudo --preserve-env -u odoo $CI_PROJECT_DIR/start --db_host=db -d test_setup --max-cron-threads=0 --without-demo=all --data-dir /var/lib/odoo --init base & # wait for odoo to install the modules diff --git a/NEWS.rst b/NEWS.rst index d0a9893d5e45d5c05ff63f967924cdb091334810_TkVXUy5yc3Q=..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_TkVXUy5yc3Q= 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -5,4 +5,8 @@ 6.0.0 ----- +Change to how output is colorized in shell scripts. + +Add .expand to several options so that a super project can reuse other super projects. + Fix --odoo-help in docker_dev_start to avoid requiring a database. @@ -8,5 +12,4 @@ Fix --odoo-help in docker_dev_start to avoid requiring a database. - 5.0.0 ----- diff --git a/README.rst b/README.rst index d0a9893d5e45d5c05ff63f967924cdb091334810_UkVBRE1FLnJzdA==..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_UkVBRE1FLnJzdA== 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,7 @@ Shell Scripts ============= -Those scripts are not installed when installing this python module. +Those scripts are not installed when installing this python module. They are meant to be used on a system that has Odoo installed, inside an image for example. start ----- @@ -20,5 +20,5 @@ It expect the configuration file (`setup.cfg`_) to have the following keys: -- ``odoo_type``: type of odoo (odoo7, odoo8, odoo10, odoo11 or odoo13) [default to odoo8]. The environment variable ODOO_TYPE can be used instead. +- ``odoo_type``. The environment variable ODOO_TYPE can be also be used instead to override the configuration file. - ``modules``: list of directories and files to include (also used by another script) @@ -24,2 +24,3 @@ - ``modules``: list of directories and files to include (also used by another script) +- ``load-language``. @@ -25,5 +26,10 @@ -The environment variable ODOO_ADDONS_PATH can be used to set the path for the addons, it can be empty if there is no path to include. +These environment variables can be set: + +ODOO_ADDONS_PATH + can be used to set the path for the addons, it can be empty if there is no path to include. +PRE_ODOO_BIN + Will be used in the command line calling odoo. Useful to run coverage tests for example. do_tests -------- @@ -46,7 +52,7 @@ The script call `run_tests`_. -It expect the configuration file (`setup.cfg`_) to have the following keys: +It expects the configuration file (`setup.cfg`_) to have the following keys: - ``module_list``: list (separated by white space) of odoo modules to install on the database (default to empty list) - ``unaccent``: boolean to indicate if unaccent is to be installed on the database (default to True) @@ -81,7 +87,8 @@ The recommend way to install this module is to run ``pip3 install .``, eventually with the ``editable`` option. Some scripts are in other sections, because they need some specialized library, in that case you need to indicate the name of section as in ``pip3 install ".[docker]"``. The prerequisites for this module or one of its section can be installed by using pip3 or the package manager; the requirements are defined in ``setup.py``. -As there is no way of indicating sections (it is even handling them incorrectly), do not use ``python3 setup.py install``. + +.. important:: As there is no way of indicating sections (it is even handling them incorrectly), do not use ``python3 setup.py install``. docker_isort ------------ @@ -101,7 +108,7 @@ update_duplicate_sources.py --------------------------- -This script will update a metaproject that only contain the sources of the one it is launched from. +This script will update a project that only contain the sources of the one it is launched from. It expect the configuration file (`setup.cfg`_) to have the following keys: @@ -203,7 +210,7 @@ setup.cfg ========= -The scripts expects configuration in the odoo_scripts section of ``setup.cfg``. This file is in the super project, not the one in ``odoo_scripts``. +The scripts expects configuration in the odoo_scripts section of ``setup.cfg``. This is the file in the super project, not the one in `Odoo Scripts`_. Configuration keys: @@ -236,7 +243,7 @@ cd src git clone git@github.com:RobSis/zsh-completion-generator.git -Generate completion file for python scripts (from the superproject for the scripts that need to be run from there, and with the required requirements too):: +Generate completion file for python scripts (from the super project for the scripts that need to be run from there, and with the required requirements too):: for command_name in docker_dev_start docker_build docker_build_copy docker_build_clean do_tests conf2reST import_base_import import_jsonrpc import_sql docker_flake8 docker_isort docker_pg; do $command_name --help | ~/src/zsh-completion-generator/help2comp.py $command_name > ~/.local/share/zsh/completion/_$command_name diff --git a/common b/common new file mode 100644 index 0000000000000000000000000000000000000000..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_Y29tbW9u --- /dev/null +++ b/common @@ -0,0 +1,84 @@ +#!/bin/zsh +# vim: set shiftwidth=4 softtabstop=4: +# Common functions and env var + +# assume we are called from the project home +project_home=$PWD +project_name=$(basename "$project_home") + +if ! type python3 > /dev/null; then + python="python2" +else + python="python3" +fi + +# handy colorized variables +esc=$(printf '\033') +RESET="${esc}[0m" +DEBUG="[${esc}[36mDEBUG${RESET}]" +INFO="[${esc}[34mINFO ${RESET}]" +WARN="[${esc}[33mWARN ${RESET}]" +FATAL="[${esc}[41m${esc}[37mFATAL${RESET}]" +GREEN="${esc}[32m" +OK="[${GREEN} OK${RESET} ]" +RED="${esc}[31m" +KO="[${esc}[41m${esc}[37m KO ${RESET}]" + +function read_configuration_key () { + # Read a configuration key from any ini file + # first argument is file path + # second argument is section + # third argument is the key to use + # fourth argument is default value, if any + # fifth argument is separator, default to a space + file=$1 + section=$2 + configuration_key=$3 + default_value=$4 + separator=${5- } + echo $($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${file}') ; print('$separator'.join(c.get('$section', '$configuration_key').split()) if c.has_option('$section', '$configuration_key') else '$default_value')") +} + +function read_odoo_scripts_configuration_key () { + # Return configuration value from odoo_scripts configuration file + # first argument is the key to use + # second argument is default value, if any + configuration_key=${1} + default_value=$2 + read_configuration_key "${project_home}/setup.cfg" odoo_scripts $configuration_key $default_value +} + +function read_odoo_scripts_expandable_configuration_key () { + # return configuration value by appending any expanded values from defined super projects + # first argument is the key to use + # second argument is the directory to use, defaults to project home + # third optional argument is the separator to use (default to comma) + # fourth optional argument is to indicate if the expanded project should be used as prefix for the values (default to not use, use True to use), adding a / + # fifth optional argument is a prefix to use (default to none) + configuration_key=${1} + base_dir="${2-${project_home}}" + separator=${3-,} + prefix_with_expand=${4-False} + prefix=$5 + # read expanded configurations + expanded_project_pathes=($($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('$base_dir/setup.cfg') ; print(c.get('odoo_scripts', '$configuration_key.expand') if c.has_option('odoo_scripts', '$configuration_key.expand') else '')")) + for expanded_project_path in $expanded_project_pathes; do + that_project_prefix=$prefix + if [[ "$prefix_with_expand" == True ]]; + then + that_project_prefix=${that_project_prefix}${expanded_project_path}/ + fi + expanded_configuration_value=$(read_odoo_scripts_expandable_configuration_key $configuration_key "$base_dir/$expanded_project_path" "$separator" $prefix_with_expand "$that_project_prefix") + if [[ -n $configuration_value ]]; then + configuration_value+=$separator + fi + configuration_value+=$expanded_configuration_value + done + # then add local values + this_project_configuration_value+=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('$base_dir/setup.cfg') ; print('$separator'.join(['$prefix'+a for a in c.get('odoo_scripts', '$configuration_key').split()] if c.has_option('odoo_scripts', '$configuration_key') else []))") + if [[ -n $this_project_configuration_value && -n $configuration_value ]]; then + configuration_value+=$separator + fi + configuration_value+=$this_project_configuration_value + echo $configuration_value +} diff --git a/create_archive b/create_archive index d0a9893d5e45d5c05ff63f967924cdb091334810_Y3JlYXRlX2FyY2hpdmU=..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_Y3JlYXRlX2FyY2hpdmU= 100755 --- a/create_archive +++ b/create_archive @@ -1,5 +1,5 @@ -#!/bin/sh +#!/bin/zsh # vim: set shiftwidth=4 softtabstop=4: # Create archive of project sources @@ -2,7 +2,10 @@ # vim: set shiftwidth=4 softtabstop=4: # Create archive of project sources +here=$(dirname "$0") +source $here/common + # Arguments: # - directory of the odoo sources # - name of the tar file (the target file will have this name + .xz) if no name specified, name is <project name>.tar @@ -6,5 +9,4 @@ # Arguments: # - directory of the odoo sources # - name of the tar file (the target file will have this name + .xz) if no name specified, name is <project name>.tar - odoo_dir=$1 @@ -10,3 +12,3 @@ odoo_dir=$1 -tar_file=$2 +tar_file=${2-${project_name}.tar} @@ -12,15 +14,6 @@ -here=$(dirname "$0") -project_home=$(cd "$here" && cd .. && echo "$PWD") -project_name=$(basename "$project_home") -python=python - -odoo_modules="$($python -B -c "import ConfigParser ; c = ConfigParser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(' '.join(c.get('odoo_scripts', 'modules', '').split()))")" -dependencies="$($python -B -c "import ConfigParser ; c = ConfigParser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(c.has_section('odoo_scripts') and c.has_option('odoo_scripts', 'dependencies') and' '.join(c.get('odoo_scripts', 'dependencies', 'dependencies').split()) or 'dependencies')")" -if [ -z "$tar_file" ]; -then - tar_file=${project_name}.tar -fi +odoo_modules="$(read_odoo_scripts_expandable_configuration_key modules "$project_home" " ")" +dependencies="$(read_odoo_scripts_expandable_configuration_key dependencies "$project_home" " ")" cd "$project_home" || exit 1 # Create empty tar @@ -29,9 +22,9 @@ # Add modules, in odoo_modules directory (whatever the original directory name) for module in $(eval echo "$odoo_modules") ; do - tar uf "$tar_file" --transform="s|^$(dirname "$module")|odoo_modules|" "$module" --show-transform --exclude-vcs --exclude-backups --exclude='*.pyc' --exclude='.drone.yml' --exclude='.gitlab-ci.yml' + tar uf "$tar_file" --transform="s|^$(dirname "$module")|odoo_modules|" --show-transform --exclude-vcs --exclude-backups --exclude='*.pyc' --exclude='.drone.yml' --exclude='.gitlab-ci.yml' --atime-preserve "$module" done # Add dependencies, in dependencies directory (whatever the original directory name) for dep in $(eval echo "$dependencies") ; do @@ -33,11 +26,11 @@ done # Add dependencies, in dependencies directory (whatever the original directory name) for dep in $(eval echo "$dependencies") ; do - tar uf "$tar_file" --transform="s|^$(dirname "$dep")|dependencies|" "$dep" --exclude-vcs --exclude-backups --exclude='*.pyc' --exclude='.drone.yml' --exclude='.gitlab-ci.yml' + tar uf "$tar_file" --transform="s|^$(dirname "$dep")|dependencies|" --exclude-vcs --exclude-backups --exclude='*.pyc' --exclude='.drone.yml' --exclude='.gitlab-ci.yml' --atime-preserve "$dep" done # Add version number file if present if [ -f VERSION ]; then @@ -39,10 +32,10 @@ done # Add version number file if present if [ -f VERSION ]; then - tar uf "tar_file" VERSION + tar uf "$tar_file" --atime-preserve VERSION fi if [ -d "$odoo_dir" ]; then @@ -45,9 +38,9 @@ fi if [ -d "$odoo_dir" ]; then - tar uf "$tar_file" --transform="s|^$(echo "$odoo_dir" | sed -e 's|/\(.*\)|\1|')|odoo|" "$odoo_dir" --exclude-vcs --exclude-backups --exclude='*.pyc' + tar uf "$tar_file" --transform="s|^$(echo "$odoo_dir" | sed -e 's|/\(.*\)|\1|')|odoo|" --exclude-vcs --exclude-backups --exclude='*.pyc' --atime-preserve "$odoo_dir" fi # Compress the file xz "$tar_file" @@ -50,4 +43,5 @@ fi # Compress the file xz "$tar_file" +echo $INFO Tar file $tar_file.xz created diff --git a/do_tests b/do_tests index d0a9893d5e45d5c05ff63f967924cdb091334810_ZG9fdGVzdHM=..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_ZG9fdGVzdHM= 100755 --- a/do_tests +++ b/do_tests @@ -16,13 +16,8 @@ # Version 5.0.0 here=$(dirname $0) -# assume we are called from the project home -project_home=$PWD -if ! type python3 > /dev/null; then - python="python2" -else - python="python3" -fi +source $here/common + # this is the same value as conf/drone/odoo.conf if [[ -e "${project_home}/conf/drone/odoo.conf" ]]; then @@ -26,8 +21,8 @@ # this is the same value as conf/drone/odoo.conf if [[ -e "${project_home}/conf/drone/odoo.conf" ]]; then - dbowner=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/conf/drone/odoo.conf') ; print(c.get('options', 'db_user'))") - unaccent=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/conf/drone/odoo.conf') ; print(c.get('options', 'unaccent') if c.has_option('options', 'unaccent') else False)") + dbowner=$(read_configuration_key ${project_home}/conf/drone/odoo.conf options db_user) + unaccent=$(read_configuration_key ${project_home}/conf/drone/odoo.conf options unaccent False) # this is the same value as conf/dev/odoo.conf elif [[ -e "${project_home}/conf/dev/odoo.conf" ]]; then @@ -31,9 +26,9 @@ # this is the same value as conf/dev/odoo.conf elif [[ -e "${project_home}/conf/dev/odoo.conf" ]]; then - dbowner=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/conf/dev/odoo.conf') ; print(c.get('options', 'db_user'))") - unaccent=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/conf/dev/odoo.conf') ; print(c.get('options', 'unaccent') if c.has_option('options', 'unaccent') else False)") + dbowner=$(read_configuration_key ${project_home}/conf/dev/odoo.conf options db_user) + unaccent=$(read_configuration_key ${project_home}/conf/dev/odoo.conf options unaccent False) else dbowner=odoo unaccent=False fi @@ -36,28 +31,10 @@ else dbowner=odoo unaccent=False fi -modules_to_install=${ODOO_SCRIPTS_MODULE_LIST-$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(','.join(c.get('odoo_scripts', 'module_list').split()))")} -if [[ -e "${project_home}/setup.cfg" ]]; -then - fail_on_errors=${ODOO_SCRIPTS_FAIL_ON_ERRORS-$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(c.get('odoo_scripts', 'fail_on_errors') if c.has_option('odoo_scripts', 'fail_on_errors') else True)")} -else - fail_on_errors=${ODOO_SCRIPTS_FAIL_ON_ERRORS-True} -fi - -# color stuff -autoload colors -if [[ "$terminfo[colors]" -gt 7 ]]; -then - echo "[DEBUG] colors" - colors -fi -for COLOR in RED GREEN YELLOW BLUE MAGENTA CYAN BLACK WHITE; do - eval $COLOR='$fg_no_bold[${(L)COLOR}]' - eval BOLD_$COLOR='$fg_bold[${(L)COLOR}]' -done -eval RESET='$reset_color' +modules_to_install=${ODOO_SCRIPTS_MODULE_LIST-$(read_odoo_scripts_expandable_configuration_key module_list)} +fail_on_errors=${ODOO_SCRIPTS_FAIL_ON_ERRORS-$(read_odoo_scripts_configuration_key fail_on_errors True)} # argument handling if [[ $# -gt 0 ]]; then @@ -60,10 +37,10 @@ # argument handling if [[ $# -gt 0 ]]; then - echo "[${YELLOW}INFO${RESET}] Using database host $1" + echo "$INFO Using database host $1" PG_HOST=-h$1 ODOO_HOST=--db_host=$1 shift if [[ $# -gt 0 ]]; then @@ -65,9 +42,9 @@ PG_HOST=-h$1 ODOO_HOST=--db_host=$1 shift if [[ $# -gt 0 ]]; then - echo "[${YELLOW}INFO${RESET}] Using database user $1" + echo "$INFO Using database user $1" PG_USER=-U$1 ODOO_USER=--db_user=$1 dbowner=$1 @@ -98,5 +75,5 @@ if [[ -z "$ODOO_NO_DROP" ]]; then - echo "[${YELLOW}INFO${RESET}] Drop any existing database '$dbname'" + echo "$INFO Drop any existing database '$dbname'" dropdb $PG_HOST $PG_USER --if-exists $dbname --no-password @@ -102,4 +79,4 @@ dropdb $PG_HOST $PG_USER --if-exists $dbname --no-password - echo "[${YELLOW}INFO${RESET}] Create database '$dbname' with owner $dbowner" - createdb $PG_HOST $PG_USER -O $dbowner $dbname --no-password || { echo ${RED}FATAL${RESET} - Cannot create test database ; exit 1; } + echo "$INFO Create database '$dbname' with owner $dbowner" + createdb $PG_HOST $PG_USER -O $dbowner $dbname --no-password || { echo "$FATAL Cannot create test database" ; exit 1; } fi @@ -105,4 +82,6 @@ fi -# TODO should also add all extensions from setup.cfg listed in pg.extensions + +# Add extensions +typeset -a extensions if [[ "$unaccent" == "True" ]]; then @@ -107,5 +86,4 @@ if [[ "$unaccent" == "True" ]]; then - echo "[${YELLOW}INFO${RESET}] Add unaccent to '$dbname'" - psql $PG_HOST $PG_USER $dbname -c "CREATE EXTENSION IF NOT EXISTS unaccent;" + extensions+=unaccent fi @@ -111,6 +89,12 @@ fi -echo "[${YELLOW}INFO${RESET}] Modules to install: $modules_to_install" -echo "[${YELLOW}INFO${RESET}] Install those modules" +extensions+=($(read_odoo_scripts_configuration_key pg.extensions)) +for extension in $extensions; do + echo "$INFO Create extension $extension in '$dbname'" + psql $PG_HOST $PG_USER $dbname -c "CREATE EXTENSION IF NOT EXISTS $extension;" +done + +echo "$INFO Modules to install: $modules_to_install" +echo "$INFO Install those modules" logfile=$(tempfile --suffix=.log) function clean_logfile() { rm $logfile @@ -120,7 +104,7 @@ start_status=$pipestatus[1] if [[ $start_status -ne 0 ]]; then - echo "[${RED} KO ${RESET}] Cannot install modules (exit ${start_status})" + echo "$KO Cannot install modules (exit ${start_status})" exit $start_status fi criticals=$(grep ' CRITICAL' -F $logfile -c) @@ -129,7 +113,7 @@ warnings=$(grep ' WARNING' -F $logfile -c) if [[ $criticals -gt 0 ]]; then - echo "[${RED} KO ${RESET}] Cannot install modules ($criticals CRITICAL messages found)" + echo "$KO Cannot install modules ($criticals CRITICAL messages found)" exit 2 fi @@ -137,5 +121,5 @@ then if [[ "$fail_on_errors" == "False" ]]; then - echo "[${MAGENTA}WARN${RESET}] Install modules with $errors ERROR messages" + echo "$WARN Install modules with $errors ERROR messages" else @@ -141,5 +125,5 @@ else - echo "[${RED} KO ${RESET}] Cannot install modules ($errors ERROR messages found)" + echo "$KO Cannot install modules ($errors ERROR messages found)" exit 1 fi else @@ -147,5 +131,5 @@ then if [[ "${FAIL_ON_WARNING:-False}" == "False" ]]; then - echo "[${MAGENTA}WARN${RESET}] Modules installed ($warnings WARNING messages)" + echo "$WARN Modules installed ($warnings WARNING messages)" else @@ -151,5 +135,5 @@ else - echo "[${RED} KO ${RESET}] Cannot install modules ($warnings WARNING messages found)" + echo "$KO Cannot install modules ($warnings WARNING messages found)" exit 1 fi else @@ -153,6 +137,6 @@ exit 1 fi else - echo "[${GREEN} OK ${RESET}] Modules installed" + echo "$OK Modules installed" fi fi @@ -157,4 +141,4 @@ fi fi -echo "[${YELLOW}INFO${RESET}] Run tests on $dbname" +echo "$INFO Run tests on $dbname" $here/run_tests $dbname $ODOO_HOST $ODOO_USER $* diff --git a/odoo_scripts/config.py b/odoo_scripts/config.py index d0a9893d5e45d5c05ff63f967924cdb091334810_b2Rvb19zY3JpcHRzL2NvbmZpZy5weQ==..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_b2Rvb19zY3JpcHRzL2NvbmZpZy5weQ== 100644 --- a/odoo_scripts/config.py +++ b/odoo_scripts/config.py @@ -3,4 +3,5 @@ import configparser import logging import os +import sys from glob import glob @@ -6,7 +7,8 @@ from glob import glob +from typing import List, Optional _logger = logging.getLogger(__name__) class Config(object): """Singleton for the configuration. @@ -7,13 +9,12 @@ _logger = logging.getLogger(__name__) class Config(object): """Singleton for the configuration. - At the moment, only read from `setup.cfg`. """ __instance = None def __new__(cls): if Config.__instance is None: @@ -14,9 +15,9 @@ """ __instance = None def __new__(cls): if Config.__instance is None: - Config.__instance = object.__new__(cls) + Config.__instance = Configuration() return Config.__instance @@ -21,4 +22,11 @@ return Config.__instance - def __init__(self): + +class Configuration(object): + """ + At the moment, only read from `setup.cfg`. + """ + + def __init__(self, base_path: str = None): + self._expanded_configuration = dict() setup_path = "setup.cfg" @@ -24,6 +32,8 @@ setup_path = "setup.cfg" + if base_path: + setup_path = os.path.join(base_path, setup_path) section = "odoo_scripts" config_parser = configparser.ConfigParser() if not os.path.exists(setup_path): _logger.warning("Missing %s", setup_path) else: @@ -25,7 +35,27 @@ section = "odoo_scripts" config_parser = configparser.ConfigParser() if not os.path.exists(setup_path): _logger.warning("Missing %s", setup_path) else: - config_parser.read(os.path.join(os.getcwd(), "setup.cfg")) + config_parser.read(setup_path) + + def set_from_glob_values( + base: Optional[str], glob_values: List[str] + ) -> set: + result_set = set() + for glob_value in glob_values: + if base: + glob_value = os.path.join(base, glob_value) + for file in glob(glob_value): + if os.path.isdir(file): + result_set.add(file) + return result_set + + def get_expanded_configuration(path_name: str): + if path_name not in self._expanded_configuration: + self._expanded_configuration[path_name] = Configuration( + path_name + ) + return self._expanded_configuration[path_name] + for key in ("modules", "dependencies", "other_sources"): @@ -31,10 +61,15 @@ for key in ("modules", "dependencies", "other_sources"): - key_set = set() - for key_glob in config_parser.get( - section, key, fallback="" - ).split(): - for file in glob(key_glob): - if os.path.isdir(file): - key_set.add(file) - setattr(self, key, list(key_set)) + # get the values from this configuration + values = config_parser.get(section, key, fallback="").split() + set_values = set_from_glob_values(base_path, values) + # handle expand, getting value from another configuration + expand_value = config_parser.get( + section, key + ".expand", fallback=None + ) + if expand_value: + for element in expand_value.split(): + set_values.update( + getattr(get_expanded_configuration(element), key) + ) + setattr(self, key, list(set_values)) @@ -40,3 +75,3 @@ - def key_format(key: str) -> str: + def key_format(a_key: str) -> str: """Replace invalid characters in an attribute""" @@ -42,4 +77,4 @@ """Replace invalid characters in an attribute""" - return key.replace("-", "_").replace(".", "_") + return a_key.replace("-", "_").replace(".", "_") for key in ("module_list", "module_list_tests", "pg.extensions"): @@ -44,7 +79,8 @@ for key in ("module_list", "module_list_tests", "pg.extensions"): - setattr( - self, - key_format(key), - config_parser.get(section, key, fallback="").split(), + value = list() + formatted_key = key_format(key) + # add any expanded value + expand_value = config_parser.get( + section, key + ".expand", fallback=None ) @@ -50,7 +86,18 @@ ) + if expand_value: + for element in expand_value.split(): + value.extend( + getattr( + get_expanded_configuration(element), formatted_key + ) + ) + # add local values + value += config_parser.get(section, key, fallback="").split() + # then set it + setattr(self, formatted_key, value) for key in ("db_user", "db_password", "load-language"): setattr( self, key_format(key), config_parser.get(section, key, fallback=None), ) @@ -51,9 +98,10 @@ for key in ("db_user", "db_password", "load-language"): setattr( self, key_format(key), config_parser.get(section, key, fallback=None), ) + self.registry = config_parser.get( section, "registry", fallback="registry.xcg.io" ) @@ -78,3 +126,18 @@ self.start_py3o = config_parser.get( section, "start_py3o", fallback="no" ) in ("yes", "true") + + +def main(argv=None): + """Display configuration. Useful for development of odoo_scripts. + """ + c = Config() + for key, value in c.__dict__.items(): + print(key, "=", value) + return 0 + + +if __name__ == "__main__": + return_code = main(sys.argv[1:]) + if return_code: + exit(return_code) diff --git a/odoo_scripts/docker_build_copy.py b/odoo_scripts/docker_build_copy.py index d0a9893d5e45d5c05ff63f967924cdb091334810_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jb3B5LnB5..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jb3B5LnB5 100644 --- a/odoo_scripts/docker_build_copy.py +++ b/odoo_scripts/docker_build_copy.py @@ -61,7 +61,10 @@ c = Config() modules = [os.path.realpath(module) for module in c.modules] # copy files - _logger.info("Copying Odoo modules files to odoo_modules") + target = "odoo_modules" + _logger.info("Copying Odoo modules files to %s", target) + if not os.path.exists(target): + os.mkdir(target) cmd = ( [ "rsync", @@ -75,8 +78,8 @@ "--times", ] + modules - + ["odoo_modules"] + + [target] ) _logger.debug(" ".join(cmd)) call(cmd) # this only sync static from our modules @@ -79,8 +82,11 @@ ) _logger.debug(" ".join(cmd)) call(cmd) # this only sync static from our modules - _logger.info("Copying static files to static") + target = "static" + _logger.info("Copying static files to %s", target) + if not os.path.exists(target): + os.mkdir(target) cmd = ( [ "rsync", @@ -96,7 +102,7 @@ "--prune-empty-dirs", ] + modules - + ["static"] + + [target] ) _logger.debug(" ".join(cmd)) call(cmd) diff --git a/run_tests b/run_tests index d0a9893d5e45d5c05ff63f967924cdb091334810_cnVuX3Rlc3Rz..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_cnVuX3Rlc3Rz 100755 --- a/run_tests +++ b/run_tests @@ -4,6 +4,6 @@ # This script is used to run tests on a database with demo data installed. # # Either provide the name of the database (first argument) or it will default to <project>_test -# The DB user can be overriden by setting ODOO_SCRIPTS_DB_USER. +# The DB user can be overridden by setting ODOO_SCRIPTS_DB_USER. # Version 5.0.0 here=$(dirname $0) @@ -8,13 +8,9 @@ # Version 5.0.0 here=$(dirname $0) -# assume we are called from the project home -project_home=$PWD -if ! type python3 > /dev/null; then - python="python2" -else - python="python3" -fi -tested_modules=${ODOO_SCRIPTS_MODULE_LIST_TESTS-$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(','.join(c.get('odoo_scripts', 'module_list_tests').split() if c.has_option('odoo_scripts', 'module_list_tests') else []))")} +source $here/common + +tested_modules=${ODOO_SCRIPTS_MODULE_LIST_TESTS-$(read_odoo_scripts_expandable_configuration_key module_list_tests)} + if [[ "$tested_modules" != "" ]]; then update="-u $tested_modules" @@ -26,7 +22,7 @@ else shift fi -echo "Using database $dbname for tests" +echo "$INFO Using database $dbname for tests" if [[ -n "$ODOO_SCRIPTS_DB_USER" ]] then @@ -30,7 +26,7 @@ if [[ -n "$ODOO_SCRIPTS_DB_USER" ]] then - echo "Using db user $ODOO_SCRIPTS_DB_USER" + echo "$INFO Using db user $ODOO_SCRIPTS_DB_USER" db_user_param="--db_user $ODOO_SCRIPTS_DB_USER" fi @@ -34,7 +30,8 @@ db_user_param="--db_user $ODOO_SCRIPTS_DB_USER" fi -ODOO_TYPE=${ODOO_TYPE:-$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(c.get('odoo_scripts', 'odoo_type') if c.has_option('odoo_scripts', 'odoo_type') else 'odoo8')")} +ODOO_TYPE=${ODOO_TYPE:-$(read_odoo_scripts_configuration_key odoo_type odoo8)} + if [ "$ODOO_TYPE" = "odoo8" ]; then loglevel="--log-level=info" @@ -81,7 +78,7 @@ failed=$(grep 'openerp.modules.loading: At least one test failed when loading the modules.' $logfile -c) fi echo '' -echo '\e[2m*****\e[22m \e[1mTest results\e[21m \e[2m*****\e[22m' +echo "${esc}[2m*****${esc}[22m ${esc}[1mTest results${esc}[21m ${esc}[2m*****${esc}[22m" echo "Ran $tests_ran tests, $tests_failures failures, $tests_errors errors" if [ $ODOO_TYPE != 'odoo13' ]; then @@ -85,9 +82,9 @@ echo "Ran $tests_ran tests, $tests_failures failures, $tests_errors errors" if [ $ODOO_TYPE != 'odoo13' ]; then - echo "$ok modules passing" + echo "$OK $ok modules passing" fi echo '' if [[ $ok -gt 0 ]]; then @@ -89,9 +86,9 @@ fi echo '' if [[ $ok -gt 0 ]]; then - echo -e '\033[32mOK:\033[0m' + echo -e '${GREEN}Passes${RESET}:' # Highlight the "OK"s in green (32). GREP_COLOR='0;32' grep --color=always ' OK' $logfile || true @@ -99,7 +96,7 @@ if [[ $failed -gt 0 ]]; then - echo -e '\033[31mFailures\033[0m:' + echo -e '${RED}Failures${RESET}:' # Highlight the failure matches in red (31). GREP_COLOR='0;31' grep --color=always "CRITICAL\|FAIL\(ED\|:\)" $logfile @@ -115,8 +112,8 @@ rm $logfile if [[ $start_status -ne 0 ]]; then - echo "[${RED}FATAL${RESET}] Tests failed (exit ${start_status})" + echo "$FATAL Tests failed (exit ${start_status})" exit $start_status fi if [[ $tests_failures -gt 0 ]] || [[ $tests_errors -gt 0 ]]; then @@ -119,9 +116,9 @@ exit $start_status fi if [[ $tests_failures -gt 0 ]] || [[ $tests_errors -gt 0 ]]; then - echo "[${RED}FATAL${RESET}] Tests failed (found failure and errors in Ran N failures, M errors)" + echo "$FATAL Tests failed (found failure and errors in Ran N failures, M errors)" exit 42 fi if [[ $failed -gt 0 ]]; then @@ -124,11 +121,11 @@ exit 42 fi if [[ $failed -gt 0 ]]; then - echo "[${RED}FATAL${RESET}] Tests failed (found failure with grep)" + echo "$FATAL Tests failed (found failure with grep)" exit 1 fi if [[ "${FAIL_ON_WARNING:-False}" != "False" ]]; then if [[ $warnings -gt 0 ]]; then @@ -129,10 +126,10 @@ exit 1 fi if [[ "${FAIL_ON_WARNING:-False}" != "False" ]]; then if [[ $warnings -gt 0 ]]; then - echo "[${RED}FATAL${RESET}] Tests failed ($warnings WARNING found)" + echo "$FATAL Tests failed ($warnings WARNING found)" exit 1 fi fi diff --git a/start b/start index d0a9893d5e45d5c05ff63f967924cdb091334810_c3RhcnQ=..0d4e37c13858ac34f5fbe5a0271cafb2ad90ab45_c3RhcnQ= 100755 --- a/start +++ b/start @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/zsh # vim: set shiftwidth=4 softtabstop=4: # # This script start odoo for development @@ -8,12 +8,7 @@ # # Version 5.0.0 -# assume we are called from the project home -project_home=$PWD -if [ -x "$(command -v python3)" ]; -then - python="python3" -else - python="python2" -fi +here=$(dirname $0) +source $here/common + # odoo7, odoo8, odoo10, odoo11, odoo13 @@ -19,3 +14,3 @@ # odoo7, odoo8, odoo10, odoo11, odoo13 -ODOO_TYPE=${ODOO_TYPE:-$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(c.get('odoo_scripts', 'odoo_type') if c.has_option('odoo_scripts', 'odoo_type') else 'odoo8')")} +ODOO_TYPE=${ODOO_TYPE:-$(read_odoo_scripts_configuration_key odoo_type odoo8)} @@ -21,5 +16,5 @@ -echo "INFO - Starting odoo ($ODOO_TYPE) for development" +echo "$INFO Starting odoo ($ODOO_TYPE) for development" # # Do some magic to find the odoo command to run @@ -35,7 +30,7 @@ odoo_command=odoo ;; esac -echo "DEBUG - Trying odoo command $odoo_command" +echo "$DEBUG Trying odoo command $odoo_command" if [ -x "$(command -v $odoo_command)" ]; then odoo_bin=$odoo_command @@ -39,5 +34,5 @@ if [ -x "$(command -v $odoo_command)" ]; then odoo_bin=$odoo_command - echo "DEBUG - Command found" + echo "$DEBUG Command found" else @@ -43,6 +38,6 @@ else - echo "DEBUG - No odoo command found" - echo "DEBUG - Trying import in python" + echo "$DEBUG No odoo command found" + echo "$DEBUG Trying import in python" if [ "$ODOO_TYPE" = "odoo7" ] || [ "$ODOO_TYPE" = "odoo8" ]; then print_statement="import os;import openerp;print os.path.abspath(openerp.__file__)" @@ -54,5 +49,5 @@ odoo_bin=$odoo_command if test -z "$module_path"; then - echo "DEBUG - No odoo found by using module path" + echo "$DEBUG No odoo found by using module path" virtualenv_name=$(basename "$(readlink -f "$(dirname start)")") @@ -58,5 +53,5 @@ virtualenv_name=$(basename "$(readlink -f "$(dirname start)")") - echo "DEBUG - Trying $virtualenv_name virtualenvwrapper" + echo "$DEBUG Trying $virtualenv_name virtualenvwrapper" # assume you use virtualenvwrapper, and try the same env name as the project venv_python=$WORKON_HOME/$virtualenv_name/bin/python if [ -e "$venv_python" ]; @@ -65,7 +60,7 @@ fi if test -z "$module_path"; then - echo "DEBUG - No odoo found by using virtuenvwrapper" - echo "DEBUG - Trying in /opt/odoo/sources/odoo" + echo "$DEBUG No odoo found by using virtuenvwrapper" + echo "$DEBUG Trying in /opt/odoo/sources/odoo" if test -e "/opt/odoo/sources/odoo/$odoo_bin"; then @@ -70,6 +65,6 @@ if test -e "/opt/odoo/sources/odoo/$odoo_bin"; then - echo "DEBUG - Found in /opt/odoo/sources/odoo" + echo "$DEBUG Found in /opt/odoo/sources/odoo" odoo_bin=/opt/odoo/sources/odoo/$odoo_bin module_path="/opt/odoo/sources/odoo/odoo/__init__.py" else @@ -73,8 +68,8 @@ odoo_bin=/opt/odoo/sources/odoo/$odoo_bin module_path="/opt/odoo/sources/odoo/odoo/__init__.py" else - echo "FATAL - No odoo found" - echo "INFO - Maybe you forgot to activate your environment?" - exit 1 + echo "$FATAL No odoo found" + echo "$INFO Maybe you forgot to activate your environment?" + exit 1 fi else @@ -79,5 +74,5 @@ fi else - echo "DEBUG - Odoo found by using virtuenvwrapper" + echo "$DEBUG Odoo found by using virtuenvwrapper" fi else @@ -82,6 +77,6 @@ fi else - echo "DEBUG - Odoo found by using module path ($module_path)" + echo "$DEBUG Odoo found by using module path ($module_path)" fi odoo=$(dirname "$(dirname $module_path)") @@ -112,6 +107,6 @@ else if [ -e "${project_home}/conf/drone/odoo.conf" ]; then - config="-c ${project_home}/conf/drone/odoo.conf" + config="--config=${project_home}/conf/drone/odoo.conf" elif [ -e "${project_home}/conf/dev/odoo.conf" ]; then @@ -116,6 +111,6 @@ elif [ -e "${project_home}/conf/dev/odoo.conf" ]; then - config="-c ${project_home}/conf/dev/odoo.conf" + config="--config=${project_home}/conf/dev/odoo.conf" fi if echo "$args" | grep -q -e '\( \|^\)--addons-path'; then @@ -128,5 +123,6 @@ pathes=$ODOO_ADDONS_PATH fi else + modules_to_use=$(read_odoo_scripts_expandable_configuration_key modules ${project_home} , True) if [ "$ODOO_TYPE" = "odoo7" ] || [ "$ODOO_TYPE" = "odoo8" ]; then @@ -131,4 +127,4 @@ if [ "$ODOO_TYPE" = "odoo7" ] || [ "$ODOO_TYPE" = "odoo8" ]; then - pathes=$($python -B -c "from six.moves import configparser ; import os ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(','.join(['$odoo_addons_path/addons']+['${project_home}/'+line for line in set(os.path.dirname(path) for path in c.get('odoo_scripts', 'modules').split())]))") + pathes=$($python -B -c "import os;print(','.join(['$odoo_addons_path/addons']+['${project_home}/'+line for line in set(os.path.dirname(path) for path in '${modules_to_use}'.split(','))]))") else @@ -134,5 +130,5 @@ else - pathes=$($python -B -c "from six.moves import configparser ; import os ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(','.join(['${project_home}/'+line for line in set(os.path.dirname(path) for path in c.get('odoo_scripts', 'modules').split())]))") + pathes=$($python -B -c "import os;print(','.join(['${project_home}/'+line for line in set(os.path.dirname(path) for path in '${modules_to_use}'.split(','))]))") fi fi if [ -n "$pathes" ]; @@ -144,5 +140,5 @@ # use load-language from setup.cfg if none already provided if echo "$args" | grep -q -e '\( \|^\)-c' -e '\( \|^\)--load-language'; then - echo "INFO - load-language flag detected, no reading from setup.cfg" + echo "$INFO load-language flag detected, no reading from setup.cfg" else @@ -148,4 +144,4 @@ else - load_language=$($python -B -c "from six.moves import configparser ; c = configparser.ConfigParser() ; c.read('${project_home}/setup.cfg') ; print(c.get('odoo_scripts', 'load-language') if c.has_option('odoo_scripts', 'load-language') else '')") + load_language=$(read_odoo_scripts_configuration_key load-language) if [ -n "$load_language" ]; then @@ -150,6 +146,6 @@ if [ -n "$load_language" ]; then - load_language="--load-language $load_language" + load_language="--load-language=$load_language" fi fi @@ -157,7 +153,7 @@ # Start Odoo # -echo "INFO - Odoo Version: $($odoo_bin --version)" -echo "DEBUG - command line is: ${PRE_ODOO_BIN}$(command -v $odoo_bin) $config $db_host $addons_path $args $load_language" -# shellcheck disable=SC2046,SC2086 -${PRE_ODOO_BIN}$(command -v $odoo_bin) $config $db_host $addons_path $args $load_language +echo "$INFO Odoo Version: $($odoo_bin --version)" +echo "$DEBUG command line is: ${PRE_ODOO_BIN}$(which $odoo_bin) $config $db_host $addons_path $args $load_language" +# need to use eval due to spaces in the variables, otherwise zsh would treat one as an argument +exec eval ${PRE_ODOO_BIN}$(which $odoo_bin) $config $db_host $addons_path $args $load_language