2320 lines
86 KiB
Bash
Executable File
2320 lines
86 KiB
Bash
Executable File
#!/bin/bash
|
|
cd "$(dirname "$0")" || exit
|
|
# Commands such as git pull return exit code if there are no changes
|
|
# set -e
|
|
|
|
if [[ -a ".env" ]]; then
|
|
source .env
|
|
fi
|
|
|
|
function help-table() {
|
|
# Define column widths
|
|
cmd_width=25
|
|
opt_width=20
|
|
desc_width=90
|
|
|
|
# Print table header
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "Command" "Option" "Description"
|
|
echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|"
|
|
|
|
# Print table rows
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "activate-venv" "" "Activate virtualenv."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "build" "[platform]" "Build Odoo Conainer image. Optionally define the target platform."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "change-uuid" "[env]" "Change database uuid via xmlrpc."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "checkout" "[branch]" "Checkout Odoo version / branch."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "checkout-config-files" "[branch]" "Checkout config files from another branch."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "checkout-revision" "[revision]" "Run Odoo revision script or checkout revision set by env var."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "clear-assets" "[db]" "Clear all assets of Odoo database."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "clear-views" "[db]" "Clear all views of Odoo database."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "clear-filestore" "[db]" "Clear local filestore folder. No param will clear all filestores. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "convert-database" "[db]" "Convert database backup file from PostgreSQL 9.5 to latest. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-module" "[path]" "Create new Odoo module from template."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-module-repo" "[path]" "Initialize Odoo module repo from template."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-revision" "[revision]" "Create new Odoo revision."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-nextcloud-env" "[env]" "Create env file for Nextcloud instance."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-odoo-env" "[env]" "Create env file for Odoo Instance."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "create-snippet" "[id]" "Create snippet from template."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "disable-mailserver" "[env]" "Disable mail server settings via xmlrpc."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "disable-snippet" "[env][path]" "Disable snippet definition."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "container-login" "" "Setup container hub login credentials."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "drop-db" "[db]" "Drop target Odoo database. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "edit-env" "[env]" "Open env file in default editor."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-admin-passwd" "[pass]" "Generate hash for Odoo master password."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "translate-module" "[env][path][lang]" "Generate translation for Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-help-doc" "" "Write help table to task.md file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-module-overview" "" "Update module overview doc file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-module-security" "[path][model]" "Generate model access file for a selected model of a module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-module-model" "[path][model]" "Generate model files from templates."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-module-snippet" "[path][ref]" "Generate view snippet from template."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-snippets-doc" "" "Update snippets doc file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-revisions-doc" "" "Update revisions doc file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "get-addons-path" "" "Output addons path."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "get-module-version" "[path]" "Get module version from manifest."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "get-modules" "[path][option]" "Get list of modules in path. Option is 'basename' or 'dirname'."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-feature-branch" "[path]" "Create feature branch for Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-fetch" "" "Fetch all Odoo version branches."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-mig-branch" "[path]" "Create migration branch for Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-add" "[url] [path]" "Add git submodule."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-checkout" "" "Checkout submodule commits."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-ls" "" "List submodule path space separated."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-list" "" "List path and url of submodules."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-init" "" "Init submodules listed in the .gitmodules file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-pull" "" "Pull all submodules listed in the .gitmodules file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-remove" "[path]" "Remove a git submodule."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-delete" "" "Delete all submodule folders."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-switch" "[branch]" "Switch branch for all submodules listed in the .gitmodules file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "git-submodule-sync" "" "Switch, stash and pull all submodules."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "import-csv" "[db][path]" "Import data from csv. Filename must match PostgreSQL table name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "info" "" "Show values of project env vars."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "init-db" "[db]" "Initialize the Odoo database. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "init-venv" "" "Initialize python virtual env."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "init-module" "[db][path,module]" "Initialize Odoo module. Default database is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "load-language" "[db][lang]" "Install language package in Odoo db."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install-native" "" "Install Odoo requirements in source folder."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install-odoo-scripts" "" "Install Odoo scripts."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install-requirements" "[db][path]" "Install python packages from requirements.txt."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install-snippet" "[env][path]" "Install snippet definition."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "k8s-apply" "" "Apply the Odoo K8s manifests."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "lint-module" "[path]" "Run pylint odoo for module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "lint-module-repo" "[path]" "Run pylint odoo for modules in repo folder."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "lint-snippets" "" "Run checks for all snippets."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "list-modules" "[path]" "Get modules in path as list."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "list-env" "" "List env files."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "list-revision" "" "List available Odoo revisions."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "llm-update" "[path]" "Feed module files with prompt to LLM and apply updates with git path."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "logs" "" "Tail Odoo container logs."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-install" "" "Install build dependencies."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-dev" "" "Start vuepress development server."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-build" "" "Create vuepress build."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-serve-build" "" "Serve vuepress build."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "odoo-cloc" "[db]" "Count custom line of codes. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "pass-store-dotenv" "" "Store content of .env in pass entry."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "pass-restore-dotenv" "" "Restore content of .env from pass entry."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "patch-database" "[db][path]" "Apply sql file to database. Default database is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "publish" "" "Publish Odoo container image."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "ps" "" "List container processes."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "pytest-module" "[db][name,path]" "Run module tests with pytest."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "release-module" "[path]" "Create GitHub release for a module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "remove" "[name]" "Remove containers and volumes. Options: none, db, admin, odoo, mail."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "remove-env" "[env]" "Remove environment config."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "remove-module" "[db][name]" "Remove target Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "remove-snippet" "[env][path]" "Remove snippet definition."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "reset-views" "[db][key]" "Execute hard reset on views matching keys."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "restart" "[name]" "Restart container."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "save-config" "[name]" "Save Odoo database config."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "setup-mail" "[db]" "Setup mail config in Odoo db."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "setup-mail-sql" "[db]" "Setup mail config in Odoo db with SQL."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "set-admin" "[db]" "Sets the password for the first user in database. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "set-addons-path" "" "Set Odoo addons path env variable."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "source" "" "Source the Python virtual env."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "show-env" "[env]" "Output content of the env file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "show-revision" "[revision]" "Show references of Odoo revision."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "start" "[name][db]" "Start container. Options: none, db, admin, odoo, native, mail."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "start-kind" "" "Start kind Kubernetes cluster."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "start-minikube" "" "Start minikube Kubernetes cluster."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "start-psql" "[db]" "Start PSQL shell in container container. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "start-shell" "[db]" "Start Odoo shell from source folder. Default is branch name."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "stop" "[name]" "Stop containers."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "template-odoo-rc" "" "Template the Odoo config file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "template-docker-compose" "" "Template the Docker compose file."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-container" "" "Test container environment."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-xmlrpc" "[env]" "Test json rpc connection."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-k8s" "" "Test Kubernetes environment."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-module" "[db][name,path]" "Test target Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-module-repo" "[db][path]" "Test target Odoo modules in repo folder."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "update-app-list" "[db]" "Update app list."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "update-docs" "" "Update project docs."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "upgrade-module" "[path][version]" "Upgrade code of module from target Odoo version."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "upgrade-odoo" "[db][version][mode]" "Run the Odoo upgrade scripts. Default mode ist 'test'."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "update-module" "[db][name,path]" "Update target Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "update-readme" "[path]" "Update Readme file of Odoo module collection."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "update-snippet" "[env][path]" "Update snippet definition."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "upload-module" "[env][path]" "Zip and upload Odoo module."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "visualize-dependencies" "[path]" "Generate visualizations of module dependencies."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "version" "" "Show version of required tools."
|
|
printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "zip-module" "[path]" "Create zip file for module."
|
|
}
|
|
|
|
function help() {
|
|
echo
|
|
echo "$1 <command> [options]"
|
|
echo
|
|
echo "commands:"
|
|
echo
|
|
help-table
|
|
echo
|
|
}
|
|
|
|
# Static env vars
|
|
|
|
PASS_ENTRY=env/Odoo-Build
|
|
ODOO_RC="odoo.conf"
|
|
ODOO_BUILD_CONFIG_DIR="$HOME/.config/odoo-build"
|
|
|
|
# Dynamic env vars
|
|
|
|
GIT_BRANCH=$(git symbolic-ref --short -q HEAD)
|
|
ODOO_DATABASE=${ODOO_DATABASE:="$GIT_BRANCH"}
|
|
ODOO_REVISION=${ODOO_REVISION:="$GIT_BRANCH"}
|
|
ODOO_LANGUAGE=${ODOO_LANGUAGE:="de_CH"}
|
|
ODOO_PORT=${ODOO_PORT:="8069"}
|
|
POSTGRES_PORT=${POSTGRES_PORT:="5432"}
|
|
LOG_LEVEL=${LOG_LEVEL:="info"}
|
|
CONTAINER_REGISTRY=${CONTAINER_REGISTRY:="mintsystem/"}
|
|
CONTAINER_TAG=${CONTAINER_TAG:="odoo:${ODOO_REVISION}"}
|
|
CONTAINER_CONFIG="$HOME/.docker/$CONTAINER_REGISTRY"
|
|
BROWSER_OPEN=${BROWSER_OPEN:=true}
|
|
ODOO_REVISION_CONTAINER_PULL=${ODOO_REVISION_CONTAINER_PULL:=true}
|
|
CONTAINER_ENGINE=${CONTAINER_ENGINE:="docker"}
|
|
COMPOSE_COMMAND=${COMPOSE_COMMAND:="docker compose"}
|
|
LLM_MODEL=${LLM_MODEL:="deepseek-coder"}
|
|
|
|
# Conditional env vars
|
|
|
|
if [[ "$CONTAINER_ENGINE" == "podman" ]]; then
|
|
COMPOSE_COMMAND="podman-compose"
|
|
fi
|
|
|
|
if [ -n "$SERVER_WIDE_MODULES" ]; then
|
|
SERVER_WIDE_MODULES="base,web,$SERVER_WIDE_MODULES"
|
|
else
|
|
SERVER_WIDE_MODULES="base,web"
|
|
fi
|
|
|
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
OS_RELEASE="Darwin"
|
|
PYTHON_NOTIFY=""
|
|
OS_OPEN="open"
|
|
else
|
|
OS_RELEASE=$(awk -F= '/^NAME/{print $2}' /etc/os-release | tr -d '"')
|
|
PYTHON_NOTIFY="inotify"
|
|
OS_OPEN="xdg-open"
|
|
fi
|
|
|
|
# Help Commands
|
|
|
|
function info() {
|
|
set-addons-path
|
|
echo "OS Release: $OS_RELEASE"
|
|
echo "Git Branch: $GIT_BRANCH"
|
|
echo "Odoo Revision: $ODOO_REVISION"
|
|
echo "Odoo Port: $ODOO_PORT"
|
|
echo "Postgres Port: $POSTGRES_PORT"
|
|
echo "Odoo Language: $ODOO_LANGUAGE"
|
|
echo "Container Registry: $CONTAINER_REGISTRY"
|
|
echo "Container Config: $CONTAINER_CONFIG"
|
|
echo "Container Tag: $CONTAINER_TAG"
|
|
echo "Addons Path: $ADDONS_PATH"
|
|
}
|
|
|
|
function version() {
|
|
activate-venv
|
|
uv --version
|
|
wkhtmltopdf -V
|
|
if [ "$CONTAINER_ENGINE" == "docker" ]; then
|
|
docker -v
|
|
docker compose version
|
|
else
|
|
podman --version
|
|
podman-compose --version
|
|
fi
|
|
minikube version
|
|
kind version
|
|
}
|
|
|
|
function generate-admin-passwd() {
|
|
activate-venv
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
ODOO_PASSWORD="$1"
|
|
scripts/hash_password
|
|
}
|
|
|
|
# Environment Commands
|
|
|
|
function init-venv() {
|
|
if [ ! -d "venv$GIT_BRANCH" ]; then
|
|
echo "Init venv$GIT_BRANCH with $(uv --version)."
|
|
uv venv "venv$GIT_BRANCH"
|
|
fi
|
|
}
|
|
|
|
function activate-venv() {
|
|
echo "Source virtualenv venv$GIT_BRANCH."
|
|
source "venv$GIT_BRANCH/bin/activate"
|
|
echo "$(python --version) is active."
|
|
}
|
|
|
|
function load-env() {
|
|
ENV_FILE="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
echo "Load env file $ENV_FILE"
|
|
|
|
export $(cat "$ENV_FILE" | sed 's/#.*//g' | xargs)
|
|
}
|
|
|
|
function get-addons-path() {
|
|
set-addons-path
|
|
echo "$ADDONS_PATH"
|
|
}
|
|
|
|
function template-odoo-rc() {
|
|
echo "Template $ODOO_RC"
|
|
|
|
export SERVER_WIDE_MODULES
|
|
export MODULE_AUTO_INSTALL_DISABLED
|
|
|
|
if [ -n "$GIT_SSH_PRIVATE_KEY" ]; then
|
|
GIT_SSH_PRIVATE_KEY=$(echo -e "$GIT_SSH_PRIVATE_KEY" | base64 -w0)
|
|
fi
|
|
export GIT_SSH_PRIVATE_KEY
|
|
export GIT_SSH_PUBLIC_KEY
|
|
|
|
export MAIL_DEFAULT_FROM=${MAIL_DEFAULT_FROM:="notification"}
|
|
export MAIL_CATCHALL_ALIAS=${MAIL_CATCHALL_ALIAS:="catchall"}
|
|
|
|
envsubst < "odoo.conf.template" > "$ODOO_RC"
|
|
}
|
|
|
|
function set-addons-path() {
|
|
|
|
# Read addons path from git submodules
|
|
SUBMODULES_PATH="$(git config --file .gitmodules --get-regexp path | awk '{ print $2 }' | tr '\n' ',' | sed 's/,*$//g')"
|
|
|
|
# Remove excluded addons
|
|
EXCLUDES="addons/theme_mint_system addons/company addons/web"
|
|
for EXCLUDE in $EXCLUDES; do
|
|
SUBMODULES_PATH=$(echo "$SUBMODULES_PATH" | sed "s|${EXCLUDE},||g")
|
|
done
|
|
|
|
# Check if addons dir exist
|
|
for ADDON in $SUBMODULES_PATH; do
|
|
if [ -d "$ADDON" ]; then
|
|
echo "Path does not exist: $ADDON"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Convert to native paths
|
|
ADDONS_PATH="$(echo $SUBMODULES_PATH | sed 's|odoo,|odoo/addons,|g')"
|
|
|
|
# Append paths from config env var
|
|
if [ -n "$ODOO_ADDONS_PATH" ]; then
|
|
ADDONS_PATH="${ODOO_ADDONS_PATH},${ADDONS_PATH}"
|
|
fi
|
|
}
|
|
|
|
function init-config-dir() {
|
|
echo "Ensure $ODOO_BUILD_CONFIG_DIR exists"
|
|
mkdir -p "$ODOO_BUILD_CONFIG_DIR"
|
|
}
|
|
|
|
function create-odoo-env() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
init-config-dir
|
|
ENV_FILEPATH="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
if [ -f "$ENV_FILEPATH" ]; then
|
|
echo "Env file already exists: $ENV_FILEPATH"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Init env file: $ENV_FILEPATH"
|
|
echo "ODOO_URL=$ODOO_URL" > "$ENV_FILEPATH"
|
|
echo "ODOO_DATABASE=$ODOO_DATABASE" >> "$ENV_FILEPATH"
|
|
echo "ODOO_USERNAME=$ODOO_USERNAME" >> "$ENV_FILEPATH"
|
|
echo "ODOO_PASSWORD=$ODOO_PASSWORD" >> "$ENV_FILEPATH"
|
|
|
|
echo "Edit with: task edit-env $1"
|
|
}
|
|
|
|
function create-nextcloud-env() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
init-config-dir
|
|
ENV_FILEPATH="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
if [ -f "$ENV_FILEPATH" ]; then
|
|
echo "Env file already exists: $ENV_FILEPATH"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Init env file: $ENV_FILEPATH"
|
|
echo "NEXTCLOUD_URL=" > "$ENV_FILEPATH"
|
|
echo "NEXTCLOUD_USERNAME=" >> "$ENV_FILEPATH"
|
|
echo "NEXTCLOUD_PASSWORD=" >> "$ENV_FILEPATH"
|
|
|
|
echo "Edit with: task edit-env $1"
|
|
}
|
|
|
|
function list-env() {
|
|
ls -a1 "$ODOO_BUILD_CONFIG_DIR"
|
|
}
|
|
|
|
function show-env() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
ENV_FILEPATH="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
cat "$ENV_FILEPATH"
|
|
}
|
|
|
|
function edit-env() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
ENV_FILEPATH="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
"$EDITOR" "$ENV_FILEPATH"
|
|
}
|
|
|
|
function remove-env() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
ENV_FILEPATH="$ODOO_BUILD_CONFIG_DIR/.env.$1"
|
|
rm "$ENV_FILEPATH"
|
|
}
|
|
|
|
# Docs Commands
|
|
|
|
generate-help-doc() {
|
|
help-table > task.md
|
|
}
|
|
|
|
function update-readme() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
README_PATH="$1"
|
|
FILE_NAME=$(basename "$README_PATH")
|
|
|
|
if [[ "$FILE_NAME" != "README.md" ]]; then
|
|
README_PATH="$1/README.md"
|
|
FILE_NAME="README.md"
|
|
fi
|
|
|
|
REPO_PATH=$(dirname "$README_PATH")
|
|
|
|
MANIFEST_FILES="$REPO_PATH/*/__manifest__.py"
|
|
|
|
# Find marker in readme and clear content after
|
|
echo "Clear modules table for $README_PATH."
|
|
MARKER="## Available modules"
|
|
sed -i "/$MARKER/Q" "$README_PATH"
|
|
|
|
echo "$MARKER" >> "$README_PATH"
|
|
echo "" >> "$README_PATH"
|
|
echo "| Module | Summary |" >> "$README_PATH"
|
|
echo "| --- | --- |" >> "$README_PATH"
|
|
|
|
# Clear table after a marker
|
|
for MANIFEST_FILE in $MANIFEST_FILES; do
|
|
MODULE_DIR=$(dirname "$MANIFEST_FILE")
|
|
MODULE_NAME=$(basename "$MODULE_DIR")
|
|
echo "Add summary of $MODULE_NAME to readme file."
|
|
SUMMARY=$(grep 'summary' "$MANIFEST_FILE" -A 1 | tail -1)
|
|
echo "| [$MODULE_NAME]($MODULE_NAME) | $SUMMARY |" >> "$README_PATH"
|
|
done
|
|
}
|
|
|
|
|
|
function generate-snippets-doc() {
|
|
|
|
echo "Update snippets doc file."
|
|
|
|
echo "# Snippets" > snippets.md
|
|
echo "In Odoo everything is described as an XML document. \
|
|
Snippets are modifications (edits) for these XML documents. \
|
|
With a snippet you can e.g. hide a field on the contact form. \
|
|
A snippet name is unique and follows the \`\$COMPANY.\$MODULE.\$XML_ID.\$DESCRIPTION\` schema." >> snippets.md
|
|
|
|
PATH_URL="https://github.com/Mint-System/Odoo-Build/tree/16.0"
|
|
|
|
# Get all modules
|
|
MODULES=$(ls snippets/*.xml | xargs -n 1 basename | cut -d. -f1 | sort | uniq)
|
|
for MODULE in $MODULES; do
|
|
|
|
TITLE="${MODULE^}" # Uppercase first letter
|
|
TITLE=$(echo "$TITLE" | sed 's/_/ /g') # Replace underline with space
|
|
TITLE=$(echo "$TITLE" | sed -r 's/\<./\U&/g') # Uppercase first letter after space
|
|
|
|
# Create doc file for each module
|
|
DOCFILE="snippets/$MODULE.md"
|
|
echo -e "# $TITLE" > "$DOCFILE"
|
|
echo "## [$TITLE](snippets/$MODULE.md)" >> snippets.md
|
|
SIDEBAR_ENTRIES+="'/snippets/$MODULE.md',\n"
|
|
|
|
# Get all xml ids
|
|
XML_IDS=$(ls snippets/$MODULE.*.xml | xargs -n 1 basename | cut -d. -f2 | uniq)
|
|
for XML_ID in $XML_IDS; do
|
|
|
|
XML_ID_TITLE=$(echo "$XML_ID" | sed 's/_/ /g') # Replace underline with space
|
|
XML_ID_TITLE=$(echo "$XML_ID_TITLE" | sed -r 's/\<./\U&/g') # Uppercase first letter after space
|
|
|
|
echo "## $XML_ID_TITLE " >> "$DOCFILE"
|
|
|
|
# Process each file
|
|
FILES="snippets/$MODULE.$XML_ID.*.xml"
|
|
for FILE in $FILES; do
|
|
|
|
# Get snippet params
|
|
FILENAME=$(basename "$FILE")
|
|
EDIT=$(echo "$FILENAME" | cut -d. -f3)
|
|
|
|
EDIT_TITLE=$(echo "$EDIT" | sed 's/_/ /g') # Replace underline with space
|
|
EDIT_TITLE=$(echo "$EDIT_TITLE" | sed -r 's/\<./\U&/g') # Uppercase first letter after space
|
|
|
|
# Group by modules
|
|
echo "### $EDIT_TITLE " >> "$DOCFILE"
|
|
echo "ID: \`mint_system.$MODULE.$XML_ID.$EDIT\` " >> "$DOCFILE"
|
|
echo -e '```xml' >> "$DOCFILE"
|
|
cat "$FILE" >> "$DOCFILE"
|
|
echo -e '\n```' >> "$DOCFILE"
|
|
echo -e "Source: [$FILE]($PATH_URL/$FILE)\n" >> "$DOCFILE"
|
|
done
|
|
done
|
|
done
|
|
echo -e "export default [$SIDEBAR_ENTRIES]" > .vuepress/sidebar.js
|
|
}
|
|
|
|
function generate-revisions-doc() {
|
|
|
|
echo "Update revisions doc file."
|
|
|
|
rm -f "revisions.md"
|
|
echo -e "# Odoo Revisions \n\
|
|
A Odoo revision is a snapshot of git references of the Odoo source and modules at a specific date.\n\
|
|
For each major release there are multiple revisions.\n" > "revisions.md"
|
|
|
|
declare -A REVISIONS
|
|
PATH_URL="https://github.com/Mint-System/Odoo-Build/tree/16.0"
|
|
|
|
for FILE in scripts/odoo_revision_*; do
|
|
if [[ -f "$FILE" ]]; then
|
|
REVISION=$(basename "$FILE" | sed 's/odoo_revision_//')
|
|
VERSION=$(echo "$REVISION" | cut -d'.' -f1-2)
|
|
|
|
if [[ -z "${REVISIONS[$VERSION]}" ]]; then
|
|
REVISIONS[$VERSION]="## $VERSION"
|
|
fi
|
|
|
|
REVISIONS[$VERSION]+=$'\n\n'
|
|
REVISIONS[$VERSION]+="#### $REVISION"
|
|
REVISIONS[$VERSION]+=$'\n\n```bash\n'
|
|
REVISIONS[$VERSION]+=$(cat "$FILE")
|
|
REVISIONS[$VERSION]+=$'\n```'
|
|
fi
|
|
done
|
|
|
|
for REVISION in $(echo "${!REVISIONS[@]}" | tr ' ' '\n' | sort -V); do
|
|
echo -e "${REVISIONS[$REVISION]}\n" >> "revisions.md"
|
|
done
|
|
}
|
|
|
|
function generate-module-overview() {
|
|
echo "Update module overview doc file."
|
|
activate-venv
|
|
./scripts/generate_module_overview
|
|
}
|
|
|
|
function update-docs() {
|
|
generate-module-overview
|
|
generate-revisions-doc
|
|
generate-snippets-doc
|
|
generate-help-doc
|
|
}
|
|
|
|
# Module Commands
|
|
|
|
function get-modules() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
OPTION="$2"
|
|
if [ -z "$OPTION" ]; then
|
|
OPTION="dirname"
|
|
fi
|
|
|
|
if [[ "$OPTION" == "dirname" ]]; then
|
|
MODULES=$(echo "$1" | tr "," "\n" | xargs -I {} find {} -type f -name "__manifest__.py" | xargs grep -l "version.*${GIT_BRANCH}" | xargs -r dirname | sort -u | tr "\n" "," | sed 's/,$//')
|
|
fi
|
|
if [[ "$OPTION" == "basename" ]]; then
|
|
MODULES=$(echo "$1" | tr "," "\n" | xargs -I {} find {} -type f -name "__manifest__.py" | xargs grep -l "version.*${GIT_BRANCH}" | xargs -r dirname | xargs -r -I {} basename {} | sort -u | tr "\n" "," | sed 's/,$//')
|
|
fi
|
|
echo "$MODULES"
|
|
}
|
|
|
|
function get-module-version() {
|
|
if test -z "$1"
|
|
then
|
|
echo "\$1 is empty."
|
|
else
|
|
# Get version of module
|
|
VERSION=$(grep -m 1 \"version "$1/__manifest__.py" | sed "s;';\";g" | sed "s/,//g" | sed 's/#.*//g')
|
|
VERSION=$(echo "{ $VERSION }" | jq .version | sed 's/"//g' | sed 's/null//g')
|
|
|
|
# Set default version
|
|
[ -z "$VERSION" ] && VERSION=0.0
|
|
|
|
COUNT_DOTS=$(echo "$VERSION" | grep -o "\." | wc -l)
|
|
|
|
# Check if oca version or enterprise version
|
|
if [[ $COUNT_DOTS == 2 ]]; then
|
|
VERSION="$GIT_BRANCH.$VERSION"
|
|
fi
|
|
if [[ $COUNT_DOTS == 1 ]]; then
|
|
VERSION="$GIT_BRANCH.$VERSION"
|
|
fi
|
|
|
|
echo "$VERSION"
|
|
fi
|
|
}
|
|
|
|
function list-modules() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
echo $(get-modules "$1" basename | tr "," "\n")
|
|
}
|
|
|
|
# Container Commands
|
|
|
|
function template-docker-compose() {
|
|
echo "Template docker-compose.yml"
|
|
|
|
export CONTAINER_REGISTRY
|
|
export CONTAINER_TAG
|
|
export POSTGRES_PORT
|
|
export ODOO_PORT
|
|
export MAIL_DEFAULT_FROM
|
|
export MAIL_CATCHALL_DOMAIN
|
|
export MAIL_CATCHALL_ALIAS
|
|
export ODOO_MAIL_SMTP_HOST
|
|
export ODOO_MAIL_SMTP_PORT
|
|
export ODOO_MAIL_SMTP_ENCRYPTION
|
|
export ODOO_MAIL_SMTP_FROM_FILTER
|
|
export ODOO_MAIL_IMAP_HOST
|
|
export ODOO_MAIL_IMAP_PORT
|
|
export ODOO_MAIL_IMAP_SSL
|
|
export ODOO_MAIL_USERNAME
|
|
export ODOO_MAIL_PASSWORD
|
|
export GIT_SSH_PUBLIC_KEY
|
|
export GIT_SSH_PRIVATE_KEY
|
|
export ADDONS_GIT_REPOS
|
|
export ODOO_ADDONS_PATH
|
|
export ODOO_DATABASE
|
|
export ODOO_INIT
|
|
export ODOO_INIT_LANG
|
|
export ODOO_INIT_ADDONS
|
|
export ENVIRONMENT
|
|
export PYTHON_INSTALL
|
|
export SERVER_WIDE_MODULES
|
|
export SESSION_DB_URI
|
|
export PROXY_MODE
|
|
export LOG_LEVEL
|
|
export LIST_DB
|
|
export ADMIN_PASSWD
|
|
export DBFILTER
|
|
export WORKERS
|
|
export LIMIT_REQUEST
|
|
export LIMIT_TIME_CPU
|
|
export LIMIT_TIME_REAL
|
|
export MODULE_AUTO_INSTALL_DISABLED
|
|
export CLICK_ODOO_UPDATE
|
|
export PGADMIN_DEFAULT_EMAIL
|
|
export PGADMIN_DEFAULT_PASSWORD
|
|
export POSTGRES_IMAGE
|
|
|
|
envsubst < "docker-compose.yml.template" > "docker-compose.yml"
|
|
}
|
|
|
|
function ps() {
|
|
$CONTAINER_ENGINE ps
|
|
}
|
|
|
|
function build() {
|
|
MANIFEST_FILE="image/Dockerfile"
|
|
PLATFORM="linux/amd64" # linux/arm64
|
|
if [ -n "$1" ]; then
|
|
PLATFORM="$1"
|
|
fi
|
|
ODOO_DATE=""
|
|
if [[ "ODOO_REVISION" != "$GIT_BRANCH" ]]; then
|
|
ODOO_DATE=$(echo "$ODOO_REVISION" | cut -d'.' -f3-)
|
|
fi
|
|
|
|
echo "Remove container image with tag ${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
$CONTAINER_ENGINE image rm -f "${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
|
|
if [ "$CONTAINER_ENGINE" == "podman" ]; then
|
|
echo "Run Podman build ${CONTAINER_REGISTRY}${CONTAINER_TAG} for ${PLATFORM}"
|
|
SOURCE_DATE_EPOCH=$(git -C odoo log -1 --pretty=%ct) podman build --platform "$PLATFORM" . \
|
|
--file "$MANIFEST_FILE" \
|
|
--build-arg ODOO_VERSION="$GIT_BRANCH" \
|
|
--build-arg ODOO_DATE="$ODOO_DATE" \
|
|
--tag "${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
fi
|
|
|
|
if [ "$CONTAINER_ENGINE" == "docker" ]; then
|
|
echo "Run Docker build ${CONTAINER_REGISTRY}${CONTAINER_TAG} for ${PLATFORM}"
|
|
SOURCE_DATE_EPOCH=$(git -C odoo log -1 --pretty=%ct) docker buildx build --platform "$PLATFORM" . \
|
|
--file "$MANIFEST_FILE" \
|
|
--build-arg ODOO_VERSION="$GIT_BRANCH" \
|
|
--build-arg ODOO_DATE="$ODOO_DATE" \
|
|
--tag "${CONTAINER_REGISTRY}${CONTAINER_TAG}" \
|
|
--load
|
|
fi
|
|
}
|
|
|
|
function container-login() {
|
|
echo "Setup container hub login credentials for $CONTAINER_REGISTRY"
|
|
echo -n "Enter username: "
|
|
read CONTAINER_REGISTRY_USERNAME
|
|
echo -n "Enter password: "
|
|
read -s CONTAINER_REGISTRY_PASSWORD
|
|
if [ "$CONTAINER_ENGINE" == "podman" ]; then
|
|
podman login --username "$CONTAINER_REGISTRY_USERNAME" --password "$CONTAINER_REGISTRY_PASSWORD" docker.io
|
|
fi
|
|
if [ "$CONTAINER_ENGINE" == "docker" ]; then
|
|
docker --config "$CONTAINER_CONFIG" login --username "$CONTAINER_REGISTRY_USERNAME" --password "$CONTAINER_REGISTRY_PASSWORD"
|
|
fi
|
|
}
|
|
|
|
function publish() {
|
|
LATEST_TAG="odoo:$GIT_BRANCH"
|
|
echo "Tag container image ${CONTAINER_REGISTRY}${CONTAINER_TAG} with ${CONTAINER_REGISTRY}${LATEST_TAG}"
|
|
$CONTAINER_ENGINE tag "${CONTAINER_REGISTRY}${CONTAINER_TAG}" "${CONTAINER_REGISTRY}${LATEST_TAG}"
|
|
|
|
if [ "$CONTAINER_ENGINE" == "docker" ]; then
|
|
echo "Push container image to ${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
docker --config "$CONTAINER_CONFIG" push "${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
docker --config "$CONTAINER_CONFIG" push "${CONTAINER_REGISTRY}${LATEST_TAG}"
|
|
fi
|
|
}
|
|
|
|
function upload-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
# Check if path is root folder
|
|
MODULES="$2"
|
|
if [ ! -f "$2/__manifest__.py" ]; then
|
|
echo "Identified as root folder"
|
|
MODULES="$MODULES/*"
|
|
fi
|
|
|
|
for MODULE in $MODULES; do
|
|
|
|
if [ -f "$MODULE/__manifest__.py" ]; then
|
|
|
|
# Create module zip
|
|
zip-module "$MODULE"
|
|
|
|
# Get path to zip file and upload url
|
|
FILE_PATH="tmp/$MODULE_NAME.zip"
|
|
load-env "$1"
|
|
NEXTCLOUD_UPLOAD_URL="$NEXTCLOUD_URL/remote.php/dav/files/$NEXTCLOUD_USERNAME/Odoo-Apps/"
|
|
|
|
# Upload zip file
|
|
curl -u "$NEXTCLOUD_USERNAME:$NEXTCLOUD_PASSWORD" -T "$FILE_PATH" "$NEXTCLOUD_UPLOAD_URL"
|
|
echo "File $FILE_PATH uploaded to $NEXTCLOUD_UPLOAD_URL."
|
|
|
|
UPLOADS+=" - name: $MODULE\n"
|
|
UPLOADS+=" version: $VERSION\n"
|
|
fi
|
|
done
|
|
|
|
echo "odoo_apps:"
|
|
echo -e "$UPLOADS"
|
|
}
|
|
|
|
function logs() {
|
|
$CONTAINER_ENGINE logs --follow odoo
|
|
}
|
|
|
|
# Script Commands
|
|
|
|
function install-odoo-scripts() {
|
|
curl -L https://raw.githubusercontent.com/mint-system/ansible-build/master/roles/odoo_scripts/files/install | bash
|
|
}
|
|
|
|
function upgrade-odoo() {
|
|
if test -z "$1"; then echo "\$1/database is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2/version is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
ODOO_TARGET_VERSION="$2"
|
|
MODE="test"
|
|
if [ -n "$3" ]; then
|
|
# Options: test, production
|
|
MODE="$3"
|
|
fi
|
|
NEW_DATABASE="${DATABASE}_${ODOO_TARGET_VERSION}"
|
|
|
|
echo "Execute Odoo upgrade script in $MODE mode for $DATABASE with version $ODOO_TARGET_VERSION."
|
|
echo "The database will be restored as $NEW_DATABASE."
|
|
export PGHOST=localhost
|
|
export PGUSER=odoo
|
|
export PGPASSWORD=odoo
|
|
python <(curl -s https://upgrade.odoo.com/upgrade) "$MODE" -d "$DATABASE" -t "$ODOO_TARGET_VERSION" -r "$NEW_DATABASE"
|
|
echo "Upgrade finished successfully."
|
|
}
|
|
|
|
# Install Commands
|
|
|
|
function install-native() {
|
|
init-venv
|
|
activate-venv
|
|
|
|
if [[ "$OS_RELEASE" =~ ^(Ubuntu|Debian|Pop!_OS)$ ]]; then
|
|
|
|
# Source: https://gist.github.com/faniska/37f896d5e9de5fee925925d7caf3cb9e
|
|
INSTALLED_VERSION=$(wkhtmltopdf --version 2>&1 | grep -Po '^wkhtmltopdf \K[\d.]+')
|
|
if [ "$INSTALLED_VERSION" != "0.12.4" ]; then
|
|
echo "Install wkhtmltopdf"
|
|
sudo apt remove wkhtmltopdf
|
|
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
|
|
tar xvf wkhtmltox*.tar.xz
|
|
sudo mv wkhtmltox/bin/wkhtmlto* /usr/bin
|
|
rm -rf wkhtmltox wkhtmltox-0.12.4_linux-generic-amd64.tar.*
|
|
else
|
|
echo "wkhtmltopdf version is already 0.12.4"
|
|
fi
|
|
|
|
echo "Install python-ldap and psycopg2 build dependencies"
|
|
sudo apt-get install -y libsasl2-dev libldap2-dev libssl-dev libpq-dev python3-dev
|
|
|
|
echo "Install xmllint and gettext"
|
|
sudo apt install -y libxml2-utils gettext
|
|
|
|
elif [[ "$OS_RELEASE" =~ ^(Darwin)$ ]]; then
|
|
|
|
echo "Welcome daring Mac user. Let's try our best to get this working."
|
|
echo "Install wkhtmltopdf and some dev libraries"
|
|
echo "This will give a depreciation warning and you need to enter your sudo password."
|
|
brew install gettext wkhtmltopdf libsasl2 openldap openssl libxml2
|
|
|
|
echo "Install the binary version of psycopg2"
|
|
uv pip install psycopg2-binary --force
|
|
|
|
echo "Add LDFLAGS to .env file"
|
|
if ! grep -qxF 'LDFLAGS=-L/opt/homebrew/lib/' .env; then
|
|
echo '' >> .env
|
|
echo 'LDFLAGS=-L/opt/homebrew/lib/' >> .env
|
|
fi
|
|
|
|
else
|
|
echo "The operating system $OS_RELEASE is not supported."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Install Odoo development tools"
|
|
uv pip install ${PYTHON_NOTIFY}
|
|
uv pip install -r requirements.txt
|
|
|
|
if [ -f "odoo/requirements.txt" ]; then
|
|
echo "Install Odoo dependencies"
|
|
uv pip install -r odoo/requirements.txt
|
|
|
|
echo "Configure Odoo as python package"
|
|
uv pip install pip
|
|
pip install -e odoo
|
|
fi
|
|
}
|
|
|
|
# Process Commands
|
|
|
|
function open-url-with-delay(){
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if $BROWSER_OPEN; then
|
|
sleep 2
|
|
$OS_OPEN "$1"
|
|
fi
|
|
}
|
|
|
|
function start() {
|
|
activate-venv
|
|
set-addons-path
|
|
template-docker-compose
|
|
|
|
# Use default database if second param is not given
|
|
DATABASE="$2"
|
|
if [ -z "$2" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
if [ -z "$1" ] ; then
|
|
echo "Start odoo container ${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
echo "Open http://localhost:8069 url in your browser."
|
|
$COMPOSE_COMMAND up -d
|
|
fi
|
|
|
|
if [[ "$1" =~ "db" ]]; then
|
|
$COMPOSE_COMMAND up -d db
|
|
fi
|
|
|
|
if [[ "$1" =~ "admin" ]]; then
|
|
echo "Open http://localhost:8000 url in your browser."
|
|
open-url-with-delay "http://localhost:8000" & $COMPOSE_COMMAND up -d admin
|
|
fi
|
|
|
|
if [[ "$1" =~ "odoo" ]]; then
|
|
echo "Start odoo container ${CONTAINER_REGISTRY}${CONTAINER_TAG}"
|
|
echo "Open http://localhost:8069 url in your browser."
|
|
open-url-with-delay "http://localhost:8069" & $COMPOSE_COMMAND up -d odoo
|
|
fi
|
|
|
|
if [[ "$1" =~ "native" ]]; then
|
|
activate-venv
|
|
template-odoo-rc
|
|
PORT=8069
|
|
while [ $PORT -le 8079 ]; do
|
|
if ! lsof -i:$PORT >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
PORT=$((PORT + 1))
|
|
done
|
|
export ODOO_BASE_URL="http://localhost:8069"
|
|
|
|
echo "Open http://localhost:$PORT url in your browser."
|
|
open-url-with-delay "http://localhost:$PORT/web?debug=1&db=$DATABASE" &
|
|
odoo --database="$DATABASE" --config "$ODOO_RC" --xmlrpc-port="$PORT" --addons-path="$ADDONS_PATH" --dev=all --log-level="$LOG_LEVEL"
|
|
fi
|
|
|
|
if [[ "$1" =~ "queue" ]]; then
|
|
activate-venv
|
|
PORT=8069
|
|
echo "Open http://localhost:$PORT url in your browser."
|
|
open-url-with-delay "http://localhost:$PORT/web?debug=1&db=$DATABASE" &
|
|
odoo --database="$DATABASE" --config "$ODOO_RC" --xmlrpc-port="$PORT" --gevent-port=8072 --load=web,queue_job --workers=4 --addons-path="$ADDONS_PATH" --dev=all --log-level="$LOG_LEVEL" --log-handler=odoo.addons.queue_job:DEBUG
|
|
fi
|
|
|
|
if [[ "$1" =~ "mail" ]]; then
|
|
echo "Open http://localhost:8025 url in your browser."
|
|
open-url-with-delay "http://localhost:8025" & $COMPOSE_COMMAND up -d mail
|
|
fi
|
|
}
|
|
|
|
|
|
function remove() {
|
|
activate-venv
|
|
template-docker-compose
|
|
|
|
if test -z "$1"; then
|
|
$COMPOSE_COMMAND down -v
|
|
fi
|
|
|
|
if [[ "$1" =~ "db" ]]; then
|
|
$COMPOSE_COMMAND rm -f -s -v db
|
|
fi
|
|
|
|
if [[ "$1" =~ "admin" ]]; then
|
|
$COMPOSE_COMMAND rm -f -s -v admin
|
|
fi
|
|
|
|
if [[ "$1" =~ "odoo" ]]; then
|
|
$COMPOSE_COMMAND rm -f -s -v odoo
|
|
fi
|
|
|
|
if [[ "$1" =~ "mail" ]]; then
|
|
$COMPOSE_COMMAND rm -f -s -v mail
|
|
fi
|
|
}
|
|
|
|
function restart() {
|
|
activate-venv
|
|
template-docker-compose
|
|
|
|
if test -z "$1"; then
|
|
$COMPOSE_COMMAND restart
|
|
fi
|
|
|
|
if [[ "db|mail|odoo" =~ $1 ]]; then
|
|
$COMPOSE_COMMAND restart "$1"
|
|
fi
|
|
}
|
|
|
|
function stop() {
|
|
activate-venv
|
|
template-docker-compose
|
|
|
|
if test -z "$1"; then
|
|
$COMPOSE_COMMAND stop
|
|
fi
|
|
|
|
$COMPOSE_COMMAND stop "$1"
|
|
}
|
|
|
|
function test-container() {
|
|
activate-venv
|
|
version
|
|
info
|
|
|
|
if [ -z "$GIT_SSH_PRIVATE_KEY" ]; then
|
|
echo "Generate SSH private key."
|
|
mkdir -p tmp
|
|
if [ ! -f "tmp/ed25519" ]; then
|
|
ssh-keygen -t ed25519 -C admin@example.com -f tmp/ed25519 -N ""
|
|
fi
|
|
GIT_SSH_PRIVATE_KEY=$(cat tmp/ed25519 | base64 -w0)
|
|
GIT_SSH_PUBLIC_KEY=$(cat tmp/ed25519.pub)
|
|
fi
|
|
|
|
echo "Clone submodule"
|
|
git submodule update --init oca/partner-contact
|
|
|
|
echo "Start container environment."
|
|
export GIT_SSH_PRIVATE_KEY
|
|
export GIT_SSH_PUBLIC_KEY
|
|
export ADDONS_GIT_REPOS="https://github.com/OCA/server-env.git#${GIT_BRANCH},https://github.com/OCA/server-tools.git#${GIT_BRANCH},https://github.com/Mint-System/Odoo-Apps-Server-Tools.git#${GIT_BRANCH},https://github.com/Mint-System/Odoo-Apps-Connector.git#${GIT_BRANCH}"
|
|
export ODOO_ADDONS_PATH="/mnt/enterprise,/mnt/oca"
|
|
export ODOO_DATABASE=test
|
|
export ODOO_INIT=True
|
|
export ODOO_INIT_LANG=de_CH
|
|
export ODOO_INIT_ADDONS=server_environment_ir_config_parameter,module_auto_update,prometheus_exporter,mail_server_filter,git_base,contacts,web_enterprise
|
|
export PYTHON_INSTALL=prometheus-client,manifestoo
|
|
export SERVER_WIDE_MODULES=session_db,module_change_auto_install
|
|
export SESSION_DB_URI=postgres://odoo:odoo@db/test
|
|
export MODULE_AUTO_INSTALL_DISABLED=odoo_test_xmlrunner
|
|
export CLICK_ODOO_UPDATE=True
|
|
export ODOO_MAIL_SMTP_HOST=mail
|
|
export ODOO_MAIL_SMTP_PORT=1025
|
|
export ODOO_MAIL_SMTP_ENCRYPTION=none
|
|
export MAIL_DEFAULT_FROM="test"
|
|
export BROWSER_OPEN=false
|
|
start db,odoo,mail
|
|
while ! curl --fail -s http://localhost:8069; do sleep 1; done
|
|
|
|
echo "Test auto upgrade."
|
|
docker-odoo-init -d test -i partner_firstname
|
|
sed -i -E 's/(firstname = fields)/secondname = fields.Char();\1/' oca/partner-contact/partner_firstname/models/res_partner.py
|
|
restart odoo
|
|
while ! curl --fail -s http://localhost:8069; do sleep 1; done
|
|
|
|
echo "Check if auto upgrade was successful."
|
|
scripts/odooctl --method "search_one" --model "ir.model.fields" --domain "[('name', '=', 'secondname')]"
|
|
|
|
echo "Setup and test RPC credentials."
|
|
export ODOO_URL="http://localhost:8069"
|
|
export ODOO_USERNAME=admin
|
|
export ODOO_PASSWORD=admin
|
|
create-odoo-env test
|
|
show-env test
|
|
test-xmlrpc test
|
|
|
|
echo "Send mail with message post."
|
|
scripts/odooctl --method "create" --model "res.partner" --value "{'name': 'User', 'email': 'user@example.com'}"
|
|
docker-odoo-shell -d test -f -p "env['res.partner'].browse(3)._message_subscribe([7])"
|
|
docker-odoo-shell -d test -f -p "env['res.partner'].browse(3).message_post(body='ping', subtype_id=1)"
|
|
|
|
echo "Check if receiver is user@example.com"
|
|
TO_ADDRESS=$(curl -X GET "http://localhost:8025/api/v1/messages?limit=1" \
|
|
-H 'accept: application/json' | jq ".messages[0].To[0].Address")
|
|
[ "$TO_ADDRESS" = '"user@example.com"' ]
|
|
echo "Assert: $?"
|
|
|
|
echo "Install, update, disable and remove snippet."
|
|
install-snippet test snippets/base.view_partner_form.show_type.xml
|
|
update-snippet test snippets/base.view_partner_form.show_type.xml
|
|
disable-snippet test snippets/base.view_partner_form.show_type.xml
|
|
remove-snippet test snippets/base.view_partner_form.show_type.xml
|
|
|
|
echo "Test Odoo scripts."
|
|
docker-odoo-backup -d test
|
|
docker-odoo-drop -d test
|
|
docker-odoo-restore -d test -f /var/tmp/test.zip
|
|
change-uuid test
|
|
|
|
echo "Cleanup test environment."
|
|
remove-env test
|
|
git -C oca/partner-contact checkout .
|
|
}
|
|
|
|
# Kubernetes Commands
|
|
|
|
function start-kind() {
|
|
echo "Start kind."
|
|
kind create cluster
|
|
}
|
|
|
|
function start-minikube() {
|
|
echo "Start minikube."
|
|
minikube start
|
|
}
|
|
|
|
function k8s-apply() {
|
|
echo "Deploy Postgres:"
|
|
kubectl apply -f k8s/postgres-cm.yaml
|
|
kubectl apply -f k8s/postgres-pvc.yaml
|
|
kubectl apply -f k8s/postgres-deploy.yaml
|
|
kubectl apply -f k8s/postgres-svc.yaml
|
|
|
|
echo -e "\nDeploy Odoo:"
|
|
kubectl apply -f k8s/odoo-cm.yaml
|
|
kubectl apply -f k8s/odoo16-deploy.yaml
|
|
kubectl apply -f k8s/odoo-svc.yaml
|
|
|
|
|
|
echo -e "\nWait until resources are ready."
|
|
sleep 8
|
|
|
|
ODOO_POD=$(kubectl get pods -o=name --all-namespaces | grep odoo)
|
|
POSTGRES_POD=$(kubectl get pods -o=name --all-namespaces | grep postgres)
|
|
|
|
echo -e "\nWait for $ODOO_POD and $POSTGRES_POD pods to be running:"
|
|
kubectl wait --for=condition=Ready "$ODOO_POD" "$POSTGRES_POD" --timeout=60s
|
|
sleep 3
|
|
|
|
echo -e "\nInit Odoo database in $ODOO_POD pod:"
|
|
kubectl exec "$ODOO_POD" -- env
|
|
kubectl exec "$ODOO_POD" -- /bin/bash -c "odoo -d odoo -i web --db_host \$HOST -r\$USER -w\$PASSWORD --stop-after-init --no-http"
|
|
}
|
|
|
|
function test-k8s() {
|
|
start-kind
|
|
k8s-apply
|
|
}
|
|
|
|
# Interactive Shell Commands
|
|
|
|
function start-shell() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
odoo shell --database "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --no-http
|
|
}
|
|
|
|
function start-psql() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
$CONTAINER_ENGINE exec -it db psql "postgres://odoo:odoo@localhost:5432/$DATABASE"
|
|
}
|
|
|
|
# Database Commands
|
|
|
|
function init-db() {
|
|
ODOO_INIT_ADDONS="${ODOO_INIT_ADDONS:-"web"}"
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
template-odoo-rc
|
|
|
|
echo "Initialize database $DATABASE with $ODOO_INIT_ADDONS."
|
|
if [[ -n "$ODOO_PARAM" ]]; then
|
|
odoo -d "$DATABASE" -i "$ODOO_INIT_ADDONS" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http --load-language "$ODOO_LANGUAGE" "$ODOO_PARAM"
|
|
else
|
|
odoo -d "$DATABASE" -i "$ODOO_INIT_ADDONS" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http --load-language "$ODOO_LANGUAGE"
|
|
fi
|
|
}
|
|
|
|
function import-csv() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
FILE_PATH="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
FILE_PATH="$1"
|
|
fi
|
|
|
|
FILE_NAME=$(basename "$FILE_PATH")
|
|
echo "Importing $FILE_NAME to $DATABASE ..."
|
|
$CONTAINER_ENGINE cp "$FILE_PATH" db:/tmp/
|
|
$CONTAINER_ENGINE exec db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "\copy $FILE_NAME FROM '/tmp/$FILE_NAME' DELIMITER ',' CSV HEADER;"
|
|
}
|
|
|
|
function drop-db() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/postgres" -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DATABASE';"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/postgres" -c "DROP DATABASE \"$DATABASE\";"
|
|
}
|
|
|
|
function setup-mail() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
|
|
export ODOO_MAIL_SMTP_HOST="localhost"
|
|
export ODOO_MAIL_SMTP_PORT="1025"
|
|
export ODOO_MAIL_SMTP_ENCRYPTION="none"
|
|
export ODOO_MAIL_IMAP_PORT="993"
|
|
export ODOO_MAIL_IMAP_SSL="True"
|
|
PYTHON_SCRIPT=$(envsubst < scripts/setup-mail)
|
|
|
|
echo "Setup mail server configuation for database $DATABASE."
|
|
echo "$PYTHON_SCRIPT" | odoo shell --database "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --no-http
|
|
}
|
|
|
|
function setup-mail-sql() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
|
|
if [ -n "$ODOO_MAIL_SMTP_HOST" ]; then
|
|
ODOO_MAIL_SMTP_PORT=${ODOO_MAIL_SMTP_PORT:="587"}
|
|
ODOO_MAIL_SMTP_ENCRYPTION=${ODOO_MAIL_SMTP_ENCRYPTION:="starttls"}
|
|
ODOO_MAIL_SMTP_FROM_FILTER=${ODOO_MAIL_SMTP_FROM_FILTER:=""}
|
|
|
|
IR_MAIL_SERVER_ID=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT id FROM ir_mail_server WHERE name = '$ODOO_MAIL_SMTP_HOST' LIMIT 1")
|
|
if [ -z "$IR_MAIL_SERVER_ID" ]; then
|
|
echo "Setup outgoing mail server $ODOO_MAIL_SMTP_HOST for database $DATABASE."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "INSERT INTO ir_mail_server (active, name, smtp_host, smtp_port, smtp_user, smtp_pass, smtp_encryption, from_filter, smtp_authentication) VALUES (TRUE, '$ODOO_MAIL_SMTP_HOST', '$ODOO_MAIL_SMTP_HOST', $ODOO_MAIL_SMTP_PORT, '$ODOO_MAIL_USERNAME', '$ODOO_MAIL_PASSWORD', '$ODOO_MAIL_SMTP_ENCRYPTION', '$ODOO_MAIL_SMTP_FROM_FILTER', 'login')"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$ODOO_MAIL_IMAP_HOST" ]; then
|
|
ODOO_MAIL_IMAP_PORT=${ODOO_MAIL_IMAP_PORT:="993"}
|
|
ODOO_MAIL_IMAP_SSL=${ODOO_MAIL_IMAP_SSL:="True"}
|
|
|
|
FETCHMAIL_SERVER_ID=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT id FROM fetchmail_server WHERE name = '$ODOO_MAIL_SMTP_HOST' LIMIT 1")
|
|
if [ -z "$FETCHMAIL_SERVER_ID" ]; then
|
|
echo "Setup incoming mail server $ODOO_MAIL_IMAP_HOST for database $DATABASE."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "INSERT INTO fetchmail_server (\"active\", \"name\", \"server\", \"port\", \"user\", \"password\", \"is_ssl\", \"server_type\", \"state\") VALUES (TRUE, '$ODOO_MAIL_SMTP_HOST', '$ODOO_MAIL_IMAP_HOST', $ODOO_MAIL_IMAP_PORT, '$ODOO_MAIL_USERNAME', '$ODOO_MAIL_PASSWORD', $ODOO_MAIL_IMAP_SSL, 'imap', 'done')"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$MAIL_CATCHALL_ALIAS" ]; then
|
|
MAIL_CATCHALL_ALIAS_VALUE=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT value FROM ir_config_parameter WHERE key = 'mail.catchall.alias'")
|
|
if [ "$MAIL_CATCHALL_ALIAS_VALUE" != "$MAIL_CATCHALL_ALIAS" ]; then
|
|
echo "Update system parameter mail.catchall.alias with value $MAIL_CATCHALL_ALIAS."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "UPDATE ir_config_parameter SET value = '$MAIL_CATCHALL_ALIAS' WHERE key = 'mail.catchall.alias'"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$MAIL_DEFAULT_FROM" ]; then
|
|
MAIL_DEFAULT_FROM_VALUE=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT value FROM ir_config_parameter WHERE key = 'mail.default.from'")
|
|
if [ "$MAIL_DEFAULT_FROM_VALUE" != "$MAIL_DEFAULT_FROM" ]; then
|
|
echo "Update system parameter mail.default.from with value $MAIL_DEFAULT_FROM."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "UPDATE ir_config_parameter SET value = '$MAIL_DEFAULT_FROM' WHERE key = 'mail.default.from'"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$MAIL_CATCHALL_DOMAIN" ]; then
|
|
MAIL_CATCHALL_DOMAIN_KEY=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT id FROM ir_config_parameter WHERE key = 'mail.catchall.domain'")
|
|
if [ -z "$MAIL_CATCHALL_DOMAIN_KEY" ]; then
|
|
echo "Add system parameter mail.catchall.domain with value $MAIL_CATCHALL_DOMAIN."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "INSERT INTO ir_config_parameter (key, value) VALUES ('mail.catchall.domain', '$MAIL_CATCHALL_DOMAIN')"
|
|
fi
|
|
MAIL_CATCHALL_DOMAIN_VALUE=$($CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -tAc "SELECT value FROM ir_config_parameter WHERE key = 'mail.catchall.domain'")
|
|
if [ "$MAIL_CATCHALL_DOMAIN_VALUE" != "$MAIL_CATCHALL_DOMAIN" ]; then
|
|
echo "Update system parameter mail.catchall.domain with value $MAIL_CATCHALL_DOMAIN."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "UPDATE ir_config_parameter SET value = '$MAIL_CATCHALL_DOMAIN' WHERE key = 'mail.catchall.domain'"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function load-language() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
LANGUAGE="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
LANGUAGE="$1"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Setup language $LANGUAGE for database $DATABASE:"
|
|
odoo -d "$DATABASE" -u all --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http --load-language "$LANGUAGE"
|
|
}
|
|
|
|
function set-admin() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "UPDATE res_users SET active=true,password='\$pbkdf2-sha512\$25000\$JuScEwIg5JzTGqNUivFeqw\$yWTOcix2Afr3XGP2NPY7w4w49e9vpsu14NRndDYXAkbtMF4zkrmx6inVsoLl0zZY30xI/0GzhwonWsK9TUmjWA' WHERE id=2;"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost:5432/$DATABASE" -c "SELECT login, password FROM res_users WHERE id=2;"
|
|
}
|
|
|
|
function clear-assets() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
echo "Delete these assets for $DATABASE:"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "select id,name from ir_attachment where res_model='ir.ui.view' and name like '%assets_%';"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "delete from ir_attachment where res_model='ir.ui.view' and name like '%assets_%';"
|
|
}
|
|
|
|
function clear-views() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
echo "Archive views with prefix 'mint_system'."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "SELECT id,name from ir_ui_view WHERE name like '%mint_system%';"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "UPDATE ir_ui_view SET active=false WHERE name like '%mint_system%';"
|
|
|
|
echo "Archive views with prefix 'Odoo Studio:'."
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "SELECT id,name from ir_ui_view WHERE name like '%Odoo Studio:%';"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "UPDATE ir_ui_view SET active=false WHERE name like '%Odoo Studio:%';"
|
|
|
|
echo "Delete all active views for $DATABASE in $CONTAINER :"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "DELETE FROM report_layout WHERE view_id IN (SELECT id FROM ir_ui_view WHERE active = TRUE);"
|
|
$CONTAINER_ENGINE exec -i db psql "postgres://odoo:odoo@localhost/$DATABASE" -c "WITH RECURSIVE views_to_delete AS (SELECT id, inherit_id FROM ir_ui_view WHERE active = TRUE AND inherit_id IS NULL UNION ALL SELECT v.id, v.inherit_id FROM ir_ui_view v JOIN views_to_delete p ON v.inherit_id = p.id) DELETE FROM ir_ui_view WHERE id IN (SELECT id FROM views_to_delete);"
|
|
}
|
|
|
|
function convert-database() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
unzip "tmp/$1.zip" -d "./tmp/$1"
|
|
sed -i'' 's/AS integer//g' "./tmp/$1/dump.sql"
|
|
grep -i 'as integer' "./tmp/$1/dump.sql"
|
|
cd "tmp/$1" || exit ; zip -r "../${1}2.zip" . ; cd ../.. || exit
|
|
rm -r "tmp/$1"
|
|
echo "Converted database file $1 to ${1}2"
|
|
}
|
|
|
|
function clear-filestore() {
|
|
echo "Remove directory $HOME/.local/share/Odoo/filestore/$1"
|
|
rm -rf "$HOME/.local/share/Odoo/filestore/$1"
|
|
}
|
|
|
|
function disable-mailserver() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
scripts/odooctl --method 'write' --model 'ir.mail_server' --field 'active' --value False --domain "[]"
|
|
scripts/odooctl --method 'write' --model 'fetchmail.server' --field 'active' --value False --domain "[]"
|
|
}
|
|
|
|
function change-uuid() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
UUID=$(uuidgen)
|
|
echo "Set uuid $UUID for $1."
|
|
scripts/odooctl --method 'write' --model 'ir.config_parameter' --domain "[('key', '=', 'database.uuid')]" --field 'value' --value "'$UUID'"
|
|
}
|
|
|
|
function update-app-list() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "env['ir.module.module'].update_list()" | odoo shell --database "$1" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --no-http
|
|
}
|
|
|
|
function patch-database() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
FILENAME="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
FILENAME="$1"
|
|
fi
|
|
|
|
echo "Apply patch $FILENAME to Database $DATABASE."
|
|
cat "$FILENAME" | $CONTAINER_ENGINE exec -i db psql "postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost/$DATABASE"
|
|
echo "Patching database succeeded"
|
|
}
|
|
|
|
function save-config() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
odoo -d "$DATABASE" -s --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http
|
|
}
|
|
|
|
# Report Commands
|
|
|
|
function odoo-cloc() {
|
|
DATABASE="$1"
|
|
if [ -z "$DATABASE" ]; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
odoo cloc -d "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http
|
|
}
|
|
|
|
function visualize-dependencies() {
|
|
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
MODULE_DIR="$1"
|
|
OUTPUT_FILE="tmp/module_dependencies.mmd"
|
|
mkdir -p tmp
|
|
echo "graph TD" > "$OUTPUT_FILE"
|
|
|
|
for MODULE_PATH in "$MODULE_DIR"/*; do
|
|
if [[ -d "$MODULE_PATH" ]]; then
|
|
MODULE_NAME=$(basename "$MODULE_PATH")
|
|
MANIFEST_FILE="$MODULE_PATH/__manifest__.py"
|
|
if [[ -f $MANIFEST_FILE ]]; then
|
|
DEPENDENCIES=$(grep -Po '(?<="depends": \[)[^\]]*' "$MANIFEST_FILE" | tr -d '"[] ')
|
|
if [[ -n "$DEPENDENCIES" ]]; then
|
|
for DEPENDENCY in $(echo "$DEPENDENCIES" | tr ',' '\n'); do
|
|
echo " $MODULE_NAME --> $DEPENDENCY" >> "$OUTPUT_FILE"
|
|
done
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo "Mermaid output generated: $OUTPUT_FILE"
|
|
echo "Run mermaid-cli with npx and open png file ..."
|
|
|
|
npx @mermaid-js/mermaid-cli -i $OUTPUT_FILE -o tmp/module_dependencies.png --scale 10
|
|
$OS_OPEN tmp/module_dependencies.png
|
|
}
|
|
|
|
# Module Development Commands
|
|
|
|
function install-requirements() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
FILE_PATH="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
FILE_PATH="$1"
|
|
fi
|
|
|
|
FILE_NAME=$(basename "$FILE_PATH")
|
|
if [[ "$FILE_NAME" != "requirements.txt" ]]; then echo "\$1 must point to requirements.txt file."; exit; fi
|
|
|
|
CONTAINER_RUNNING=$($CONTAINER_ENGINE container inspect -f '{{.State.Running}}' odoo)
|
|
if [ "$CONTAINER_RUNNING" == "true" ]; then
|
|
echo "Installing python packages in container ..."
|
|
$CONTAINER_ENGINE exec -u root odoo python -m pip install -r "/mnt/$FILE_PATH"
|
|
else
|
|
activate-venv
|
|
echo "Installing python packages in virutal env ..."
|
|
uv pip install -r "$FILE_PATH"
|
|
fi
|
|
}
|
|
|
|
function init-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
MODULE_PATH="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_PATH="$1"
|
|
fi
|
|
|
|
# Check if module path is a module repo
|
|
if [ -f "$MODULE_PATH/README.md" ]; then
|
|
|
|
# Look for manifest files in repo folder
|
|
# Get parent folder name of manifest files
|
|
# Create a comma separated string of folder names
|
|
MODULES=$(get-modules "$MODULE_PATH" basename)
|
|
else
|
|
MODULES=$(basename "$MODULE_PATH")
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Initialize module $MODULES on $DATABASE ..."
|
|
odoo -d "$DATABASE" -i "$MODULES" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http
|
|
}
|
|
|
|
function upgrade-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
activate-venv
|
|
echo "Upgrade code of module $1 from $2 ..."
|
|
odoo upgrade_code --addons-path "$1" --from "$2"
|
|
}
|
|
|
|
function update-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
MODULE_NAME=$(basename "$2")
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_NAME=$(basename "$1")
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Updating module $MODULE_NAME on $DATABASE ..."
|
|
if [[ -n "$ODOO_PARAM" ]] ; then
|
|
odoo --database "$DATABASE" --update "$MODULE_NAME" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http "$ODOO_PARAM"
|
|
else
|
|
odoo --database "$DATABASE" --update "$MODULE_NAME" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http
|
|
fi
|
|
}
|
|
|
|
function translate-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
MODULE_PATH="$2"
|
|
MODULE_NAME=$(basename "$2")
|
|
LANGUAGE="$3"
|
|
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_PATH="$1"
|
|
MODULE_NAME=$(basename "$1")
|
|
fi
|
|
|
|
if test -z "$3"; then
|
|
LANGUAGE="$ODOO_LANGUAGE"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Generate $LANGUAGE tranlsation file for $MODULE_NAME on $DATABASE ..."
|
|
mkdir -p "$MODULE_PATH/i18n/"
|
|
odoo -d "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --modules "$MODULE_NAME" -l "$LANGUAGE" --i18n-export "$MODULE_PATH/i18n/$LANGUAGE.po"
|
|
# if lang is de_CH then rename the file to de.po.
|
|
if [[ "$LANGUAGE" == "de_CH" ]]; then
|
|
mv "$MODULE_PATH/i18n/$LANGUAGE.po" "$MODULE_PATH/i18n/de.po"
|
|
fi
|
|
}
|
|
|
|
function lint-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
activate-venv
|
|
|
|
echo "Set file and folder permissions on $1"
|
|
find "$1" -type d -exec chmod u=rwx,go=rx {} \;
|
|
find "$1" -type f -exec chmod u=rw,go=r {} \;
|
|
|
|
echo "Update index.html"
|
|
rst2html5 "$1/README.rst" "$1/static/description/index.html"
|
|
|
|
pushd .
|
|
cd "$1"
|
|
|
|
echo "Run pre-commit in $PWD"
|
|
pre-commit run --all-files # --show-diff-on-failure --color=always
|
|
|
|
echo "Stage changes"
|
|
git add .
|
|
|
|
popd
|
|
}
|
|
|
|
function lint-module-repo() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
MODULE_PATHS=$(get-modules "$MODULE_PATH")
|
|
|
|
for MODULE_PATH in ${MODULE_PATHS//,/ }; do
|
|
lint-module "$MODULE_PATH"
|
|
done
|
|
}
|
|
|
|
function test-module() {
|
|
DATABASE="$1"
|
|
MODULE_NAME=$(basename "$2")
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_NAME=$(basename "$1")
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Testing module $MODULE_NAME on $DATABASE ..."
|
|
odoo -d "$DATABASE" -i "$MODULE_NAME" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --stop-after-init --no-http --test-tags /"$MODULE_NAME"
|
|
}
|
|
|
|
function test-module-repo() {
|
|
DATABASE="$1"
|
|
MODULE_PATH="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_PATH="$1"
|
|
fi
|
|
|
|
MODULES=$(get-modules "$MODULE_PATH" basename)
|
|
|
|
for MODULE in ${MODULES//,/ }; do
|
|
echo "Testing module $MODULE ..."
|
|
test-module "$DATABASE" "$MODULE"
|
|
done
|
|
}
|
|
|
|
function pytest-module() {
|
|
DATABASE="$1"
|
|
MODULE_PATH="$2"
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_PATH="$1"
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
|
|
ODOO_CONFIG="tmp/odoo.conf"
|
|
echo "Write $ODOO_CONFIG"
|
|
|
|
echo "[options]" > "$ODOO_CONFIG"
|
|
echo "addons_path=$ADDONS_PATH" >> "$ODOO_CONFIG"
|
|
echo "db_host = localhost" >> "$ODOO_CONFIG"
|
|
echo "db_password = odoo" >> "$ODOO_CONFIG"
|
|
echo "db_user = odoo" >> "$ODOO_CONFIG"
|
|
|
|
pytest -s --odoo-http --odoo-config="$ODOO_CONFIG" --odoo-database="$DATABASE" "$MODULE_PATH"
|
|
}
|
|
|
|
function remove-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
MODULE_NAME=$(basename "$2")
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
MODULE_NAME=$(basename "$1")
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Remove module $MODULE_NAME"
|
|
echo "self.env['ir.module.module'].search([('name', '=', '$MODULE_NAME')]).button_immediate_uninstall()" |
|
|
odoo shell --database "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --no-http
|
|
}
|
|
|
|
function create-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
MODULE_NAME=$(basename "$1")
|
|
PARENT_DIR=$(dirname "$1")
|
|
|
|
activate-venv
|
|
echo "Scaffolding module $MODULE_NAME in $PARENT_DIR ..."
|
|
odoo scaffold "$MODULE_NAME" "$PARENT_DIR" -t templates/module
|
|
}
|
|
|
|
function create-module-repo() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
REPO_PATH="$1"
|
|
REPO_NAME=$(basename "$REPO_PATH")
|
|
|
|
# If repo already exists, create new branch
|
|
if [ -d "$REPO_PATH/.git" ]; then
|
|
echo "Create new branch $REPO_NAME in $REPO_PATH"
|
|
cd "$REPO_PATH" || exit
|
|
git switch --orphan -c "$GIT_BRANCH"
|
|
|
|
echo "Remove all files from $REPO_PATH"
|
|
rm -rf "$REPO_PATH/*"
|
|
fi
|
|
|
|
echo "Copy template files from templates/GIT_BRANCH to $REPO_PATH"
|
|
cp templates/GIT_BRANCH/* "$REPO_PATH"
|
|
}
|
|
|
|
function generate-module-security() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
MODULE_NAME=$(basename "$1")
|
|
PARENT_DIR=$(dirname "$1")
|
|
MODEL_DOT_NAME="$2"
|
|
MODEL_NAME=$(echo "$MODEL_DOT_NAME" | tr '.' '_')
|
|
|
|
ACCESS_FILE="$PARENT_DIR/$MODULE_NAME/security/ir.model.access.csv"
|
|
mkdir -p "$PARENT_DIR/$MODULE_NAME/security"
|
|
|
|
if [ ! -f "$ACCESS_FILE" ]; then
|
|
echo "Init security file: $ACCESS_FILE"
|
|
echo "id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink" > "$ACCESS_FILE"
|
|
fi
|
|
|
|
# id
|
|
# name
|
|
# model_id:id
|
|
# group_id:id
|
|
# perm_read
|
|
# perm_write
|
|
# perm_create
|
|
# perm_unlink
|
|
|
|
echo "Add model access to $ACCESS_FILE"
|
|
echo "access_${MODEL_NAME}_user,access.$MODEL_DOT_NAME.user,model_${MODEL_NAME},base.group_user,1,0,0,0" >> "$ACCESS_FILE"
|
|
echo "access_${MODEL_NAME}_manager,access.$MODEL_DOT_NAME.manager,model_${MODEL_NAME},base.group_erp_manager,1,1,1,1" >> "$ACCESS_FILE"
|
|
}
|
|
|
|
function generate-module-model() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
MODULE_PATH="$1"
|
|
MODULE_NAME=$(basename "$1")
|
|
|
|
# Generate template values
|
|
MODEL_DOT_NAME="$2" # res.partner
|
|
MODEL_NAME=$(echo "$MODEL_DOT_NAME" | tr '.' '_') # res_partner
|
|
NAME=$(echo "$MODEL_DOT_NAME" | cut -d"." -f2 | sed 's/[^_]\+/\L\u&/g') # Partners
|
|
MODEL_DESCRIPTION=$(echo "$MODEL_NAME" | sed 's/[^_]\+/\L\u&/g' | sed 's/_/ /g') # Res Partner
|
|
MODEL_CAMEL_NAME=$(echo "$MODEL_DESCRIPTION" | sed 's/ //g') # ResPartner
|
|
export NAME MODULE_NAME MODEL_DOT_NAME MODEL_NAME MODEL_DESCRIPTION MODEL_CAMEL_NAME
|
|
|
|
echo "Substitute model template"
|
|
envsubst '$NAME $MODULE_NAME $MODEL_DOT_NAME $MODEL_NAME $MODEL_DESCRIPTION $MODEL_CAMEL_NAME' < templates/model.py > "$MODULE_PATH/models/$MODEL_NAME.py"
|
|
echo "from . import $MODEL_NAME" >> "$MODULE_PATH/models/__init__.py"
|
|
|
|
echo "Substitute view template"
|
|
mkdir -p "$MODULE_PATH/views"
|
|
envsubst '$NAME $MODULE_NAME $MODEL_DOT_NAME $MODEL_NAME $MODEL_DESCRIPTION $MODEL_CAMEL_NAME' < templates/model_views.xml > "$MODULE_PATH/views/${MODEL_NAME}_views.xml"
|
|
echo "Update file $MODULE_NAME/__manifest__.py with:"
|
|
echo -e "\t\"views/${MODEL_NAME}_views.xml\","
|
|
}
|
|
|
|
function generate-module-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
MODULE_PATH="$1"
|
|
VIEW_REF="$2"
|
|
|
|
# Generate template values
|
|
MODEL_NAME="crm_lead"
|
|
MODEL_DOT_NAME="crm.lead"
|
|
MODULE_NAME=$(basename "$1")
|
|
SRC_MODULE_NAME=$(echo "$VIEW_REF" | cut -d"." -f1)
|
|
XML_ID=$(echo "$VIEW_REF" | cut -d"." -f1)
|
|
export MODULE_NAME MODEL_DOT_NAME SRC_MODULE_NAME XML_ID
|
|
|
|
echo "Substitute snippet template"
|
|
envsubst '$MODULE_NAME $MODEL_DOT_NAME $SRC_MODULE_NAME $XML_ID' < templates/model_snippet.xml > "$MODULE_PATH/views/$MODEL_NAME_views.xml"
|
|
echo "Update file $MODULE_NAME/__manifest__.py with:"
|
|
echo -e "\t, \"views/${MODEL_NAME}_views.xml\""
|
|
}
|
|
|
|
function release-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
VERSION=$(get-module-version "$1")
|
|
cd "$1" || exit
|
|
LAST_TAG=$(git describe --tags)
|
|
RELEASE_NOTES=$(git log "$LAST_TAG"..HEAD --oneline)
|
|
|
|
echo "Tag with v$VERSION ..."
|
|
git tag -a "v$VERSION" -m "v$VERSION"
|
|
|
|
echo "Release notes:"
|
|
echo "$RELEASE_NOTES"
|
|
}
|
|
|
|
function zip-module() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
# Get version and module name
|
|
VERSION=$(get-module-version "$1")
|
|
MODULE=$(basename "$1")
|
|
|
|
# Copy module to tmp folder
|
|
echo "Copy module $MODULE version $VERSION to tmp folder"
|
|
MODULE_NAME="$MODULE-$VERSION"
|
|
MODULE_PATH="tmp/$MODULE_NAME"
|
|
rm -rf "$MODULE_PATH"
|
|
mkdir -p "$MODULE_PATH"
|
|
cp -r "$1/." "$MODULE_PATH"
|
|
find "$MODULE_PATH" -type d -exec chmod u=rwx,go=rx {} \;
|
|
find "$MODULE_PATH" -type f -exec chmod u=rw,go=r {} \;
|
|
|
|
# Configure and zip module
|
|
echo "Remove auto install option"
|
|
sed -i'' -e "s/'auto_install': True,/'auto_install': False,/" "$MODULE_PATH/__manifest__.py"
|
|
echo "Remove pycache and hidden folders"
|
|
find "$MODULE_PATH" | grep -E "(\.git|__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
|
|
echo "Zip module $MODULE"
|
|
cd tmp || exit
|
|
rm -f "$MODULE_NAME".zip
|
|
zip -q -r "$MODULE_NAME".zip "$MODULE_NAME"
|
|
cd .. || exit
|
|
}
|
|
|
|
# Snippet Commands
|
|
|
|
function reset-views() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
DATABASE="$1"
|
|
KEY=$(basename "$2")
|
|
|
|
# Use default database if second param is not given
|
|
if test -z "$2"; then
|
|
DATABASE="$ODOO_DATABASE"
|
|
KEY=$(basename "$1")
|
|
fi
|
|
|
|
activate-venv
|
|
set-addons-path
|
|
echo "Reset views for key $KEY"
|
|
echo "self.env['ir.ui.view'].search([('key', 'ilike', '$KEY')]).reset_arch(mode='hard')" |
|
|
odoo shell --database "$DATABASE" --config "$ODOO_RC" --addons-path="$ADDONS_PATH" --no-http
|
|
}
|
|
|
|
function create-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
export INHERIT_ID=$(echo "$1" | cut -d. -f1-2)
|
|
FILE="snippets/$1.xml"
|
|
|
|
echo "Create snippet from template: $FILE"
|
|
envsubst '$INHERIT_ID' < templates/snippet.xml > "$FILE"
|
|
}
|
|
|
|
function install-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
# Generate view name from filename
|
|
FILE=$(basename "$2")
|
|
NAME="mint_system.${FILE%.xml}"
|
|
INHERIT_ID=$(echo 'cat //data/@inherit_id' | xmllint --shell "$2" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
TYPE=$(echo 'cat //data/@type' | xmllint --shell "$2" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
MODEL=$(echo 'cat //data/@model' | xmllint --shell "$2" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
PRIORITY=$(echo 'cat //data/@priority' | xmllint --shell "$2" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
MODULE_NAME=$(echo "$INHERIT_ID" | cut -d. -f 1 )
|
|
XML_ID=$(echo "$INHERIT_ID" | cut -d. -f 2 )
|
|
|
|
# Set default values
|
|
: ${TYPE:='qweb'}
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
echo "Search for view with name $MODULE_NAME.$XML_ID"
|
|
INHERIT_ID=$(scripts/odooctl --method "read" --model "ir.model.data" --field "res_id" --domain "[('name', '=', '$XML_ID'), ('module', '=', '$MODULE_NAME')]")
|
|
echo "Found view id $INHERIT_ID"
|
|
|
|
echo "Apply view $NAME"
|
|
scripts/odooctl --method 'create' --model 'ir.ui.view' --value "{
|
|
'name': '$NAME',
|
|
'type': '$TYPE',
|
|
'model': '$MODEL',
|
|
'mode': 'extension',
|
|
'priority': $PRIORITY,
|
|
'inherit_id': $INHERIT_ID,
|
|
'arch_base': '''$(cat "$2")'''
|
|
}"
|
|
}
|
|
|
|
function update-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
# Generate view name from filename
|
|
FILE=$(basename "$2")
|
|
NAME="mint_system.${FILE%.xml}"
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
echo "Update view with name $NAME"
|
|
scripts/odooctl --method 'write' --model 'ir.ui.view' --domain "[('name', '=', '$NAME')]" --field 'arch_base' --value "'''$(cat "$2")'''"
|
|
}
|
|
|
|
function disable-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
# Generate view name from filename
|
|
FILE=$(basename "$2")
|
|
NAME="mint_system.${FILE%.xml}"
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
echo "Disable view with name $NAME"
|
|
scripts/odooctl --method 'write' --model "ir.ui.view" --domain "[('name', '=', '$NAME')]" --field "active" --value "False"
|
|
}
|
|
|
|
function remove-snippet() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
# Generate view name from filename
|
|
FILE=$(basename "$2")
|
|
NAME="mint_system.${FILE%.xml}"
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
echo "Remove view with name $NAME"
|
|
scripts/odooctl --method "unlink" --model "ir.ui.view" --domain "[('name', '=', '$NAME')]"
|
|
}
|
|
|
|
function lint-snippets() {
|
|
|
|
echo "Lint snippets files ..."
|
|
|
|
FILES="snippets/*.xml"
|
|
|
|
for FILE in $FILES; do
|
|
|
|
# Access various snippet parameters
|
|
FILENAME=$(basename "$FILE")
|
|
SNIPPET_MODULE=$(echo "$FILENAME" | cut -d. -f1)
|
|
REPORT=$(echo "$FILENAME" | cut -d. -f2)
|
|
EDIT=$(echo "$FILENAME" | cut -d. -f3)
|
|
INHERIT_ID=$(echo 'cat //data/@inherit_id' | xmllint --shell "$FILE" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
TYPE=$(echo 'cat //data/@type' | xmllint --shell "$FILE" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
MODEL=$(echo 'cat //data/@model' | xmllint --shell "$FILE" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
PRIORITY=$(echo 'cat //data/@priority' | xmllint --shell "$FILE" | awk -F'[="]' '!/>/{print $(NF-1)}')
|
|
MODULE_NAME=$(echo "$INHERIT_ID" | cut -d. -f 1 )
|
|
XML_ID=$(echo "$INHERIT_ID" | cut -d. -f 2 )
|
|
|
|
# Check filename
|
|
COUNT_DOTS=$(echo "$FILENAME" | grep -o "\." | wc -l)
|
|
if [ "$COUNT_DOTS" -ge 4 ]; then
|
|
echo "Linting failed for $FILE"
|
|
echo "Dots count: $COUNT_DOTS"
|
|
echo " Filename: $SNIPPET_MODULE.$REPORT"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if inherit id matches the filename
|
|
if [ -n "$INHERIT_ID" ]; then
|
|
if [[ "$INHERIT_ID" != "$SNIPPET_MODULE.$REPORT" ]]; then
|
|
echo "Linting failed for $FILE"
|
|
echo " Inherit: $INHERIT_ID"
|
|
echo "Filename: $SNIPPET_MODULE.$REPORT"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Check if priority is set
|
|
if [ -z "$PRIORITY" ] && [ -n "$INHERIT_ID" ]; then
|
|
echo "Linting failed for $FILE"
|
|
echo "No priority is set."
|
|
exit 1
|
|
fi
|
|
done
|
|
echo "No problems with snippets found."
|
|
}
|
|
|
|
# Git Commands
|
|
|
|
function git-fetch() {
|
|
git fetch origin 13.0
|
|
git fetch origin 14.0
|
|
git fetch origin 15.0
|
|
git fetch origin 16.0
|
|
git fetch origin 17.0
|
|
git fetch origin 18.0
|
|
}
|
|
|
|
function git-submodule-add() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
if test -z "$2"; then echo "\$2 is empty."; exit; fi
|
|
|
|
git submodule add -f -b "$GIT_BRANCH" "$1" "$2"
|
|
}
|
|
|
|
function git-submodule-ls() {
|
|
echo $(git config --file .gitmodules --get-regexp url | sed -e 's/submodule.//g' -e 's/.url.*//g')
|
|
}
|
|
|
|
function git-submodule-list() {
|
|
# git submodule foreach --quiet 'printf "%-30s %-20s\n" "$name" "$(git rev-parse --abbrev-ref HEAD)"'
|
|
git config --file .gitmodules --get-regexp url | sed -e 's/submodule.//g' -e 's/.url//g' | awk '{ print $1 "," $2}'
|
|
}
|
|
|
|
function git-submodule-delete() {
|
|
echo "Delete git submodules."
|
|
|
|
# Using "git submodule update --init --recursive" is not possible as modules are registered from different branches
|
|
SUBMODULES=$(git-submodule-ls)
|
|
for SUBMODULE in $SUBMODULES; do
|
|
echo "Delete submodule: $SUBMODULE"
|
|
rm -rf "$SUBMODULE"
|
|
done
|
|
}
|
|
|
|
function git-submodule-remove() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
echo "Deinit submodule"
|
|
git submodule deinit -f "$1"
|
|
|
|
echo "Move submodule to tmp folder"
|
|
mkdir -p tmp/"$1"
|
|
mv "$1" tmp/"$1"
|
|
|
|
echo "Remove submodule from work tree"
|
|
git rm -f "$1"
|
|
|
|
echo "Remove submodule from .git folder"
|
|
rm -rf .git/modules/"$1"
|
|
}
|
|
|
|
function git-submodule-init() {
|
|
echo "Init git submodules."
|
|
|
|
# Using "git submodule update --init --recursive" is not possible as modules are registered from different branches
|
|
SUBMODULES=$(git-submodule-ls)
|
|
for SUBMODULE in $SUBMODULES; do
|
|
SHALLOW=$(git config --file .gitmodules --get-regexp submodule."$SUBMODULE".shallow | awk '{ print $2 }')
|
|
if [ "$SHALLOW" = "true" ]; then
|
|
echo "Initializing submodule: $SUBMODULE (shallow)"
|
|
git submodule update --init --depth 1 "$SUBMODULE"
|
|
else
|
|
echo "Initializing submodule: $SUBMODULE"
|
|
git submodule update --init "$SUBMODULE"
|
|
fi
|
|
done
|
|
}
|
|
|
|
function git-submodule-pull() {
|
|
echo "Pull git submodules"
|
|
SUBMODULES=$(git-submodule-ls)
|
|
for SUBMODULE in $SUBMODULES; do
|
|
echo "Pull git submodule: $SUBMODULE"
|
|
git -C "$SUBMODULE" stash
|
|
UPDATE=$(git config submodule."$SUBMODULE".update)
|
|
if [ -z "$UPDATE" ]; then
|
|
git -C "$SUBMODULE" pull origin "$GIT_BRANCH"
|
|
fi;
|
|
done
|
|
}
|
|
|
|
function git-submodule-checkout() {
|
|
echo "Checkout submodule commits."
|
|
SUBMODULES=$(git-submodule-ls)
|
|
for SUBMODULE in $SUBMODULES; do
|
|
SHALLOW=$(git config --file .gitmodules --get-regexp submodule."$SUBMODULE".shallow | awk '{ print $2 }')
|
|
COMMIT_HASH=$(git ls-tree HEAD "$SUBMODULE" | awk '{print $3}')
|
|
if [ "$SHALLOW" = "true" ]; then
|
|
echo "Update git submodule: $SUBMODULE (shallow)"
|
|
git -C "$SUBMODULE" stash
|
|
git -C "$SUBMODULE" fetch origin "$COMMIT_HASH"
|
|
git -C "$SUBMODULE" checkout "$COMMIT_HASH"
|
|
else
|
|
echo "Update git submodule: $SUBMODULE"
|
|
git -C "$SUBMODULE" stash
|
|
git -C "$SUBMODULE" checkout "$COMMIT_HASH"
|
|
fi
|
|
done
|
|
}
|
|
|
|
function git-submodule-switch() {
|
|
if [ -n "$1" ]; then
|
|
GIT_BRANCH="$1"
|
|
fi
|
|
|
|
echo "Switch branch on git submodules."
|
|
SUBMODULES=$(git-submodule-ls)
|
|
for SUBMODULE in $SUBMODULES; do
|
|
echo "Switch git submodule branch to $GIT_BRANCH: $SUBMODULE"
|
|
git -C "$SUBMODULE" stash
|
|
git -C "$SUBMODULE" switch "$GIT_BRANCH"
|
|
done
|
|
}
|
|
|
|
function git-submodule-sync() {
|
|
echo "Switch and pull submodules."
|
|
git-submodule-switch
|
|
git-submodule-pull
|
|
}
|
|
|
|
function git-feature-branch(){
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
MODULE_NAME=$(basename "$1")
|
|
MODULE_PATH=$(dirname "$1")
|
|
|
|
echo "Create feature branch for $MODULE_NAME in $MODULE_PATH ..."
|
|
cd ./"$MODULE_PATH" || exit
|
|
pwd
|
|
git switch -c "feature-$MODULE_NAME"
|
|
}
|
|
|
|
function git-mig-branch(){
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
MODULE_NAME=$(basename "$1")
|
|
MODULE_PATH=$(dirname "$1")
|
|
|
|
echo "Create mig branch for $MODULE_NAME in $MODULE_PATH ..."
|
|
cd ./"$MODULE_PATH" || exit
|
|
pwd
|
|
git switch -c "$GIT_BRANCH-mig-$MODULE_NAME"
|
|
}
|
|
|
|
function checkout-config-files() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
echo "Checkout config files $1 branch."
|
|
git checkout "$1" .git-checkout-files .git-reset-files
|
|
|
|
echo "Remove reset files."
|
|
git rm -r $(tr '\n' ' ' < ./.git-reset-files) >/dev/null 2>&1
|
|
|
|
echo "Sync checkout files from $1 branch."
|
|
git checkout "$1" $(tr '\n' ' ' < ./.git-checkout-files)
|
|
}
|
|
|
|
function checkout() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
GIT_BRANCH="$1"
|
|
|
|
echo "Switch current branch to $GIT_BRANCH."
|
|
git switch "$GIT_BRANCH"
|
|
git pull
|
|
|
|
git-submodule-init
|
|
|
|
git-submodule-switch
|
|
}
|
|
|
|
# Revision Commands
|
|
|
|
function list-revision() {
|
|
ls scripts/odoo_revision_* | sed 's/scripts\/odoo_revision_//g'
|
|
}
|
|
|
|
function show-revision() {
|
|
if [ -n "$1" ]; then
|
|
ODOO_REVISION="$1"
|
|
fi
|
|
ODOO_VERSION=$(echo "$ODOO_REVISION" | cut -d'.' -f1-2)
|
|
|
|
echo "Load refs for revision: $ODOO_REVISION"
|
|
source "scripts/odoo_revision_$ODOO_REVISION"
|
|
|
|
echo "Odoo Ref: $ODOO_REF"
|
|
echo "Odoo Enterprise Ref: $ODOO_ENTERPRISE_REF"
|
|
echo "Odoo Themes Ref: $ODOO_THEME_REF"
|
|
echo "Odoo Image Ref: $ODOO_IMAGE_REF"
|
|
}
|
|
|
|
function checkout-revision() {
|
|
if [ -n "$1" ]; then
|
|
ODOO_REVISION="$1"
|
|
fi
|
|
ODOO_VERSION=$(echo "$ODOO_REVISION" | cut -d'.' -f1-2)
|
|
|
|
echo "Update revision var in .env file."
|
|
if grep -q "ODOO_REVISION" .env; then
|
|
sed -i -e "s/^ODOO_REVISION=.*/ODOO_REVISION=${ODOO_REVISION}/" .env
|
|
else
|
|
echo "ODOO_REVISION=${ODOO_REVISION}" >> .env
|
|
fi
|
|
|
|
echo "Load refs for revision: $ODOO_REVISION"
|
|
export $(cat "scripts/odoo_revision_$ODOO_REVISION" | sed 's/#.*//g' | xargs)
|
|
|
|
echo "Checkout and tag git repos ..."
|
|
git -C odoo checkout $ODOO_REF
|
|
git -C odoo tag -a $ODOO_REVISION -m "$ODOO_REVISION"
|
|
git -C enterprise checkout $ODOO_ENTERPRISE_REF
|
|
git -C enterprise tag -a $ODOO_REVISION -m "$ODOO_REVISION"
|
|
git -C themes checkout $ODOO_THEME_REF
|
|
git -C themes tag -a $ODOO_REVISION -m "$ODOO_REVISION"
|
|
|
|
|
|
if $ODOO_REVISION_CONTAINER_PULL; then
|
|
|
|
echo "Pull container image ..."
|
|
$CONTAINER_ENGINE pull "$ODOO_IMAGE_REF"
|
|
IMAGE_ID=$($CONTAINER_ENGINE image inspect "$ODOO_IMAGE_REF" --format "{{ .ID }}")
|
|
|
|
echo "Tag container image with odoo:$ODOO_REVISION"
|
|
$CONTAINER_ENGINE tag "$IMAGE_ID" odoo:$ODOO_REVISION
|
|
fi
|
|
}
|
|
|
|
function create-revision() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit; fi
|
|
|
|
REVISION="$1" # 16.0.20241029
|
|
ODOO_VERSION=$(echo "$REVISION" | cut -d'.' -f1-2)
|
|
ODOO_DATE=$(echo "$REVISION" | cut -d'.' -f3-)
|
|
BEFORE_DATE=$(date -d "$ODOO_DATE -1 day" +"%Y-%m-%d")
|
|
|
|
# Pull container image with revision
|
|
IMAGE=odoo:"$ODOO_VERSION-$ODOO_DATE"
|
|
$CONTAINER_ENGINE pull "$IMAGE"
|
|
CONTAINER_REF=$($CONTAINER_ENGINE inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
|
|
|
|
# Get git commit by date
|
|
cd odoo
|
|
REF=$(git rev-list -n 1 --before="$BEFORE_DATE" origin/$ODOO_VERSION)
|
|
git checkout "$REF"
|
|
cd ..
|
|
cd enterprise
|
|
ENTERPRISE_REF=$(git rev-list -n 1 --before="$BEFORE_DATE" origin/$ODOO_VERSION)
|
|
git checkout "$ENTERPRISE_REF"
|
|
cd ..
|
|
cd themes
|
|
THEME_REF=$(git rev-list -n 1 --before="$BEFORE_DATE" origin/$ODOO_VERSION)
|
|
git checkout "$THEME_REF"
|
|
cd ..
|
|
|
|
echo "Create revision: $REVISION"
|
|
export REVISION REF ENTERPRISE_REF THEME_REF CONTAINER_REF
|
|
envsubst '$REVISION $REF $ENTERPRISE_REF $THEME_REF $CONTAINER_REF' < templates/odoo_revision > scripts/odoo_revision_"$REVISION"
|
|
chmod +x scripts/odoo_revision_"$REVISION"
|
|
|
|
echo "Checkout revision: $REVISION"
|
|
checkout-revision "$REVISION"
|
|
}
|
|
|
|
# RPC Commands
|
|
|
|
function test-xmlrpc() {
|
|
if test -z "$1"; then echo "\$1 is empty."; exit 1; fi
|
|
|
|
activate-venv
|
|
load-env "$1"
|
|
|
|
echo "Connect to database and count res.partner records: $(scripts/odooctl --model "res.partner" --method "search_count" --domain '[]')"
|
|
}
|
|
|
|
# Pass Commands
|
|
|
|
function pass-store-dotenv() {
|
|
if [ -f .env ]; then
|
|
echo "Store .env file in pass: $PASS_ENTRY"
|
|
cat .env | pass insert -m -f "$PASS_ENTRY"
|
|
else
|
|
echo "No .env file found."
|
|
fi
|
|
}
|
|
|
|
function pass-restore-dotenv() {
|
|
if pass find "$PASS_ENTRY" >/dev/null; then
|
|
echo "Restore .env file from pass: $PASS_ENTRY"
|
|
pass show "$PASS_ENTRY" > .env
|
|
else
|
|
echo "Pass entry not found."
|
|
fi
|
|
}
|
|
|
|
# LLM Commands
|
|
|
|
function llm-update() {
|
|
if test -z "$1"; then
|
|
echo "\$1 is empty.";
|
|
exit 1;
|
|
fi
|
|
|
|
# Get list of files
|
|
FILES=$(find "$1" -type f \( -name "*.py" -o -name "*.xml" \))
|
|
|
|
echo -e "Loaded these files into prompt:\n\n$FILES\n"
|
|
|
|
# Get task description
|
|
read -p "Enter the task description: " TASK_DESCRIPTION
|
|
|
|
# Prepare the files content for prompt
|
|
FILE_CONTENTS=""
|
|
for file in $FILES; do
|
|
FILE_CONTENTS+="<<< $file >>>
|
|
$(cat "$file")
|
|
|
|
"
|
|
done
|
|
|
|
# Define the prompt
|
|
PROMPT="EOF
|
|
Look at the code files below and do the following:
|
|
|
|
$TASK_DESCRIPTION
|
|
|
|
Output your response in the format of a git patch file. The patch should include only the changes to the files, and it should be applicable with 'git apply'. Do not include any explanations or extra information outside of the patch format.
|
|
|
|
Here are the files:
|
|
|
|
$FILE_CONTENTS
|
|
EOF"
|
|
|
|
# Run the llm command with the prompt
|
|
echo -e "\nWait for the response of the $LLM_MODEL llm."
|
|
RESULT=$(llm -m "$LLM_MODEL" "$PROMPT")
|
|
|
|
# Check if the result is empty
|
|
if test -z "$RESULT"; then
|
|
echo "No response from the model. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
# Save the patch to a file
|
|
PATCH_FILE="tmp/llm_changes.patch"
|
|
echo "$RESULT" > "$PATCH_FILE"
|
|
echo -e "Saved patch to $PATCH_FILE.\n"
|
|
|
|
# Preview patch file and ask to apply
|
|
git apply --check "$PATCH_FILE"
|
|
less "$PATCH_FILE"
|
|
read -p "Do you want to apply this patch? (y/n): " CONFIRM
|
|
if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then
|
|
git apply "$PATCH_FILE"
|
|
echo "Applied patch file."
|
|
fi
|
|
}
|
|
|
|
if declare -f "$1" > /dev/null; then
|
|
"$1" "${@:2}"
|
|
else
|
|
case "$1" in
|
|
help)
|
|
help task
|
|
exit 1
|
|
;;
|
|
node-install)
|
|
npm install
|
|
;;
|
|
node-dev)
|
|
npm run dev
|
|
;;
|
|
node-build)
|
|
npm run build
|
|
;;
|
|
node-serve-build)
|
|
cd .vuepress/dist
|
|
npx serve
|
|
;;
|
|
source)
|
|
activate-venv
|
|
;;
|
|
*)
|
|
echo "Unknown command: $1"
|
|
help task
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|