From de9779cfc28c5b073a5720e78568b4c223283b1c Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Mon, 5 May 2025 04:43:13 -0400 Subject: [PATCH] [IMP] refactoring .venv.erplibre - erplibre separate venv erplibre and odoo - rename python-version to python-odoo-version - add conf/python-erplibre-version - rename .venv to .venv.erplibre - move .venv/repo to .venv.erplibre/bin/repo - install pyenv into .venv.erplibre - install poetry into .venv.odooVERSION - first installation show odoo version to install - can install erplibre without odoo - update README.md information about installation with TODO - change image from github to locally - remove link creation .venv - update version: remove code to force create symbolic link .venv - use dynamic merge manifest, will be able to merge different odoo version - can add dev tools - default manifest is empty to remove conflict --- .gitignore | 5 + CHANGELOG.md | 3 + Makefile | 22 +-- README.md | 76 ++++---- TODO.md | 2 +- conf/git_manifest.csv | 2 + conf/git_manifest_odoo.csv | 5 + conf/make.code_generator.Makefile | 30 ++-- conf/make.documentation.Makefile | 10 +- conf/make.image_db.Makefile | 12 +- conf/make.installation.Makefile | 52 +++++- conf/make.test.Makefile | 42 ++--- conf/module_list_image_db_odoo.json | 97 +++++++++++ conf/pycharm_exclude_folder.txt | 1 + conf/python-erplibre-venv | 1 + conf/python-erplibre-version | 1 + conf/supported_version_erplibre.json | 38 +++- doc/DEVELOPMENT.md | 14 +- doc/GIT_REPO.md | 34 ++-- doc/MIGRATION.md | 2 +- doc/RELEASE.md | 8 +- doc/image/odoo_application_list.png | Bin 0 -> 113645 bytes doc/image/odoo_first_installation.png | Bin 0 -> 32314 bytes docker/Dockerfile.prod.pkg | 18 +- docker/entrypoint.sh | 14 +- env_var.sh | 7 +- install.sh | 3 + odoo_bin.sh | 3 +- run.sh | 1 + script/database/image_db.py | 2 +- .../database/restore_mariadb_sql_example_1.sh | 2 +- script/docker/docker_build.sh | 2 +- script/docker/docker_repo_show_status.sh | 4 +- script/generate_config.sh | 21 +-- script/git/git_merge_repo_manifest.py | 155 +++++++++++++---- script/git/git_tool.py | 68 ++++++-- script/git/repo_diff_last_version.sh | 2 +- script/git/repo_diff_stat_last_version.sh | 2 +- script/ide/pycharm_configuration.py | 2 +- script/install/install_daemon.sh | 5 +- script/install/install_erplibre.sh | 5 + script/install/install_git_repo.sh | 14 ++ script/install/install_locally.sh | 136 +++++---------- script/install/install_locally_dev.sh | 2 +- script/install/install_venv.sh | 68 ++++++++ script/maintenance/autopep8.sh | 2 +- script/maintenance/black.sh | 2 +- script/maintenance/format_python.sh | 4 +- script/manifest/update_manifest_dev.sh | 4 +- script/manifest/update_manifest_local_dev.sh | 7 +- ...pdate_manifest_local_dev_code_generator.sh | 4 +- script/manifest/update_manifest_local_prod.sh | 4 +- script/manifest/update_manifest_prod.sh | 4 +- script/poetry/poetry_add_build_dependency.sh | 2 +- script/selenium/install.md | 2 +- script/statistic/code_count.sh | 2 +- script/test/run_parallel_test.py | 2 +- script/todo/todo.json | 2 +- script/version/change_python_version.sh | 2 +- script/version/update_env_version.py | 164 ++++++++---------- 60 files changed, 771 insertions(+), 429 deletions(-) create mode 100644 conf/git_manifest.csv create mode 100644 conf/git_manifest_odoo.csv create mode 100644 conf/python-erplibre-venv create mode 100644 conf/python-erplibre-version create mode 100644 doc/image/odoo_application_list.png create mode 100644 doc/image/odoo_first_installation.png create mode 100755 install.sh create mode 100755 script/install/install_erplibre.sh create mode 100755 script/install/install_git_repo.sh create mode 100755 script/install/install_venv.sh diff --git a/.gitignore b/.gitignore index 2bf95fd..2116d5e 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,8 @@ doc/itpp* doc/odoo* script/OCA* odoo +odoo*/OCA_OpenUpgrade +odoo*/odoo_documentation-user image_db get-poetry.py artifacts @@ -39,7 +41,10 @@ pyproject.toml .odoo-version .poetry-version .python-version +.python-odoo-version requirements.txt requirement/ignore_requirements.txt screenshots screencasts +script/todo/todo_override.json +.erplibre.error.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d417d8..9589de6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Added - Script for hardening the installation +- Support Odoo versions 12.0 to 18.0 +- Separate ERPLibre python installation from Odoo python with .venv.erplibre and .venv.odoo18 +- Implement auto-installation with TODO.py ## [1.6.0] - 2025-04-25 diff --git a/Makefile b/Makefile index 38e7856..63e5824 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ SHELL := /bin/bash -LOG_FILE := ./.venv/make_test.log +LOG_FILE := ./.venv.$(cat ".erplibre-version" | xargs)/make_test.log ############# # General # ############# @@ -123,7 +123,7 @@ open_terminal: ############## .PHONY: open_selenium open_selenium: - ./.venv/bin/python ./script/selenium/web_login.py + ./.venv.erplibre/bin/python ./script/selenium/web_login.py ############ # format # @@ -134,42 +134,42 @@ format: .PHONY: format_code_generator format_code_generator: - .venv/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator/ ./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator/ ./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator/ .PHONY: format_erplibre_addons format_erplibre_addons: - .venv/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_addons/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_addons/ ./script/maintenance/black.sh ./addons/ERPLibre_erplibre_addons/ ./script/maintenance/prettier_xml.sh ./addons/ERPLibre_erplibre_addons/ - .venv/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_theme_addons/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_theme_addons/ ./script/maintenance/black.sh ./addons/ERPLibre_erplibre_theme_addons/ #./script/maintenance/prettier_xml.sh ./addons/ERPLibre_erplibre_theme_addons/ .PHONY: format_supported_addons format_supported_addons: - .venv/bin/isort --profile black -l 79 ./addons/MathBenTech_erplibre-family-management/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/MathBenTech_erplibre-family-management/ ./script/maintenance/black.sh ./addons/MathBenTech_erplibre-family-management/ #./script/maintenance/prettier_xml.sh ./addons/MathBenTech_erplibre-family-management/ - .venv/bin/isort --profile black -l 79 ./addons/MathBenTech_odoo-business-spending-management-quebec-canada/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/MathBenTech_odoo-business-spending-management-quebec-canada/ ./script/maintenance/black.sh ./addons/MathBenTech_odoo-business-spending-management-quebec-canada/ #./script/maintenance/prettier_xml.sh ./addons/MathBenTech_erplibre-family-management/ .PHONY: format_code_generator_template format_code_generator_template: - .venv/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator-template/ + .venv.erplibre/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator-template/ ./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator-template/ #./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator-template/ .PHONY: format_script format_script: - #.venv/bin/isort --profile black -l 79 ./script/ --gitignore + #.venv.erplibre/bin/isort --profile black -l 79 ./script/ --gitignore ./script/maintenance/black.sh ./script/ .PHONY: format_script_isort_only format_script_isort_only: - .venv/bin/isort --profile black -l 79 ./script/ --gitignore + .venv.erplibre/bin/isort --profile black -l 79 ./script/ --gitignore ######### # log # @@ -210,7 +210,7 @@ repo_configure_group_code_generator: # Show git status for all repo .PHONY: repo_show_status repo_show_status: - ./.venv/repo forall -pc "git status -s" + .venv.erplibre/bin/repo forall -pc "git status -s" # Show divergence between actual repository and production manifest .PHONY: repo_diff_manifest_production diff --git a/README.md b/README.md index 20797c7..ae913bc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # ERPLibre ERPLibre is a CRM/ERP platform including automated installation, maintenance, and development of open source modules of -the Odoo community version. It is a "soft-fork" of the Odoo Community Edition (OCE), meaning it aims at contributing back -upstream. +the Odoo community version. It is a "soft-fork" of the Odoo Community Edition (OCE), meaning it aims at contributing +back upstream. It is based on a set of production-ready modules, supported by the Odoo Community Association (OCA) and an ecosystem of specialized companies. This solution ensures digital sovereignty in a local environment while integrating pre-trained Generative Transformers (GPT), bringing an additional dimension to data management and automation. @@ -11,32 +11,57 @@ Follow us on Mastodon : https://fosstodon.org/@erplibre # Installation -Select a guide to install your environment. - -## Easy install on Ubuntu or Debian using Docker +## Easy installation on Ubuntu or Debian using Docker This has been tested in Debian 12 and Ubuntu 24.04 LTS. -**Note** : This is meant for a test environment, on a local network or similar environment not directly exposed to the Internet. +**Note** : This is meant for a test environment, on a local network or similar environment not directly exposed to the +Internet. 1. Make sure Docker and nginx web server are installed:
-```sudo apt install docker docker-compose nginx``` + ```sudo apt install docker docker-compose nginx``` 1. Get the latest ERPLibre Docker compose file:
-```wget https://raw.githubusercontent.com/ERPLibre/ERPLibre/v1.6.0/docker-compose.yml``` + ```wget https://raw.githubusercontent.com/ERPLibre/ERPLibre/v1.6.0/docker-compose.yml``` 1. Install and run ERPLibre with Docker running as a daemon (web server):
-```sudo docker-compose up -d``` + ```sudo docker-compose up -d``` 1. Open the final installation step at this web page :
-```http://[server IP]:8069```
-![Capture du 2024-11-05 08-34-45](https://github.com/user-attachments/assets/7c6295b6-cc95-462d-822c-3ff72b772155) -1. Finish the installation by providing a database name, email and password. then click on **Create Database**. Depending on your system resources **this may take more than 2 minutes without feedback !** Check your browser loading indicator. + ```http://[server IP]:8069```
+ ![odoo_first_installation.png](doc/image/odoo_first_installation.png) +1. Finish the installation by providing a database name, email and password. then click on **Create Database**. + Depending on your system resources **this may take more than 2 minutes without feedback !** Check your browser + loading indicator. 1. Next, the web page will reload itself, and you should see the Applications list in ERPLibre:
-![2024-11-05_09-54](https://github.com/user-attachments/assets/1742c4a9-da96-466b-9c17-35eb5ca786ff) -You can now personalize your ERPLibre installation. + ![odoo_application_list.png](doc/image/odoo_application_list.png) + + You can now personalize your ERPLibre installation. For more information, read [Docker guide](./docker/README.md). ## Install from source code +### Automated installation + +For Debian/Ubuntu + +```bash +sudo apt install make python +``` + +Clone the project: + +```bash +git clone https://github.com/ERPLibre/ERPLibre.git +cd ERPLibre +``` + +Follow the instruction on the following script, it will try to detect your environment. + +```bash +./script/todo/todo.py +``` + +### Manually + Into Ubuntu, minimal dependency: ```bash @@ -81,6 +106,9 @@ Ready to execute: make run ``` +### For Windows + +For Windows, read [WINDOWS_INSTALLATION.md](doc/WINDOWS_INSTALLATION.md) ## Discover guide @@ -94,26 +122,6 @@ make run [Guide to run ERPLibre in development environment](./doc/DEVELOPMENT.md). -### Pycharm - -First open - -```bash -make pycharm_open -``` - -Close it, and configure - -```bash -make pycharm_configure -``` - -Open it - -```bash -make pycharm_open -``` - # Execution [Guide to run ERPLibre with different case](./doc/RUN.md). diff --git a/TODO.md b/TODO.md index 85364d6..4866dce 100644 --- a/TODO.md +++ b/TODO.md @@ -6,7 +6,7 @@ devops_erplibre need sshpass ## Simplify push tag For RELEASE.md, replace next value by a script to select all remote by manifest file. Actually, need to push manually all different remote. -> ./.venv/repo forall -pc "git push ERPLibre --tags" +> .venv.erplibre/bin/repo forall -pc "git push ERPLibre --tags" ## Funding - Add funding for MathBenTech and TechnoLibre diff --git a/conf/git_manifest.csv b/conf/git_manifest.csv new file mode 100644 index 0000000..e70dab6 --- /dev/null +++ b/conf/git_manifest.csv @@ -0,0 +1,2 @@ +"filepath" +manifest/git_manifest_erplibre.xml diff --git a/conf/git_manifest_odoo.csv b/conf/git_manifest_odoo.csv new file mode 100644 index 0000000..09a81f1 --- /dev/null +++ b/conf/git_manifest_odoo.csv @@ -0,0 +1,5 @@ +"filepath" +manifest/git_manifest_erplibre.xml +manifest/git_manifest_erplibre_extra.xml +manifest/git_manifest_erplibre_odoo.xml +manifest/git_manifest_erplibre_odoo_dev.xml diff --git a/conf/make.code_generator.Makefile b/conf/make.code_generator.Makefile index e42d59f..37b8462 100644 --- a/conf/make.code_generator.Makefile +++ b/conf/make.code_generator.Makefile @@ -288,39 +288,39 @@ test_code_generator_demo_mariadb_sql_example_1: .PHONY: test_addons_code_generator test_addons_code_generator: - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./odoo_bin.sh db --drop --database test_addons_code_generator # TODO missing test in code_generator ./test.sh --dev cg -d test_addons_code_generator --db-filter test_addons_code_generator -i code_generator - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" # run: make open_test_coverage .PHONY: test_addons_code_generator_code_generator test_addons_code_generator_code_generator: # TODO this test only generation, not test - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./script/database/db_restore.py --database test_addons_code_generator_code_generator ./test.sh --dev cg -d test_addons_code_generator_code_generator --db-filter test_addons_code_generator_code_generator -i code_generator_code_generator - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" # run: make open_test_coverage .PHONY: test_addons_code_generator_template_code_generator test_addons_code_generator_template_code_generator: # TODO this test only generation, not test - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./script/database/db_restore.py --database test_addons_code_generator_template_code_generator ./test.sh --dev cg -d test_addons_code_generator_template_code_generator --db-filter test_addons_code_generator_template_code_generator -i code_generator ./test.sh --dev cg -d test_addons_code_generator_template_code_generator --db-filter test_addons_code_generator_template_code_generator -i code_generator_template_code_generator - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" # run: make open_test_coverage # generate config repo code_generator diff --git a/conf/make.documentation.Makefile b/conf/make.documentation.Makefile index f58cf68..ab2569f 100644 --- a/conf/make.documentation.Makefile +++ b/conf/make.documentation.Makefile @@ -31,7 +31,7 @@ open_doc_all: # documentation dev .PHONY: doc_dev doc_dev: - source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-development/docs html || exit 1 + source ./.venv.erplibre/bin/activate && make -C doc/itpp-labs_odoo-development/docs html || exit 1 .PHONY: open_doc_dev open_doc_dev: @@ -44,7 +44,7 @@ doc_clean_dev: # documentation migration .PHONY: doc_migration doc_migration: - source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-port-docs/docs html || exit 1 + source ./.venv.erplibre/bin/activate && make -C doc/itpp-labs_odoo-port-docs/docs html || exit 1 .PHONY: open_doc_migration open_doc_migration: @@ -57,7 +57,7 @@ doc_clean_migration: # documentation test .PHONY: doc_test doc_test: - source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-test-docs/doc-src html || exit 1 + source ./.venv.erplibre/bin/activate && make -C doc/itpp-labs_odoo-test-docs/doc-src html || exit 1 .PHONY: open_doc_test open_doc_test: @@ -71,7 +71,7 @@ doc_clean_test: .PHONY: doc_user doc_user: ln -sf ../../odoo/odoo ./doc/odoo_documentation-user/odoo - source ./.venv/bin/activate && make -C doc/odoo_documentation-user html || exit 1 + source ./.venv.erplibre/bin/activate && make -C doc/odoo_documentation-user html || exit 1 .PHONY: open_doc_user open_doc_user: @@ -84,4 +84,4 @@ doc_clean_user: # documentation markdown .PHONY: doc_markdown doc_markdown: - ./.venv/bin/mmg --verbose --yes ./doc/CODE_GENERATOR.base.md + ./.venv.erplibre/bin/mmg --verbose --yes ./doc/CODE_GENERATOR.base.md diff --git a/conf/make.image_db.Makefile b/conf/make.image_db.Makefile index 9922be9..8dc7b76 100644 --- a/conf/make.image_db.Makefile +++ b/conf/make.image_db.Makefile @@ -15,21 +15,21 @@ image_db_create_erplibre_code_generator: image_db_create_all_parallel: ./script/database/db_restore.py --clean_cache echo "Search in-existing module" - ./.venv/bin/python3 ./script/database/image_db.py --check_addons_exist + ./.venv.erplibre/bin/python3 ./script/database/image_db.py --check_addons_exist echo "Create Image DB" - ./.venv/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel | bash + ./.venv.erplibre/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel | bash ./script/database/db_restore.py --clean_cache #./script/make.sh image_db_create_test_website_attachments .PHONY: image_db_list_data image_db_list_data: - ./.venv/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel - #./.venv/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel --odoo_version 12.0 + ./.venv.erplibre/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel + #./.venv.erplibre/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel --odoo_version 12.0 .PHONY: image_db_list image_db_list: - ./.venv/bin/python3 ./script/database/image_db.py --show_list_only - #./.venv/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel --odoo_version 12.0 + ./.venv.erplibre/bin/python3 ./script/database/image_db.py --show_list_only + #./.venv.erplibre/bin/python3 ./script/database/image_db.py --generate_bash_cmd_parallel --odoo_version 12.0 .PHONY: image_db_create_test_website_attachments image_db_create_test_website_attachments: diff --git a/conf/make.installation.Makefile b/conf/make.installation.Makefile index ce2e6fa..2be2f45 100644 --- a/conf/make.installation.Makefile +++ b/conf/make.installation.Makefile @@ -11,13 +11,40 @@ install_dev: # ./script/install/install_locally_dev.sh ./script/version/update_env_version.py --install_dev +.PHONY: install_odoo_18 +install_odoo_18: + ./script/version/update_env_version.py --erplibre_version odoo18.0_python3.12.10 --install_dev + +.PHONY: switch_odoo_18 +switch_odoo_18: + ./script/version/update_env_version.py --erplibre_version odoo18.0_python3.12.10 --switch + ./script/make.sh config_gen_all + +.PHONY: install_odoo_17 +install_odoo_17: + ./script/version/update_env_version.py --erplibre_version odoo17.0_python3.10.18 --install_dev + +.PHONY: switch_odoo_17 +switch_odoo_17: + ./script/version/update_env_version.py --erplibre_version odoo17.0_python3.10.18 --switch + ./script/make.sh config_gen_all + .PHONY: install_odoo_16 install_odoo_16: - ./script/version/update_env_version.py --erplibre_version odoo16.0_python3.10.14 --install_dev + ./script/version/update_env_version.py --erplibre_version odoo16.0_python3.10.18 --install_dev .PHONY: switch_odoo_16 switch_odoo_16: - ./script/version/update_env_version.py --erplibre_version odoo16.0_python3.10.14 --switch + ./script/version/update_env_version.py --erplibre_version odoo16.0_python3.10.18 --switch + ./script/make.sh config_gen_all + +.PHONY: install_odoo_15 +install_odoo_15: + ./script/version/update_env_version.py --erplibre_version odoo15.0_python3.8.20 --install_dev + +.PHONY: switch_odoo_15 +switch_odoo_15: + ./script/version/update_env_version.py --erplibre_version odoo15.0_python3.8.20 --switch ./script/make.sh config_gen_all .PHONY: install_odoo_14 @@ -29,6 +56,15 @@ switch_odoo_14: ./script/version/update_env_version.py --erplibre_version odoo14.0_python3.8.20 --switch ./script/make.sh config_gen_all +.PHONY: install_odoo_13 +install_odoo_13: + ./script/version/update_env_version.py --erplibre_version odoo13.0_python3.7.17 --install_dev + +.PHONY: switch_odoo_13 +switch_odoo_13: + ./script/version/update_env_version.py --erplibre_version odoo13.0_python3.7.17 --switch + ./script/make.sh config_gen_all + .PHONY: install_odoo_12 install_odoo_12: ./script/version/update_env_version.py --erplibre_version odoo12.0_python3.7.17 --install_dev @@ -40,17 +76,19 @@ switch_odoo_12: .PHONY: install_odoo_all_version install_odoo_all_version: - ./script/make.sh install_odoo_12 - ./script/make.sh install_odoo_14 + ./script/make.sh install_odoo_18 + ./script/make.sh install_odoo_17 ./script/make.sh install_odoo_16 + ./script/make.sh install_odoo_15 + ./script/make.sh install_odoo_14 + ./script/make.sh install_odoo_13 + ./script/make.sh install_odoo_12 .PHONY: install_odoo_all_version_dev install_odoo_all_version_dev: echo "Open Pycharm, close it before install Odoo and reopen at the end" pycharm . - ./script/make.sh install_odoo_12 - ./script/make.sh install_odoo_14 - ./script/make.sh install_odoo_16 + ./script/make.sh install_odoo_all_version #.PHONY: install_update_odoo #install_update_odoo: diff --git a/conf/make.test.Makefile b/conf/make.test.Makefile index 8d996a6..2e86f25 100644 --- a/conf/make.test.Makefile +++ b/conf/make.test.Makefile @@ -2,7 +2,7 @@ # TEST # ######## -# TODO load specific test file : ./run.sh -d test_file --log-level=test --test-enable --stop-after-init --test-file ./.venv/test.py +# TODO load specific test file : ./run.sh -d test_file --log-level=test --test-enable --stop-after-init --test-file ./.venv.erplibre/test.py .PHONY: open_test_coverage open_test_coverage: @@ -48,14 +48,14 @@ test_full_fast_coverage: ./script/make.sh clean # Need to create a BD to create cache _cache_erplibre_base ./script/database/db_restore.py --database test - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./script/test/run_parallel_test.py --coverage # TODO This test is broken in parallel #./script/make.sh test_coverage_code_generator_hello_world - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" # run: make open_test_coverage @@ -64,12 +64,12 @@ test_cg_demo: ./script/make.sh clean # Need to create a BD to create cache _cache_erplibre_base ./script/database/db_restore.py --database test - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./script/addons/coverage_install_addons_dev.sh test code_generator_demo - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" - ./.venv/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage html --include="addons/TechnoLibre_odoo-code-generator/*" + ./.venv.erplibre/bin/coverage json --include="addons/TechnoLibre_odoo-code-generator/*" .PHONY: test_base test_base: @@ -102,20 +102,20 @@ test_installation_demo: ############### .PHONY: test_addons_sale test_addons_sale: - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./odoo_bin.sh db --drop --database test_addons_sale ./test.sh -d test_addons_sale --db-filter test_addons_sale -i sale - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m - ./.venv/bin/coverage html - ./.venv/bin/coverage json + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m + ./.venv.erplibre/bin/coverage html + ./.venv.erplibre/bin/coverage json .PHONY: test_addons_helpdesk test_addons_helpdesk: - ./.venv/bin/coverage erase + ./.venv.erplibre/bin/coverage erase ./odoo_bin.sh db --drop --database test_addons_helpdesk ./test.sh -d test_addons_helpdesk --db-filter test_addons_helpdesk -i helpdesk_mgmt - ./.venv/bin/coverage combine -a - ./.venv/bin/coverage report -m - ./.venv/bin/coverage html - ./.venv/bin/coverage json \ No newline at end of file + ./.venv.erplibre/bin/coverage combine -a + ./.venv.erplibre/bin/coverage report -m + ./.venv.erplibre/bin/coverage html + ./.venv.erplibre/bin/coverage json \ No newline at end of file diff --git a/conf/module_list_image_db_odoo.json b/conf/module_list_image_db_odoo.json index 801f241..a9fdbea 100644 --- a/conf/module_list_image_db_odoo.json +++ b/conf/module_list_image_db_odoo.json @@ -239,6 +239,24 @@ } ] }, + "odoo13.0_base": { + "base": "", + "disable": false, + "image_list": [ + { + "module": [ + "auth_user_case_insensitive", + "auto_backup", + "disable_odoo_online", + "fetchmail_notify_error_to_sender", + "mail_debrand", + "remove_odoo_enterprise", + "web_responsive", + "web_timeline" + ] + } + ] + }, "odoo14.0_base": { "base": "", "disable": false, @@ -427,6 +445,34 @@ } ] }, + "odoo15.0_base": { + "base": "", + "disable": false, + "image_list": [ + { + "module": [ + "auth_user_case_insensitive", + "auto_backup", + "disable_odoo_online", + "mail_debrand", + "remove_odoo_enterprise", + "web_responsive", + "web_timeline", + "partner_firstname", + "web_search_with_and", + "web_listview_range_select", + "web_dialog_size", + "password_security", + "web_refresher", + "date_range", + "partner_contact_access_link", + "auditlog", + "queue_job", + "web_advanced_search" + ] + } + ] + }, "odoo16.0_base": { "base": "", "disable": false, @@ -639,5 +685,56 @@ ] } ] + }, + "odoo17.0_base": { + "base": "", + "disable": false, + "image_list": [ + { + "module": [ + "auth_user_case_insensitive", + "auto_backup", + "disable_odoo_online", + "mail_debrand", + "remove_odoo_enterprise", + "web_responsive", + "web_timeline", + "server_action_mass_edit", + "partner_firstname", + "web_search_with_and", + "web_dialog_size", + "password_security", + "web_refresher", + "date_range", + "partner_contact_access_link", + "auditlog", + "queue_job" + ] + } + ] + }, + "odoo18.0_base": { + "base": "", + "disable": false, + "image_list": [ + { + "module": [ + "auth_user_case_insensitive", + "disable_odoo_online", + "remove_odoo_enterprise", + "web_responsive", + "web_timeline", + "server_action_mass_edit", + "partner_firstname", + "web_search_with_and", + "web_dialog_size", + "password_security", + "web_refresher", + "date_range", + "partner_contact_access_link", + "queue_job" + ] + } + ] } } diff --git a/conf/pycharm_exclude_folder.txt b/conf/pycharm_exclude_folder.txt index 14cf1b3..bfaaa99 100644 --- a/conf/pycharm_exclude_folder.txt +++ b/conf/pycharm_exclude_folder.txt @@ -11,6 +11,7 @@ cache htmlcov node_modules .venv +.venv.erplibre odoo screencasts screenshots diff --git a/conf/python-erplibre-venv b/conf/python-erplibre-venv new file mode 100644 index 0000000..48a0b46 --- /dev/null +++ b/conf/python-erplibre-venv @@ -0,0 +1 @@ +.venv.erplibre \ No newline at end of file diff --git a/conf/python-erplibre-version b/conf/python-erplibre-version new file mode 100644 index 0000000..d367df0 --- /dev/null +++ b/conf/python-erplibre-version @@ -0,0 +1 @@ +3.12.10 \ No newline at end of file diff --git a/conf/supported_version_erplibre.json b/conf/supported_version_erplibre.json index c3486bf..c3e634e 100644 --- a/conf/supported_version_erplibre.json +++ b/conf/supported_version_erplibre.json @@ -2,18 +2,48 @@ "odoo12.0_python3.7.17": { "odoo_version": "12.0", "python_version": "3.7.17", - "poetry_version": "1.5.0" + "poetry_version": "1.5.0", + "is_deprecated": true, + "note": "Deprecated" + }, + "odoo13.0_python3.7.17": { + "odoo_version": "13.0", + "python_version": "3.7.17", + "poetry_version": "1.5.0", + "is_deprecated": true, + "note": "Deprecated" }, "odoo14.0_python3.8.20": { "odoo_version": "14.0", "python_version": "3.8.20", - "poetry_version": "1.5.0" + "poetry_version": "1.5.0", + "is_deprecated": true, + "note": "Deprecated" }, - "odoo16.0_python3.10.14": { + "odoo15.0_python3.8.20": { + "odoo_version": "15.0", + "python_version": "3.8.20", + "poetry_version": "1.8.3", + "is_deprecated": true, + "note": "Deprecated" + }, + "odoo16.0_python3.10.18": { "odoo_version": "16.0", - "python_version": "3.10.14", + "python_version": "3.10.18", "poetry_version": "1.8.3", "default": true, "note": "Official support ERPLibre 1.6.0" + }, + "odoo17.0_python3.10.18": { + "odoo_version": "17.0", + "python_version": "3.10.18", + "poetry_version": "1.8.3", + "note": "New GUI" + }, + "odoo18.0_python3.12.10": { + "odoo_version": "18.0", + "python_version": "3.12.10", + "poetry_version": "2.1.3", + "note": "Last version" } } diff --git a/doc/DEVELOPMENT.md b/doc/DEVELOPMENT.md index 5d8c700..4e89348 100644 --- a/doc/DEVELOPMENT.md +++ b/doc/DEVELOPMENT.md @@ -198,7 +198,7 @@ rm -r ~/.local/share/Odoo/filestore/database_name ## Create module scaffold ```bash -source ./.venv/bin/activate +source ./.venv.erplibre/bin/activate python odoo/odoo-bin scaffold MODULE_NAME addons/REPO_NAME/ ``` @@ -212,7 +212,7 @@ Read GIT_REPO.md to understand how changer version. ## Python version -Your actual version is in file .python-version. Use script `./script/version/change_python_version.sh 3.7.16` to change +Your actual version is in file .python-odoo-version. Use script `./script/version/change_python_version.sh 3.7.16` to change to version 3.7.16 . Run the installation, `make install_dev`. @@ -228,17 +228,9 @@ When you need to change python 3.7.17 to 3.8.10, do : ```bash rm -r .venv make install_dev -./.venv/bin/poetry lock --no-update +./.venv.$(cat ".erplibre-version" | xargs)/bin/poetry lock --no-update ``` -And update file script/install/install_locally.sh - -`ln -fs ${EL_HOME_ODOO}/odoo ${EL_HOME}/.venv/lib/python3.7/site-packages/` - -to - -`ln -fs ${EL_HOME_ODOO}/odoo ${EL_HOME}/.venv/lib/python3.8/site-packages/` - # Pull request ## Show all pull requests from organization diff --git a/doc/GIT_REPO.md b/doc/GIT_REPO.md index 27a5fa7..c8c017c 100644 --- a/doc/GIT_REPO.md +++ b/doc/GIT_REPO.md @@ -8,21 +8,21 @@ licence [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.html). ## Setup repo ```bash -curl https://storage.googleapis.com/git-repo-downloads/repo > ./.venv/repo +curl https://storage.googleapis.com/git-repo-downloads/repo > .venv.erplibre/bin/repo ``` ## prod ```bash -./.venv/repo init -u https://github.com/ERPLibre/ERPLibre -b master -./.venv/repo sync +.venv.erplibre/bin/repo init -u https://github.com/ERPLibre/ERPLibre -b master +.venv.erplibre/bin/repo sync -c -j $(nproc --all) ``` ## dev ```bash -./.venv/repo init -u https://github.com/ERPLibre/ERPLibre -b 12.0_repo -m ./manifest/default.dev.xml -./.venv/repo sync +.venv.erplibre/bin/repo init -u https://github.com/ERPLibre/ERPLibre -b 12.0_repo -m ./manifest/default.dev.xml +.venv.erplibre/bin/repo sync -c -j $(nproc --all) ``` ## local dev @@ -32,8 +32,8 @@ curl https://storage.googleapis.com/git-repo-downloads/repo > ./.venv/repo ```bash git daemon --base-path=. --export-all --reuseaddr --informative-errors --verbose & -./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --abbrev-ref HEAD) -m ./manifest/default.dev.xml -./.venv/repo sync -m ./manifest/default.dev.xml +.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --abbrev-ref HEAD) -m ./manifest/default.dev.xml +.venv.erplibre/bin/repo sync -c -j $(nproc --all) -m ./manifest/default.dev.xml ``` # Create Manifest @@ -48,7 +48,7 @@ It freezes all repo, from dev to prod. This will add revision git hash in the manifest. ```bash -./.venv/repo manifest -r -o ./default.xml +.venv.erplibre/bin/repo manifest -r -o ./default.xml ``` Commit. @@ -63,21 +63,21 @@ When dev contains specific revision with default revision, you need to replace d keep specific version: ```bash -./script/git/git_merge_repo_manifest.py --input1 ./manifest/default.dev.xml --input2 ./default.xml --output ./manifest/default.staged.xml +./script/git/git_merge_repo_manifest.py --input "./manifest/default.dev.xml;./default.xml" --output ./manifest/default.staged.xml git commit -am "Updated manifest/default.staged.xml" git daemon --base-path=. --export-all --reuseaddr --informative-errors --verbose & -./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --abbrev-ref HEAD) -m ./manifest/default.staged.xml -./.venv/repo sync -m ./manifest/default.staged.xml +.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --abbrev-ref HEAD) -m ./manifest/default.staged.xml +.venv.erplibre/bin/repo sync -c -j $(nproc --all) -m ./manifest/default.staged.xml -./.venv/repo manifest -r -o ./default.xml +.venv.erplibre/bin/repo manifest -r -o ./default.xml ``` ## Create a dev version ```bash -./.venv/repo manifest -o ./manifest/default.dev.xml +.venv.erplibre/bin/repo manifest -o ./manifest/default.dev.xml ``` Commit. @@ -91,19 +91,19 @@ git commit -am "[#ticket] subject: short sentence" ### Search all repos with a specific branch name ```bash -./.venv/repo forall -pc "git branch -a|grep BRANCH" +.venv.erplibre/bin/repo forall -pc "git branch -a|grep BRANCH" ``` ### Search missing branch in all repos ```bash -./.venv/repo forall -pc 'git branch -a|(grep /BRANCH$||echo "no match")|grep "no match"' +.venv.erplibre/bin/repo forall -pc 'git branch -a|(grep /BRANCH$||echo "no match")|grep "no match"' ``` ### Search changed file in all repos ```bash -./.venv/repo forall -pc "git status -s" +.venv.erplibre/bin/repo forall -pc "git status -s" ``` ### Clean all @@ -111,7 +111,7 @@ git commit -am "[#ticket] subject: short sentence" Before cleaning, check changed file in all repos. ```bash -./.venv/repo forall -pc "git status -s" +.venv.erplibre/bin/repo forall -pc "git status -s" ``` Check the changed branch, and push changed if needed. diff --git a/doc/MIGRATION.md b/doc/MIGRATION.md index 4c74e2e..0ad0ddb 100644 --- a/doc/MIGRATION.md +++ b/doc/MIGRATION.md @@ -52,7 +52,7 @@ Execute migration with OpenUpgrade. ```bash make config_gen_migration -./.venv/bin/python ./script/OCA_OpenUpgrade/odoo-bin -c ./config.conf --no-http --update all --stop-after-init -d BD +./.venv.erplibre/bin/python ./script/OCA_OpenUpgrade/odoo-bin -c ./config.conf --no-http --update all --stop-after-init -d BD ``` ## Migration Odoo 13 to Odoo 14 diff --git a/doc/RELEASE.md b/doc/RELEASE.md index caeb74f..c433f83 100644 --- a/doc/RELEASE.md +++ b/doc/RELEASE.md @@ -7,7 +7,7 @@ A guide on how to generate a release. Before the cleaning, check if existing file isn't committed, not pushed or in stash. ```bash -./.venv/repo forall -pc "git stash list" +.venv.erplibre/bin/repo forall -pc "git stash list" ./script/git/git_show_code_diff_repo_manifest.py ``` @@ -102,7 +102,7 @@ To test it, you need to clean caches and install it: Generate production manifest and freeze all repos versions. ```bash -./.venv/repo manifest -r -o ./default.xml +.venv.erplibre/bin/repo manifest -r -o ./default.xml ``` Update ERPLIBRE_VERSION variable in [env_var.sh](../env_var.sh), [Dockerfile.prod](../docker/Dockerfile.prod.pkg) @@ -129,7 +129,7 @@ Understand differences from last release: git diff v#.#.#..HEAD # All repo -./.venv/repo forall -pc "git diff ERPLibre/v#.#.#..HEAD" +.venv.erplibre/bin/repo forall -pc "git diff ERPLibre/v#.#.#..HEAD" ``` Simplification tools: @@ -169,7 +169,7 @@ git tag v#.#.# # Push your tags git push --tags # Add tags for all repo -./.venv/repo forall -pc "git tag ERPLibre/v#.#.#" +.venv.erplibre/bin/repo forall -pc "git tag ERPLibre/v#.#.#" make tag_push_all ``` diff --git a/doc/image/odoo_application_list.png b/doc/image/odoo_application_list.png new file mode 100644 index 0000000000000000000000000000000000000000..426915b364d0cd45a1f0799adf22e1485d3799c4 GIT binary patch literal 113645 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�tR;$sZ97-$X8GK+b_HC@OOOn11QCkb%fX z*0xGvYW9eFu!JdoeBSNv@&@Z@s(%j+EiWxm=+P(ad(8BmZ&~w3D#dRy7bB+c%yXz+ z!uG4nZw%KGT(%O9GCKfyHLPU8hPjnntaZY1Dc{FXrh)AM>98mVTI2>4i)F%9lm@5x zg6PGp`_4Rjd;J?~NY!9TaZ6=BQ>M?ijqWOszTW3D%6rSmyu1vEj+(?;x*N{ ze)l$H+!=6AYP~APZ6&r_b2BE_f!{f%=9b8|)Iekf9z>O&SJxy@Q))%OpG z)St_A`J)h(+OLWr^>Jji@)k~3KNzZTT70-;tSB*ZE5UF3?yX_fb2R=Mdo2n=;xv_+ zh@sr<@_(wXt?W!uxo9Dz!|o}e_gL3qgmnI$i=)bMqQUb^g7HTZPTpftam#c`f4+NX zl-TFn8XcnX7F{?Ze|2>gPpT}j)=|n)E(X;knd05y+PkC^Z{n<@)CQ6U4aII`O9h2m z=$EnmXhnDl+!jOVA({xma0HvTeOGN&KRZ*O&?Fb58ehGA zxBq+IX6y0X!k21KrQp&X{GZC%jw+=)_ZNSczee`%x(Tcs$8lPkT=mYjn_ z+~NRt!E@wjKf1c`*?s%>%bH%s0g&A?uJJ#YIx5Hcc{s&_(6?9Ld*Gz_yL)-UQHe6I z1=o2kB8DT<)WvD4?cL`71P{}DxWQuWI?DA#2@4$vXCNNGzp*zZEg`Blmhb51`$Fyf zF>3j{rna*ReflI#9{f@o`IaU0q=qu{CeEma_4UCQ3Yp8K(S8B@Mslodx8AD*59BLv zM{0H){Z7U4igtyW#{(Tz;@u|(r_Jc z3hZbYL+rGA1?}(bj(0Qo^eMs)Lqv1JG(I`I&OXO#bVb#&lOT{ySU7>WyYv*3v>u%>m(#5 zHmMK#EKXl>Y(2)y`yeO?$?GjB0XR7gov8izkpTUc_fY4?U&8T=JV8k*2;miZOaQST zTkAdz^K&hJ6k*4Vir}PaA*PQ*)ZpE98wr-?rza!g<3Edppw)m+QgIBg<>%+a$Xi!W z4+Qg09H&szB6OB{xWG&Sj*t*B1`{2F<*PyRnrIY2Z7CrE!3I@wI~3HUmnYc$U-_{u z?q3z>P|$wGa`4^Lh4_n4C*H}V+SL5A-L4+0Kt}pL{QEa_6h469|K$sAiJ}k)KMEYN z-q*8^Gtr=eQdLz&xrE|t6To-$d-rlazJLw_WEY@ch^qRx!!mx{y!#sN4|eX4l9G&H z+e@w)vbVD8@tIpvwT<0)|4($cv;Vity*KNX)NVW2*SD`Gu|P&3oxCeh$Y&-lWAD2! zZuV27pOyoiU3a*Mv(OM9KQPz-aC@Ne1BhuX>8Yg6g!G2TmdLST5MWnekf8;&1!P@= zqobcHB9oH5kvy7K-#;lWZCv3kd+bi0BfZ_rqb4XQCM;J&5Y+Bu!=( z7O->Omu5|&;E1Z+1mX}l7=9Mrwk`MvnMi~l0tD=C4SWouSSHuh456+>t-yTBIqL!! z|Bp1eKS#La@Hx+O~~@NQw#yi5xWZ;|;P8pSbz7#aiahs0Jm~EGt`H zbCT`>Ijp6`#eSVUjFJ$4bWm8$%xnPPbWVYH-kR z;u1&e)urE(;^Ji35ccg7`dqF|)nZ$KjGu~@7F~ecpn`zZNY(hUh^C|#e>3|9zY&OB zVr?=rGDhP8&;71PSa7hqaZ+bvp~EEd8%mETkgOCHA>Zpg-;WLl${$_ceYgb}AuyeU z3*%!>v>~Lxb5vf@36|SIRF};R72Tr9Oxgm)p}AS(hn?;1*Cg7leV1FLH3{7VPiBX9 zowGW>x$k4L8g8Ge(ndDoA@d;@9MAR z<>vOEfJHnldL{f=;@{9j0D*f;CE7HeUS7+2@4(Le_1;MU)yPj4UDRqY58p&6HaZs5 z5D^hk;xrK*7pKHG)s}gH<0I6Q;i|gb?{04eeqRj?O-MkrNc8jDLU?<<>)TH&LZ4Ka z=BqYa=KClBrdv{X5N7v>!b7>H=ID_l&nI`>P*#43!g8=6CkMS=7yQ#fsrKPygD&Y7 zU#wEd;?9NQU+6X<1|lo&_{WLFd6%b9o)-TU{s4(N-#BL^@UT$UFDp0G3T4H3{pf5b zH-)_q%i3s?5XVtbaw>!%xx*!*i;(Wx&S+L(oP)G^ozkDX38RuJ9LvL;Z%Rr$kR=i- zdwb=Oi(mJP`b*29^|)<3_O1qzjg;w6pWZL_YIydQ(6OB+|89=M8#<*|NB#*KA5WKb)m|{#A1?S>4lTZifbXsAvvXDNddB z+x~}-eFo(Qq>mvQteNq4((q|w;xb!f%{}lNVe#>GVnHk}WKe3IRg#64jeb+*s$ilr z37+TOuxcolOl{G7cRN%e0?!;`)a$Em-n)`t!C4*pG~{JzZAXE#nerA-FXhi`lVtD@=EyD@HyomLhe)q2{h>aM-d4m@`@YdJ7;3zIbCC4*)jvyewNJQgbU?gix~ZGO07T38Vkn7DY`Zx`i`o6>byr`lkY(ns-HT#b}P!^EAD^ z`NUFPol@?KpE{Lbp-<9;BuSNh1-zhjG7ll9=m~zQuSfG#UR!8%;UDyH=$OU)*~(yn zD@Rd5u(NBZ(;$eXCEzt6;t$UiLG67#EJYs`MnnX~2xHj#omsKWFQ&Cav-mR0_M)^DN-i32i&5XU3738Wdyi1fx zV$COXr|*%I)lvK){T?1ZEazQ{degH-oS1(1kG}bN3#-cXdF}Gg9~=f(L#yV<5*;|j zGCmsPuq#9N&M7k zpv_G1T$Qv>cm86lwsfcFXnzCa{c>rNh`2{}aE^Z|!=J|apsad%s#}7m7JfAIRnp}g zyG6El99cbjiu6=G*PmY0LhZ3pUxa0P!V7(bm68$=wIa)es0e5+@a_|%N&PI~oh;F`#9P|Sz805<5BGYIXFe1?;|1WOZY+U3!)k&y$34)x?&TqJ3_A?tN`44K=)TjsOhOn%sDE`%ZGIo3R&j+qH!wWYd_CZ zwQ-!j*zoC-Ub*MVic*t>2wmcXs;dwfTEe<$*uS7tE=SOcO^a)P^`8fiJZXHZda=>; z@85UOGe83ts@2dCZs(Q9eL(FW;<1Ni-DjN|y}iAM9RB6$MUx_RSUUF*_v^bwO~(K0 z7@f;=VIwsRnlOu)&xwEMiKkIe;AQuJqY$AX82{FJ`Jp%Gv~kgO9+zvXf*j%0F*kS} zsU7ZqNR1zUe<2=4zgnVnP2K7I>7Ei8*E!(9ITXwA^1^^*6n#N-GxqmR_w{{6(*~`N zSvtGL$u2S!t&keR)d?ve-h(E86y5;(raK6zvXQUhMIxEUU;#&N%B+u%Vu8ULJaJ&~ z6FG6%MD4`2Pq2T8#h8Mm3D$ozMCQknQ&qU(TXY&rT`dh(Rw(4(<>rpHWg`1rgEP9? z-7{a&SENayDH+vi*wjZ6%0-W!hl>j;NBC&HlNCevg3|G2 zszuNi5qa}U7M+;Hr%&Hq?_$`q=Tfe{q%<$FX=}!pD+zfFGcu#?^*P^SG`r7h74F|u z%^3OVC7sLq9d5#P*W1HA`3H{f{@XfG_#-d1!FVsIq+x=3IqPI^m5J&5;D3yM%&#^SwCG_!^ocBuh%R^W7@oW~RJ7y>&i{m%qLqnS) zRPI%!M&=2kNsYvLU|`@r?ZLm}nK=ebA$=Xn{fhT~EUyI8vVO`HROG7`Ij0!n`UGY? znIDan$8e6LMZP4zisBK2A-)ryVf5|{1rN$>wRaK#L(sQxs$k(i^ekfEpob0Batz$UNTx5GFci^G#=1mo(!(VbN zvlu*fa-bi9d7UH^4Pqsf#nQ>7b$Vh!yTmK8!=#3-Z_gh!kEu9uONYy(MCNMk?@ix% zSZKGOjl0v8F0f|$&+vqLjg*u?r%ze~VKvJkeBEkGBj1yYeDkkLutT6@l7kgG-CNPy z-u@2SCJVW9dx=zkE=If{k%SE1rhl_gURqE^L_*m|f)KSJra|ynFM~mp7C$MH1-cN~ z2I%(@1sOZ$zrM(u3weJsljmx7=P5KG5mTnR^6Oe!{-8~fqjp7#m~JX@H)Po-wSjWc z!mLsPdF(>ugcwWOSka7cca~R}?R#YQo9AQ+UKx&3ieG+gX`Q8%uP1mI&O7K8(Yt^C zb6Y(_3sy)yTKd0VL{bM34Gn)_yYNOShYiBH5Q5iq<=(zIf9Qkc3yM`0ADpx)cUn2l z!6m`VQR%_Z~~}^04I~>8q4J z3~cIT!}U3d>5pw%ne&U^6}^?0bYAw@VxCw}+!vQ7tx3ShViu z@Za(#H&@ARwoj@1ELF7du}O)4cqXvcAGPfNNY{Jy;U4Ox<@tt} z4TWlT-6!jp@5B)$+bh-=FOY4X?26pJm$X~ujNQBWedxno@tjVGj{b{2pteEX^*Ds~ z`FYB?MQA*>VR6f|$;cbPrCgAhuKY-UC71tJXWw0MPKkh;l3)4`E6q~MW6>vfr73uQ zp$b5{bMgw~#T(3bedjpY2pWmcOuS#5q~jG0mq5$Yv9ed&uH|_R+Ksw4hw_IO^8_dQ z`YLm_%>C|heZmO9Lz2XJNE|)!q#9Rl3Tw=*)%oJYm3_w3#K)uKDduu{ldYZPjIfqg-wcQ^jc(?67dskug% zQ|dK%Eh{v!wWiLlHr#}-%%JNt>&bWbUG~>+4BJE#$UOC@)OTG!xY)7NpZ=9$Z1xd< z4ehMBeVWQmZMBTkANK%Nrl@;>hpw|SwEC7W`4dAA~_X3dwjK3j(1bk2>IppdgLoP5-ao zKPxkflUAuS&hVMsP~rDd3!g2SwaakePR+P-q4&HMUE%moJh9wk`sM52{uMu+Mn724Yb1y4EF?X0@I|U z^Eq~BO607K*pQ>y%O{siiEK^5DpaQan~6;NyAI%&s_CD7{1#oShwk2|E$`d3)_9{EdrIe^IX6u| zbsH-O4e86TBrI3uA+ayl1W)ii%}%W@D_Y8_Emb+W+jrLd+j|D>Uu#;52aZ~qp_@hj zFofiOpts%geU=bEH_hdh9j_a>nw)OE#Av3dq-@QkgQQRk%@1A`8a^F_s-3w-^Lj3(MBGyhqYo5R) zGmx|*Odh#$DskmzOv^Jz9SL6#q$f6Qs^C>JHSNbVh+oHoo`^<=@1`x%PUF`&Y=(J$ zT0dIHk~o+Diz#3Jy2_WpCC`bgW_dD|)k=&5X?GQCiIBhq2jT7uMC z5bDx788b93#B~2;$y&$r#_Oj7_Ue)~Ww0KSmYxSAt1~RTsU0tBSI~`~$_Ke(C+(@L zt>>v^v$J&SXjm;KZ|pj~B4--d?p$@q@ZWOze9bqW>kGB@;w>ij@1jnAi_g&yz=boK z)J+Z#zq4#&*;R6zm4}{+B}*5N%~j9d`K0pMPrg-4x5oMZ_T1{oH5Dr^Z4b>L?`odu zcA0PB?MvPmJiPJfbHqh;;Z?Vh<>zKMyx7tie~XRz2UP)zreDIDUMz6QW^Q@&D@z4F z_zJzrcNP}pGc2kN7e(WEc_;mS(^q7wt6tTe!C%cyC$k-O8e(^HM5eMcP={nqS0_8$ z|Ek*Nda7an&(!@F5BGjZtyIg9t`M2}7rMG*j6u=kzA4Lf-{O}0*9pA*?dzrF)l)OO zbDb46@^zknW72Q0``$zW)U7^$!VvXRl&9%Mqx{lveLz+ct?rImV}HTwPD8fb4qImN zp>yIS!E>yMzd7_t9@866aj$M0ERHCxTLN`8J39Hy?)ZP^jMHZ`EGd!Juw z`Wk0d+a+g$)TvV|K=&{Ny--6-n6&vWJ13_f+x6Nz%pCKrZ!BwRhF>t_yF7LvUah5H zT$6}Uk3XrrGo?)(pi3&*_S6&;8s8tf6O>yv?5;SO*w~rD%Louew{!OqG)6 z8zpWj!qXHc^l_z4_as1iE zm_LKH^+OK0R~{Z7x1PuK*D#2oUH#4WKdWYii=~E1JjclGK7Fj{NAnFiy3MDvIh#yP z4;?cu&C!f9DB+}%Ob^;?Z1nGsBCXHQsARz#UC%A5*$OX-<`AE^SeMGk?g$Jx6dY!$ zAI)ZSlRNbTlgA~pe{NwrO9PX5czA30XK~-^&U}&oVgdGUW>%GnAHCoxS+HPdYR>8Y zL1F8?+65Q+^p?3lf8P~E#rjCbspw3G6wFqG1b*KXmXzUzi;jLf$f;kPPV@h?Cffu5 zDET6d{qOPj8-=>O&Frd0GUio}QmQxq@?I(K7{0%}TtM*sJJn-ZDt2}KRC736@8u(V zWXT~u!Hi*hjmL*Zt$(EWtt8mXuB`8<9w}vPe;#07)9z2S{P>{K<-l$)^Iv@^Avd4N z)Oom5cw1mNt-JSynER(s_>UV9i31Jat;%J*hQ(9-Op;EE3(1yEX14ICl}WfMU+8qS zFUx=PLVg>e?zuXRx3_Ea={3cG@Qcdt9T&P6MgryD2YL^U7mVBwBlvda-#(`hGX34B z59t+L?@}5Qt2U)HufKI#!3!NeH@QC4;bvbZzO>w5wYI%6?o>{CQRnKnt|CXrk+P?(S}TZy(>9e+LLT)nRB)GVfMnrh?T(poR#qrx{WmomJZJ(%Vz;%X!iuHI z??tiSWj(ff6)g?s(K0gb@9KQuGV{~edGOC(o)d~*dtHX#8XenM4Hg!f->C9yW%KUN z^BDQNWyM=brSx%JoVKp+%POsSi7kX5^AVPmC$-JoK3lRjgt<{koX;?+fBHO0^_Wfh z9lmV@&C9#wk8C3RRC1TPqjzTJS2>5vK|}*-?cYj){R}sQPTrDE!tvKa zhM$k5%_m4@6qY5b+SywXJ~au|e>wKLNSqk@^W#oo<4`&K^_+lA0m9O90WHlak!q}4 zQX}nqRFB-XO7Y~Z)$0>~Hxi_e4s=zS5@vg97skfo5`32ae5}9xPg9lv)(A?2rIWzt50y*V>8C7yC}xB1}eo!r8yxO)5d=<==uC3nVuPi6_O&>yT8nVmU0ie9$-5k8lFA7rS5 zjy(SQQD@!f^}qnb`c%cC&QqqVyB25CXbv(bMczq^9=U!)-Og=0g54`Rb9*O=Um?tg zk2Y-xG}9B9Re#2txoubHVkli)7l{Z84J~tAGl&l_6t74$eUO>SNt$o1PteytUta#& zKjXK4+$opCe`jWd_lap{EVXr|goO=lRB_C|1?rP_`ox(dxpAU5#z!AlH=7i>j!etm zH~r;lezR`(p@D%f`K-GL-rhG(hP~bx{(*qJ`OKM^WA#9{l{y_HIL~x_&sThOMx&m} zO#k-Cm$a9pOUi{aon1NhY-Hzy2mhd`4^=R~dGptd59`q4(|sokF4u+GH+l3l=S(eB z>>dBJI-##U#H=c7a~#=+#uU&bnR}X!>1HTi{<7z4Woc1R-QAZbhn}{4N|JW6>z=ow zx?5_r@XITP(C6(i{rkabx%FGz%f{0O$w`tdT}w+VTXwu#{Nu#8_;)FIF)?wf*L}r} z$Udy1X`J+4JCna+-;vf&YpV@O=K_6BZ2aqT$-uKfgXlO*|DC-+%D>oh8I?iXaKKYJh7GD$mw|$LcqLoLW)}Ulpx_(J= z^w40}HEK_n|6#9C7*(%X-roAB%P@0i&hAQTyWszHbZQebX_A>QE1wJlAhRs_iG!dt z3xVmrP2USQ=-M(G*K`IyvS9L<5cw~Ar9C}UtnqV{)q{9fH&`1;64kvZzqc8D|Ae$6 z-zxU7Q0kSNpHEi4z~sZuG-ZoPlBUUt&+!lW)1KP>%eP|pXGwd>;E|wGOS6$6JJ=HG zc!b^jfubG1(6;E<2ul=k`+*$>c&mLnU_o0YKABBMkDY#&EMZvUf}BSc4SQ8S^ZTE5 zwz4Yylu6ItS)@2&2OfmG*w7P8^i#h+qTgNzPDYd7l`m2KULGrhF0Xd%%5u;`^3Hl6 zD52g!rmeH%Pfsp*A;qzM8{f&~n0h2eDZ6LeMHaV34aaAZr-lzi>6IL4e{7=lJn|H{ z8R}^YhkyR(i@v#qrwwjSl0{Eg?&aRTQA+l_l-u5YD8t`~J5fZmv%Bm}Q(~&$l^|tD zIiZO^C8wPt9TXLJoU&US81v6PKw)3BD>hIN=b1WcGo`0K;xD9Ma=i1V`s1E9A%t{U z#@b)fKm-1N&^i7$w1@v4IpqHi)`wOdFNr%MXi&<|Wh>eYkAYIgjTiF^XO(CLW=n3b z__8bSKOB%|fFjXt6MlRFfb*Rk3tmM9WRr}Ua}sZs?M@h$?4n9}nFe0Me_&yUzFSKW zG+;qo4NOk!RSH35h{=&02@^NqMKBs>4y^?aFoaF69Gy0&Zw`QkBU3L91+tGqHs}%p z$QH0ZfPe!7UQYii1Jpbk18D+qht(M08v-g?Vq6BO7wqCtNk-LQE3m7|LmwOsp9Mey zbHZ!)*fK%TmT=YHUYMRLt0yK+C;wp?kbeKB3VSs#U&dq~LmEktCxD57Qi^#kfSW%G z>~w>V?{WXv3bcI4a?r=RIv)Ut&|*)Luz8}vTMCW`26%AtUBCdmt&OAn-?#w4)8w4v z$B#?i=m#1LL=mX<&H=beyS*9+QAT0oQtvhQ(|tPgNYi_O*KgA`$zB4q!2m!CV#u>)J3l%`kNGU1A|j2LwSN-PTh*zH*Pd)@Zl>V6Jal9`l(Er3 z8~B8o4IES`p64Gv5Pf_$DB$Qt8iAXF{QT~ie(s=QqKDeGmDLIJ+7KY=S!La|QZ!Va zN_=bk^1MGH`vsT1t7dS{Q~lJs4Y?Dx(B+F%pN3?rOJP4kq|hb3+Y; zS%5LfqIOmHw!zy}&fz!J#%n~8KcW;g0=PV)g~#!e9$UNRlFF#m^Cf7ct+ zEk0gLQ-H&xsS70XkBh=(^LXR&D&Q3q;fg?Xo0Z#GRzG`olZlRAo0CHNrg_8_Jb1tD zv>!GN|NEL{W{)^h^9>w}kv#1q(urX?mzKfE0MTmC{{5sDYqau!#58dqBLP*Di@*y< zE?NTYC{M`AZA|1;tWV}QLl+N_!MZ|DemF#$?l z39LxGSMY#sT^@?r$$=+NvvX&E zveO|^GkI6nB0s-#z__KRrWV@+28X~4${>LG%YT2^1FZzs3btPlE8n5ejZ{zwZBf~o%gs@qRN8R3vmZRzalf(-{X_14W* z4Z;;TJ+2W%SVF=5#yWsNG-Zuj?WX{!>z=45N=te!%_7_pDkJ$WKTl1C);E98rw)G{ zrpAJdf&TuG{Pt*!6Tw% ze*CY+iL~q(`wI)x5n$Zv_uZnk*mA!IK7&YMd~?ueW2G0{nT|=scSD<<{v%uq6&2xW zi@0-|?p=PqVcxZRw7sE@4r+)fe#0bOC01k;0YuMK%?uowX{rgeb+^baei*ajJ0&E* z*8;~}&K*uRr{#-W^i;4^DJzqW3~B_C?0=CVao~M4qu`B~9*X|LItAkn>k6#(kJEvG?@z>>KuzYG!p~lX0!w=)=Q=@jX0` z0Z02|C>6GX{ALF&3)poOj~=))0m8Mp5)oU7RRRaJxVR&Ni9_*IdoD4tyvY#eA*qum z18~Tg9B>Bq$6Hh?yW-y}P74QM;A9G*w4*_Fdkd3@` zflNkfKsmB+>|eD3%E&l;VftnNf%%2HDP^9&sT04oZPP7B&bs zu;kcS>o3+#gH@K;1PG+V-!01Z%SBQL);-JSaB9=xTmY7(z@Q8%5BM!Q3(bW{h5a7^ zuVE(<4{{AKA5VJ0JVOe^d>?7aNrVMb*KuJ9i8~0tpt}Jk1LqC3ix)F%a5U@&?^iuu z!e)N7MeoTaHY8(Cj*cGv0S7=}Sx3M@`UTvm7q$*=O=!jcxj{A~7?ru5S4CD=$<1I^ z<#fbEMwV`@uOLFMKCcpN&{W1ATfvF+N{gTPp#It`se(%|7s3PeCJ(EID&*hzaUAOa zDS+~c_P;rS8ld`g2AemkbAe6-TLF0UO2LfAIA`(i-*x1He)kS%XZO5RJs53)4EpHf z3&_S=^R3hgu8Tb`I1s?n71~FQr7ht+sn-zbIv9H5^E%7EeQ&YGu>t|3yN!+)Krmur zPkfHQ1^}7zezDLn_yZ8LDPrrk?b|_KrC6%r{p=5t$H9tHAPaZX4%o{uI4WNrPQWn+dWF2ayitYsAp$a|z5Dl5pyn8Lfyn+E z`4x_(p~I>D0sj8L(R|@8-%EN)h|0Yrv2a6Bh@N`qnKG zlgR7GuU7g341=|f%^nI4vY_B~ARKz}EO0ntV;LG5QHEl-`ia=88JE*uV=o{!9(fD| zhBe^6LtiKfBeF=45G|1M0w;8OeaSpULvO5>WuuAScHlukN{RB(|B{Nz-b`y=xii+w zOCtPE7Tz_V%%6Loxp>*hSR=dF1DrGpmk~ukdi6Tyle_=h9x2p&P-Zt$p?M(DR(?3A zXLTv@l`radttf+!#s#mo62!iJXIbcwFMp?frt;&Zy%#r~;bkY@zqPN?BIkcf_qNPh z!#Wu8GJSA(D{sZHlSw_`<7JLLJ7XCVgNAskAHCvcvgLv}A`GLldUl}^VN4Nb7(d5( z$oyrbnEz;KR${2g^BfO3xqyg7dIGh?%X}AVpR!mIzoe4<<}gj7@3-2b57Gan25EdJ zZt6?^;U2oNei(fu4KHg{9NVr^wIoPcdHi{D%g6ozA7L9iq3;-D$iz^4X6W^<@>3^| zZqI#0peJ-M`AMOZbJElLC}n`5%1xx=q}K?u`!u2iJb1Beb|1;?jf9BAba1TAp>hQkFM6 zNPM89{UKf@tzwCnQ~?}`GybcD%l~Ek(wao ze60Wb44qej$URNaF;*%#72N|u&6qaT<AU(w&+Q}dyY|NTUu(|NsZ=P#YnctFL)A)E4I@z=zBoME}#?vQf~ zM22s^i;JUVE|=-29@B~aO{c7WdFL)mtbOwxb#wEd*JzikKAsm zbfV1_6K_8Y{CO7@H9{7?mL{nc$@G>bMMHjvqD=^p|F}jpPU1I}c_MI6mI? zbT*ADAl5p_5KFU(IvNIcBJuv4yKCytcJydQJN*=vj(foyW})=t>8D3cd6Q|$-nRDk z_9yqAuDgvr1WU;^%h+UBFnbU-aYTXHQ)dLkbAG<#ty{BF1#|=^`)I$6KJVV->%Tfr*!|7wKhm63 zAL?wlZ3K9qs%oe*=}E&7q6L8M=czK<#&MPoEJP6q9jO_yqI+cqb{^(PVy6llq`KGV zR{E&E=6dX)>pgbYu+;Mdzrt$gCL?`Ew++8=yQdgm^8S6RZGq9Tx{BkHlA<)`#$+1? z%t;!q<-LCWIw|QedAuF<%I@8}(FveR!6^%`brS%YY)@<=L<|l*6FbkbKJYBh$mS5! z;X@2DzxOk#v`7#iSm^tAJo=FNbMMyO4NKb@tmy2m=w?3F6zUrB@-`}G=kQ8ew-O(_ zn%#ezW;t17M-PlT*#8BEg-HC!GHi^D$BWB06O2l5JDi(2*3BLj#5Pm)M>5-&zAf6x z!4SM6%_88Sxte-FP1)^!LV}@_ljPy^XQof1$r*--AWo_;K z%*;V2#_vd{wmk3wo{hCm)p!SP;MvBrJe`Z0FCqdLL(-SV9^Yq@rJRwb(QjM`te9{I|&<2N6Zhn=mhw6ruT z*}z~uWDu@N&7VFokwch$SgKB#Y$kBmMxrV^LL~uRs0Ie>d#0UXhoflglxiq%c zQ91vegg6UDo&wSV^y6b=N*6EM+1aJ?ey*$I;o}S9QVJV{;0Rn!uZhKhdjn1h60zA! z@V=B}3C+y3yMBGL^0ryF&W~^3?xp?7Nl&k2b_72JnTMBGS=CkRn>X9X?jV~}R#O8F zNC@W$A78)Jm+#-jIXLdV90Nf8)hqso&%xEv}414f^(yDWbwjQ5}~e#_n6DXkoSd@!Q}`)V>sUarxFiOnz#7F zJ_R^seKfo6>MC{YdP75l06)JNODKp#psC}6wwOOtNTs-0p=dTR=tj~F2@^|8ODwQv zGTMzuom?N36%{RkLJs0XON%HUpHha__?`Fm6>IG%8{l8g#ZXgM=i=lP6&ZPf^esJ| zS2*Xf5DQIZ)0p&%|7R0}U5`fGxcy@~9_i@kgN(0lRR0Frd7=WQn|h2}3ysygW+(>sJ3}Z+Bf?U1eou z=;467bBL7{gl=20xPJ?;UcLJK<%?R128fin8OTf=@kccZc?dk3Bb=P*Rq;Q*0N(QO zk%8Aa|HT5J2MALtW8-o(Qqk)H2s465eLw-P7g{kVu6NQiGsl4{u7 zSB)6W>wEdEDMgz1E*d$E=`wKKGuMwc{m5W*OJ(3nLQ>CCW2VwY9scW6R7r|4Zqj#H4>8yYK`V zu{rG6(Sz7S1O%2+nl?7FX6kPBJ@{iGQk1+}W53`UHX`+0FoY%BVly+8jO;lCtl-o2zTz&)kOi3Fsz zO?>nPuI+yP--2dQE=#DM!aI;|Z;u{n=<5dwoPdIl zh6erlOE~TNq`p{7U;$CU;LFSXqIBfm`)5yu(>vhCA!0$b6?@s$9JP|QbviPBVoI#6 z$2$ngR9#Jf{Thy_*uY?XAoGBXe_e zMMY91O{^Gv0Wrrd3GE3wYHHjTxD_Z!&Y98rniyAtiYF96JqzKtS zTQo#P#gTPjkKC~K9ZOU(m;@AAyQ0GyotlEWhL)BVjb{ERgVS(EKD=@DnEb@_w3?EV zC=-n`i6QU`>zVAVtl8be2aUA&wc*H(5~VSF;ou0m^RPw4$8eP&PK5^#9tbQ{gwS`j6isyP)6rE_M#-!J**BG=aP7_ z{kEIzKrbBB4pbK44WYcPtF1*JfG*_j(wG!+P6j+2p=v%zOO_eqo4C5hHeZ63vjj_N z!Ue7m2me@YX$U3|ie4!-$GRmca-E%}8lw@c{v$)=A}U0Ss|TCr3J@Qh*(&WSwsGNK zv2oOK>CO>#m&W`jK^|Hxb^^@APYM}7T`x)zWd@eJ)z*^cYcG?oIP9tUW8IiJ+KBEo zydb;2efyA?m6&+N+??}QQbIyzo2_oP!O?xx@BxLr-|NZM#fGms%N~m z=)g-kgTv}q<-1|llz1wJs~#XUNOGWLjoY9h5EKGOqzrhkXJxET#c&euvfp0+@aI&t zT4ue}TEZFj$*J-5Ec+*h`pZSdOsd=x&Prsh;4&Pqh@sdr!+aFec9<^iqu%!VaFrpL z#+2~iC%+0l=s7BQS7NmwvSP@HW)7M?5P|Z#O7j-?niYp@MMJyjP?YldCol8_qwBBX ze_h#FFRXZ35(pt*xU3pw!Y@1#iIv)%qCqEMq8KNC!It*AO>jJS{l&}IR@Jy(95gIp zb02h!2uk6d>&sY8{w}PibUupqhVik#;XMUcFL_cyns4(S|CqAhr2U&do3{miasK4L z)n#l~m8g2WO+0ca9Jd9l2J{@)M3}7Oxs^22zJpLNLgPqc3{l{0CKFR0jV!-^{~q4* zo&vQf>!AgO!%UJz)y9VJFc0=XtqZjAOj zvSfwc4BAv^L4KD=jEl1oVZy;9W-Yh2wpM{g4|=~i@8{+mJR_Q-q~+2v-6?Z>=JS~r*9 zy|$4gT;8=1C(pe%=%ZL%R?+kOBd#WN9il4nX$F%Ei;Kd?j-3Vt9QMJ)6zdx|RB=I| zBC>u)?z-=Miv&iH$R(L5>V(C`%Q##yfn^MmXRYhMHS3Fob zXh4oM#(mH6kTOR{9l741)G;x!ZygTKpmVK`SkmI?+a9> zhRrUHTW(F=BD}DcJ|b~}JEmfzy?28=bLjtJ?X9Dt3g33&5fM>QhEP&U1e6Zx2I-KH z5&?lBR2oG(m1d+H1f&E(K)OU)8U#eTyQKTO=l8zn%k!;u{y4LiE)*U1?ES>`-1imq zj|s57*_1uK7k%&H`p~omJE_ddZwuUdeoB?fF{u_hP!a6#O6U8J;`}}%TU&eHO{oD* z`8TYR7Ox{0a*14v;B$dqIaTnDLf+s^%gNX6xy405qzBLvRLt!E`0*oL2(#d>HDRcP@8jjO#!=ubJ5bzS!vxyQK1RzFXPw@qmzAf3}|pE(Z4YdNuDj zqYMxn3<2RDyDTh)p}4n5chkhy+U`#GIe(asR&OYK!%cZR-2*+1B@{$&Grrqh`OhU@ z`n3Rcoxs6;`3UiVS?36P{;p_);6un*t_TA#)=-CvlA{>kTdHYdUG>Z|E;Q~Q zBP<8rpS~2`&z>5SLW|Yfj$CiCki?c4*zNYLb3fg}FDh9OJy{XciJ5l}%epeMoIQEc z`pTX;PrIykb7rBN1Mjg0dFgR<{p*)Gd6k|6k-;|gJH|J#j%N?bl27LYBrUr*l6v2+B15)(biCn#7=6UHdtKRz(pK6u*(jJ=3i0W1!6 zPyf3^JeFBnd~!E7D<@(_PnyQ?por3v$^q$m32~;R*P?`MYqIZFQ1eNB)Vky1Yd6~= zq)HMc-z*t3U$!Y)#ld!XbP{vrq*9IKMnWMMBf+f-mR4Fn(wNvFKjn3i`8TWt12vRZ z(P3pl{rR(+r>wl)6AX=SB6$EcWMyYl^V^Ekg+tF^M(t1pdvD}64=HI4- z0$Jld=>eXOVhoPyuuF0d88PLWNzA^9BhqSz*VxNr)w{a=_dcG<41XBsbIQyX*4-Q5 zV()i7EyYz{{!C`fj`)5G`}rk9^-E@!R3Ou1X3A!hmE z&ke+qdA~I-4Q|tRO{mh3d(z09oG)rN9CSWY?^0gqq{#AKC+o1gIGT2Ja78~6M>CnU zC|>R-eh?WzAj$AykSv7wF|D-b!r9+J{d-7-PN(va)nf*@b60fDa^4a41P1z@MJ%j* zU`P`;s*}Bv&WSMkmGB+LM3X70&UpK3!r;f9$&C9XRQ` z5MHZIbEr;SdF;7Lm#5_|a%!eI^{wIfDd#5_`EMP*FRwjyp!6p~#ZV~k(&PTLFdn;W zmAoD$+{0J;=0N}9`j4G8&4uJ8>s*2WdSQHdZUjP!NiN|MVmP^-(j@Ca`ZE)k9izu+ z1%G5j&|^RkQ;VKr)kh7tu@Y7^R&B$Cf@XMq=<#G21lwepJ`qSRK3sW&bMG(0azM$ni%A#F7nHEEXNE&uqA+_^w?9AHH^>+wqwcfu}N}6{l=M0LiMwkX<%4`V372J448>Dul@r8;iJORndzc)bEe{T@=fCx$*;T?fP=O!&9#>uYYFmyFZzX zd_?a`XnT=_eLN|x&-X2TTue|NF{yu@!viZwe-N4&CQHk?1_BCLVUs6}mdLR4U}^G;NPX zhk4{?9Sv{92x30P7`<&kqhe%ShR>$m^ps8($k}KuSCi?yw`|lyxMJ_`i{)O z7e`{}=v$H4X?zKES+4T;>3nGVd$hj4Ik;xAqF^_g#IqAn*mhQ0T^e)eT(ny(6sqKvjb{Kl(UeH&yQlie9U&-7cXU^F#AdO+MK8i;JH!Ud1&{c2s3LPhvWlDu20)Zg9()ujs z#b>P`OM;@I{aYmWI3%`&sY!{sHit$f&1CefzdP9`m23_9Rkjlb{!U`k;JF*g@4AtG z-Sm^hZm3qiHXC zo(v1|>)&#O_}0-$tmPY=Ao7>`Ni?|04Wzf{y6lAI z30cApg&Q)a8M|ITR#6b&#d>Al!zm&L)837wkp=zPo|!_H#I)$iTd_H#L4w9f0V9`> za&)}-!cq@mxhzml3nAN6ObB(!tWEUX#Y(sXk-Wy!_wpkACy5)s(aS$S4MU4-E5><> z3CgQewrVXTZ^a9cr1jG7+gL13oIEvCEqr@eo4_%ou$=J5ZexQta-6`nWL3jb(Dj(1 znk4c^w_e(}2<5lz$0xOJy4fh@EWVUO4J!=_d8CC>i7wSP_Rqo2hY_Dm?T`L2biuY> z@i3s)#QG(wvyID=fvE+CnZS+vTDY_+i^_Q1zqy^I)#>X{eyEX23d*BC`G^_*f~qNc z$qxTN&c8mq_Im=Cv#A}gDpvijSP0AdrTfFsK$N?%K121r$WJBNg{qnHFXg#aVjruI z=S%go;2^N(A(RIx;gTP zc$2Dv%yEBrJc*Wq*3|rKPJvB|4_S#sVQ^dt$9W8j=xuMr&z(j4l1#1;b+JkG{qNpGVb)#YcRf;68Vc;aV|n!P_rRC1J-_5UJ-_;E9U z=3NR&P!ld~%nP|7^7_gLTOvMC(aY=)@8$s%rqM;*g|X@<5blZ3ZfNa@)qfD&T=b`> zv9C{yHZlM z;a+5bERUxsEZ8}01*p)E(sW^oWC_|jf5)@Q55gA|^UTq!60mRRE3b#dLurVV%=)C~ z&1=Q9vJwLt;@O0ShJ*S;v6**uMWu=vd@2f6r@I5e^~Vo0a&s5SN8^QT1Y7O0RimxW zM}vmTPx%?#FB?5P9QGG-a@(>Alzu(&Z}VVMQ7ItROR8|vc2coNjDnC*xbuu}?4ULK z;$Kte);GKLLBEE9tKqnuc#3M8O(8#O()%|=qrI}6Qy7utqm~Ph&WbCwcE!j7=~~zf zcX8X@mA*l-Su*39jysfvtfIx~fqp!Ud+o}1eLCap(XV1^}w3CyQ7|$y-{G3DL>E&ZkmO&wS*E^XXu5L8XlL>SFBNHgpK)N<`T{GUy zxmh~1`*{{}3}&uBmArJD(la=5(~-PLy-1FZP)_HffP#?H@WlrMl4Tjc47!vzDf9dZS#-WxBTQeF@T8E~Xk?YZ#;Mnz8$YD0 zE*WqBrZSNUXdR#pr|&4HZ$IfwYTR)%H^~%dns&BcDm-QodG2u>-~9No@<6r#MM!6n z;q{J=XW6Pw@(H&;X)3I&R^6gv2?*S_vscg8r8t={aOC4ld}e(!M$WIcwrX>K@q5|6 z;aEggdvmaqId1ui9i2>{Hv>v`eq+6iXN@)EG)zX1jIix7|DO4b7n6*zwT6au)kNuFJ$BTDo-oh z^*l4yQ}pznBvbv=+7A2qUhF;p{{Ehtb2Oi;t4p@>jj`jFJ0v9LJAA$l3+yga=dPZD z_KuU<)!VfD?j>T6SZi}Cq%*Z1cPCZuQ5QaAjy_D=L7(}Z7ls&QH? zQC0PS?}~k;lFkncE2;alws;%PaB|`PMk3i=^Yg;euQzEO1s|>FGE$4}t#UHTww_Ji z{Wf-CQ)qp(8r+l2@A11~LX?}Cf_AsLV4QmGPl`Lko4%h{49^ep;-_EW)TX5uU#E54 z>Yc9Ex=1T8-}Fp5>?q^Auw&ROk6X%#<-O=CZrDhn3YW9EHS(t@%1~_NXp=kJv!txd z!+ccCf63FzYTW$d$QW+B=izzc&!6d8Sqnu~Ttu^=L!+`Z(@jXH^TqmlTZ>^Jl%pTB zRWN)15qha1Vj>f}&{9!h|EQHVw28%_+xSW;(V{v)Qpl6`^J{fZ&qjLxx!=1MI>`- zYYQ_oo#?u;y*Nv)yPjVWh+nu!qP$BWdFj&m^oulXiOwXlf`Mh0gH$2&{Z&s-hvAKj ziSq4~$2TGgB&ppGC8VSV7*pL-{;gi~o$x~Hl{vQerFu^DZ!DU$Zt4`xoW8#?VPJ45 z6IrcwMthGtahBh~7q2nD#{F@Z0>?Y- zLKA0(+QX|h5`Vqt$%CTxW4)D54ocK z`Ge%Fo+7q1n_Fom^zsuWw47YOMr)qar&Eu9|1sEAm0QHfSnblAg(tHx)!?HlDtgr3 z$_VX*cfYnF%B8{f>?zhI+xu_J%Cuc9Rwv7AijN9eI!>3TTkDSYg@B^ByD!8}eCGr9 z)xzf`3WW+n~J#p|QejEsP-?FrA!L({LpUB>BdFt2J zx*sn4dmLJKt%zxA5090(p>%bRn0lPmbq%Ov<}DJ!uBVuN{Wytugn=%kq5-vycJ8K~ z7UIq=sC!)+LYBNlxH*f46`?QweE!F<)dW_|l@1U=>5+rmAmhowMvXdNC7r@5L- z!@_Qp{D}Eu7POlWx9;uS4m!8tM_6mR)QYlMhUu^z&z>EO*ST4mX}xuR3}q|TQ)i9d z5Hj;_(_+eC+n_%(8`MAB#f}>B_3SEOc?qIf)w(X%-<350k*VlMm}(q-V+G6D5ZIrof03 z>NsU&PR8@I@q+``+N7Und268Xkkhtnnp9E$VS*XLEw z=e2yqbF(`H1%GdBXrDg8{XtxQkZ6NXb>4ouYJwIfB_VRiOl~&bPNjC;O$o)f6<%DO z-5DC<8`FOtNjPJpTdYqPov&NFVt8?0&rKG8ZQHJ#-SBvXqRrGO71pyN3I%Y7|LpezC?zu?5 zaJG`R{qYI^?1k)xj^pyfEekFQB&Np|h+F({v%EX&MOO-^di2%uo7+nZvGo+yQlY`a zlNAod)d=gCgL_?~RKv>Nn{_t(vC*;hr~Nlf2B(nOshB$B)T8vF4*|8KsmB8WLVR9F z!J1*SOhH_nohW&3^1^0ioHrb-HUYA<@Vs~cQj@w4ei4P_D5Zyfhg7Xo3sUXc9-j~k12g3gjbZjOQzf4fb%UzpKh=)wQs z0yKBPDO%&nzfHchN@naEsznGhKKsLRb<3b4nt z^G1KZBUFP}_V?dLj=ygowy`4;?oV<}`>vf?R}r#rdVoaO`c@hkZ|-TsH6E^!ZJdX+ z!?DZF8_wq$wsxP7jQcyUvndO-g31|zm|AeSYu<^AfA2ss!MwZ3Zr_xQ$n6d0pZZ?C z>%rcG>?M%!*0P6+6;kICf-k!$|JR?3cfU!?-rl5RT!1r+B^(!w!ya9S(~GIorLncO z{M*SQ?r(>J+Be$hbTbbN=on^)qC)~ zWJ53~<0>ET`{;bt%-jN-y5j;qN}*Tpe=6{f)K+jp4Hg5)S~E~>ak4$*;|t5?B&u)O z5pn&*T3m9J4S#$9+&qONhQqMaUHDL#*X&I$DBNIPAF#;&`|qT@Lx3#@FRwK57AWw+ z>&Fus6P*8iWyJK66M!(hIHLMGTayfRL>JC5e}YF3zw6@qHgJr%|K}e-$xSWq7%3Tg zbMFZTk;ChM`aZ;MasTyQ((3@r|MSAT@;|vOvhC{(@8?Tr`|zQ0nu~q)U8sd8=7-v@ z%Rt_h4CGzG1X#L-xz5nHd$2^pw^$2M^O`xo{_9=;Z`c06`ZNEpTM=R=y1-nC>PzQ* zZT0YQ{!dZ+1{PxKxN%1q0HS=voOFmn(&^stHU3}H35iLP3}}MU(a{W%?L9pl-L{)afVPC2M#gP621z&|4lo&v2VDioDB>V%rx=(~n=j zt^*%wv-ZFsC|${oFE=k84H!2}Q*IW8U&2Fm=EgbX6k2yND#Y{*hMH(Bsth~7X; zKcDi&H{}}nbONm#Fr+`6_NS)uFppB0_owy0E^mV+_~;zI=cOAu3nGiz&5zXLO3Q>VEPSBjiICtsQ}<0vR1;ace9CJ&|d zIK&7qwexkn%OS@FTyTM(e~*n#C08@7U2V?3GCF!NC$)R$6jV-|a3_IxG{dSYyxj!K z3os%o*v)>NH~1E!a&x%p_HV^K=`$Z}IIcz@8EA+`{}k zcq@WG3#pB;%dUllM8ggC8ZYF}c_gH2NI|3%@UNcP)S^7tB#=P%Zr=P1BsOT<$3#c> z@gzq@?Y7-RL*MLTQS1V|Ffl1l5KO^U#Vm#NgP{>kWlU=3*o9?V>s5W$a=Xa@b3#@X z+4~KjOc>g@hDKy*=^o@>1ooWu$x=g}iXiCnTJ3ovPIYhdh;;!c*ZZtU7VcvOgN}fX9P235b4az?2vW>10T3ZsUFA6@D`8?CBVSIz{|T2 zqnBIu!UJa=56Tey`qpS9Fnh%ump;zZ1gT_$n3=K_W-7|u96!JP@)QpA>jnk~LBL?- zK<*7)U~%=cf=9CSWrmtd9*==7*qN zf$o;oM2$1Z17P-88yHLgb=0PEKBkB~`l?a?e~+qnDb$WaP>NtsuGIGcwZj0^q4 z(4vB;HV93j#{{yX0nqKXw3xvf0?8ov!v2DfFR-P=aiL-B30Jl-bR1m>hi2afkffc% zc$!%Uve+4n!NT9|X*MM8E4kUQe)vhIH5fr&)x+qQOBz&v$WEoe3;;-fU89#TUyfwW z(r}*%WZc3BU8I13Gw{=-sIPdfJ_obu=g*Ttrd(d`zrDbD6$1SXfK&y_in{&3uVgZ| zVY!gPy@u^`FzGqj)fGC+5A-e{8b|`{jssaCTeJemTP>}uYC&aLq>~gE$8;wc!gEYJ zr#^80*A(9Y&$V(J>W<-PNI+@nV7b1$U5qazR62jDLR@06F7(fJv;EZ^VhURb#T z{HRl@dhbZ@`B$I|#HEF9@hNj1_jl?YLt>!zz_OUEV%}{{APM)%1Zalt2jiHAa<|YX zIHST>5S!!jOZ!VEs5(YUUy+HL_2z^c3x2zo%*+THz5X{NzMyfE;+sHj1# zF_CD@=)dO$xVcKEZ9&gJ=AZ~=X7<+65oFn*+y*ixH=b{Xt%E}etd60fq2e?cx7zI% z;4bX+{@fD7gZ!sy9J{F&2}*8RVCLwZ`sQI?t00~RQqcQyTgn4)y=2w-27!4HL9qww z^JIv)lU#x??(SuNn*-e&a6o~=hn9bZ&_@GV0@whiTx6Q4kgEZ;W`?jjgLoAPL9kRs zE1};V?8<5jOPl|6mOo$1qmiPsk}KfU`T{ymvl z5lG)};`lINvMur1b+^W#CF*fb~GG<`>wcZeU}b zMuCAb?EIh$UIfA~BxwQZ5Y+y8uwKEwCvq@W0x5lIPr%jp9VAz}VbpbLX)xSCZR8Gr zfK-^!X-6}oRPY4-l9vZ_vupA)^eRYw{y@BR4@_QHFx{`vVX1?!_^kc{+~I@?3om~v zmo`{*nuBfwWPnG$0{jw}o7&_ETLR90{7-=B2pTT=iaK_rKQ`&hd@vVl(kgQ{29Clu zbw_3}p-lczBYuR^)_)V`|M5y%m5gpb1#ni;(r;p};hCZ7a6q+)iU>7~S_qsj|2)A5 zTWhG)1}-}9)LO@gK_}^^**|Wx4qPFvzPCom)Ibl~UD^2aNEFi)d? z+}W&}#`MdGW64nv=yR20Uotbv7H5c3!Ex%x%|KaPe>E^rHn-Va*iad8G?$f?dVW_T zA~FT@?Ko(AV)#XM|e@Rd`5LvbpPq@#zZ9op=tB=sM+S!R(~)%2046t@{kFTtWxecQfzf`QV)b4TNJ990wnC^+6J|o=VJXl zBJM3Ab#(@g541mghOr`ZNxO^y`vnK7zW#H&DmS}MANuX#4*8&9>er3a`V^aj81RN~ZB>qx4;!aXN|t zb>!C8*3M(XfIyh2NP`@My=U0%y-ZZgi^EniJ!>U-c{_Xi>({PT#>B|J?Cs#+ijt2w z9Y{U@y;%t?GXn_!2o3EbeVbKRcOLW1nrwUk=#zkYs;^SJ**ad>GRzcHK z9%@5Fuqn({k|Fey$*{Dv2JRxfR#w-?Pk%8xnDtm&S!KTeIb2?&1!cj%e_alH(^N&z zF!`<6bWA~zha=p>96e+b2hO~}m;8S#nbg0Rm8J08(b3X23=Bk~Mqt?jvKWhDT@ro! z?ye)~BfY#Dh9xTA0tXZnwZOQiTqZih2yG%d>%-QAwjk>+PRz4TJr^=ZBIM{z{`@Ol za{4v<%k7H(^XJhD^G%eFQ+-{-^&nIL5_`Y^^(Nm#(%i`bRPDrQtN%3rSFPY-XI}p& z9V6TxstMPOlfJ}f8?8OYZJ+<=k#{Z3_&XL*Ta@)$LQI$&IfQ$-@dp0(uS`vOA%V=k zdG6pUZ3-OKiSv43_Wn(ASy+Yy7g<@^a5+D=)JwmOICvgCLYbr1N2~dSm{%M8sZQ4h zdQ?({EnnHF($GhCjQ$<9?ZRob;|GJvP%wek_PcfSW^?_}{}4$%KeNo$1~-YV{EcG`sA3@y&}AXsd@JhHWyX6y z<$-CL+1zYF`60e93VfSreP|fgCLbY;=#btf_%>MZJR!bMe64GMF;DYLz3_I0 zf42GS*JHD)!nseFwo-e%Z@5I#FR!e)3@1Elzj4Roq^nLDaw%dHUs;(n7O_Ym17>Zz zKImnb>E0o*5dPmOsk(OYKmjyLU%o`No5Jw~a2d#e8)e(OyN4`zKsN{O`)Bqvnd+FZ z+26nCR#t+L=}aq-bt;PshsfVULqo&E6nHogF#xt4AnOl3d@$*8VkIewb?yogNq+|i zQ7~_omIA1O ztNqqc6?wn-h@8jrt=*eikUBMBXxFF_k3EWEi|Z{D%-|w02@7=4ZD#N-hxrFG=U7OW zh8n+w5QeP_agX2&0A@y@MuBGz;=Ei09A%@h&8t3n>Xtl8!dtFo;?Hk0YvH^ra|B=0AV(r zZ&Mr9oBLZ^{0<9v6VS|o#|>dSVE0oDH4oTt{CXj*99A%}_5qQW7KkJb4bjM75N@`< z4oR$oFp}8yE4)%C1_z_zqft}WgZc z3grd5a0@tG(uFU<^=DavaD4!z0|1^uVI-%l42j25`YkYA&@5AlqE~Af#4b)tU~7YO zDhzeVsTOrC!A*nHrviNhn1p~3AfE5e?c33@vEak?4w9Kcz62a++%&jJUj|p;d16HV zu;rAM4HYNDAl9x5kxKms#$C3pu)~2XfFno?pzMPuf)v_P$NSqZQ78`D$XBmc!At;Z ze!1$oo!M~rAf~GV-1(vY@cXx>Ft6Kvu=FU0Ne%aR*TwzC3tCBwsbJBqB`AM@;}84} zG|@%-b`W$ znmyR6z$L3y&C$piR(HzQc+v$x*M5@I0StI|!$68kAo(zQC8MK=B#T zs*o80v8%9(OEb#<|4GLbuOdj_x96KM;7aBVmN_~4sYewSQm3Q`y!g}Q>578;3;~lR zC6Vb&L0N@7EZ(zR$^(?GaQJt1c3yvX;d>VvcxwZYKbEV{cCfX}!>J@CRXcxfBGj*> z76p;zAbfz-F;Fn0(dZ*uS=m;|ap*AR`tX9DFwi+9Y4HeHIC__PrTI4hK ziS?C|at_O|B&Q`NBRc{IC`>dxj45o1(|LAJGJZ&lpul+ikbAciVQ9e1FC(+aT*)9uI{S0;a z|4P%yXa3&O`z^GUFh$|s>A$nLSF7$T1-o?z9DTdHc~istESjV?4+B8X1U6e|RXm;A z4glCYH2^v+Y&xT$Xijav75r!^6YiMyifR2Fu&8ks2c_*dmf%UKb(K|gO^>+=Y*`7X zlbk7Jo8=Z3s%8&hYRHdlij+cr95z@MqN-lkQDD;Pz?uuvgm0-mfgaQG| z`x7iUP;Y{_6R50Y>0s0Q_Jhk(W>`OkbI_Qbyf{pNg=G!C53{QBCFAzTOY#x#M45Po z_@pi)WL`vQw`Vb}oK`wi32p9z6%=G;ZKe6gj=iNQV5IPnd!%|4nA$%+e%9NF&&TuI z_1!zB+gg>*&agRFd>X0Q0iqrZOwb>{wzPbqJJj6`fQi7Sr>kr5Whn#!5?+4~mGR5w zce%Jp@xaUF8Avp!YWbnSyzxbv4p0n#9HgGrfd4G$khrzAK-jgH=+45&H#|8xDeMnP zmQY)#INYmpzR}3R&l=M)5Ac408PX^TB-L}H(sLmFZ2Ds;No?iHqXtj=h3;g<2vbP; zg4Ag^Ab`fM;J7KRFi?r1(II7u3U-g_X`P))yq!AgTuniUa2K8@YUF@&97J(uWZZ-7 zMd&qr)q+OH3ScpSehb-n7lV|$T(^ik*x1DR$U_$zmc7}BKE6+q|Dqs)9^kD`a}cX8?7&3WcRP z*l6tM6*Brr@7_J@S{RBtW}F?BZuItg>BQ9mz`p_VuR~i1pu&~_2um8;l9iPOK-TXg+*C(Lkg^RdJAxz>_X|?}lrW+UI70%!oYo(dC=7&UM2;Q+5p2QWYzBJ;mbW-P;Uhl2gS|aYJO^;T zk$ASsM?AN=nHnAr>r-Bz1(*o|((p%OMv0zYLS@ybN%N5ZLdM?wVcZ5`i$|bGgOxfg z>{hKoYD~-ru}r*U z%fJT$`ZDBrIKm_+TSC_mao2O8c#B@Tw*I`9EzFmM00WKhz5JE5Y-VPfGq_@&>S>Un zHo&8-rU^TJa`N3*(6K;vY6w9V=tcn>#+#y#35hB;Rze^sF3U?xXyW?#N*PT4)6;wT z&`!QSd#d`Hoiw-Vz^jQ+nt+?J*3*`4kT1I^54m9GxwE@NzI2g`u(g}oh zba%H9Ne4)$1DrH7HJuVOdzWPZKOO1;u-pU60{{}O@P2h4CIS~1*RPHaScU((i&jgKcIB%E1V(s}aaV|=`>h6WKOWr$*`=kYRQLe@#wKP_!- zzbbuyc*w}e0Q$nu2PHM28Zd4B_6>=~ z0jHRd5Ig`O&;^NC!rT&IEU4$gl|fCOJ+=c10QZo%0KNba!(W1W5H?0oC9-tb`d_?+ zGtey;vXf+cuu5&17Zwo#tREs{0*5&@wQx`d0z%r~FDou4-))AKWy$FQ&iZF~4oBCg zgiugafxe!LiwnFhbV}i}hzJRpf>vO*EiK{V;WZ_9c6BvBPF=8uNEirRJjH<(VE5m@ zpPM2{=Fru}NU+`dt{QlHi`&A?gLw*3t=`#LPnbGwH1YBAp>Z>229U50WgFlbJscdf z&n7FhN+5y?`19=9bCEmAl5NIM#gf?k^;6j3;Clh}^yYBjrRs~IS3AI;4@@E;%@ocr z(8Go1sJfck3n(uZ=L>LyOWK>gJ;7wQ-bw20KJ8<+KG(Lti4Q1TVSHUZufBteP5c-- zDrVa=&5~)o4Gq(P`gaZvoZh~rs*1$%O#^K|9UT_!=Yi#i4a8aymgKE~zr zS=j1R>9D-eMR~{KkDblOf_|U-qP|uL{c5K30&(7{6w!W(7D*q}7D{qm4`2H6$Gsny zbF?z`tiFz0kLy`Iw;HCRVt)I^)2h6Bw6^Mv)hm%NWkV(+dbdlp)YLA`6Kache~G@w z2sO`ou@o+ff&gR^V)7u*6PG@c@wc@RLFwRxnxCC= z{pQU_fxCo9rkXIVvc3GDprUacNKcs3hgUqh{zg%xEZtp$w`Sq7~#L zpzA2Fq>zB52p;80WS>e~C-Y%uXUDh{|7YKU6=e-Zv{@e`8#yv$LiNC#8XDsDPzzhIBYX6FROMxlZPkW0ND=SSn;J9V`n(`5)dP=I z&B%6Xbz*2mSAau72)T&M@1;JN*3bZhDrS1l!qeNadhwbHG@4L-X&vU{WwV~kQJZZ+ zx9+eIfI4x3T}M2Eeptb&*xiCRUZ0HzPT}Cj0a0{QaH@xcwnOf{)xV6O3U0u=itwT# ze`K<|aaYulX_!O98GQQynQqqXs6>vVPSgW$SUNiH#zTHyve4r6bRRvNiL%sAu7kHWqWu z#w3(2HtJKoA;_1a_T9I|*RLRWXy@WRacP6n(_2D{CNqER#ir+&$f9w8kARK+`UJ4_ z-gc{f{Fqs+@%ApAuYuF)pQ6|pwt0T*lf~5RWWmSb^mS=|v;0`JF(~MqrOU|bvfR1q z+VZv39Dxu&Fq;fXTON0no2|&#dLx#1#)o11nt`zq8)#Gf zm1q+&i$O(GQ62J{p17XyhYd{sZCxoSC8eGfdC6 zlNN*S0E;rHIRas!Np|`>syZ!i4LVQ=)i@C|x1Q8?Q*y{Gl*woa91&g6`#J=hghsXs zT*UCu&@F0FeTLZCXNc`j`ocT?)!K#dUD)WLndqFONn~siDsxYa05A3&HZ^Zw9B6lt zeXy(X?yJZi(R?vJKeGTy|>_J3;!HJ4!ITK*16>zk_Rv`ZR!J@M@Y_|;gL=tC*Z%1OUP??zX*YauWc zDSy(NWi))`@;ryK6~+cBAcSEy2+Ut~SPF7-Dx5Y`$_l!HKn8xyxM^Qg-TnbZMuWKY z5UhVqOm5pd0~f^FI!vG8U}I46s}?t&32$Ox3-^vd7(IgK%z zPin&08CRCl-|w^dAT2`|R#Kd=!-DaM20L5mLQ|2)f_E%H88A?mo#8U0PAD{}mO(br zr=i&|A-oo_43wK$76?w|-fix?Lr*F^UG{M5c+G2Wgo_-JUaud@;c zk_Mwjm^;Ijh^q&Wp+ZxAPM%k&vXR#t3MlY3suOXw zNcccebO|9sBBAqj$Us!|P)jT*9rk_*9e_d;_$f@3y|d8o?&xp;V>1PPYn|Uc?9u~{ z)&?mW1(=JZ7dLLnh(c2d6z^)Y-?=mK*)pM?0$;U#YkyxwL8ZI1)6u~RoH%-y_W-E^ zOTjo$8eHLA4ygD%z##(}4Cyj zrCODPPgPZ4zPz0N3Dwc}5Dg1PL+~gHqF=1poS!(?`=zU7C&QtyqK{0F4eTbh8zt1< z`8r>mpJ5CzPWEfz7f}6%3k|{8-m+BhLC{OWSjbs`i?(-gcqW8hJv)U>gz)Mhd|j2) z{CfYNI+~QT-V4Csm0!g(6?*Hu(PwWiU8pY zsv=;K2G3SXQnIDFiFl&sL7JuT-F6S(5wj9CdI3>}1(=5%%S4FYff408S=@LfAaL$Z zHC%=WGfmCi>d7-}*kRvgAq(2wFq65fz1>c0(|$G2m+&US_OZ`8=d7u|fz};T(j4{N z*Sv`ag{{6H?QC!)kT1?oh6e|ozi47h+|o~_!FLtu*;lRFh94Yw=Y*R9a`c2i=K}a} z6Vk(KU81uri{$9jEPwYRXY%)AV~5v9+;hvim-252hX0aE;S&4R)1$HU-YZ2Vk6Sor z@Otg_OF2&!GOHz*o(f~1i{pFJWkW;VMWm4f&P(713;>iayv>3K(8-* z#LM63@2aEE{e_F0Q<_XZV?KF#)NZ9VHdll~S-$VlP1JN}S!=WFN90aiIDC;Y^&77ir?18Xg}yI|Kq_#lhX@iv`5p0{CpYd-8rNO+l$wY_g^U~TrSg(1%a;Q zfN^-hXQn1Qtr!%GSfg?ekMb;<*orst?7;|-k2v)0!9H3-!h6EV!XD>geJ~W^W0I3^ z+5wDvC&^&;`w&;_^ypJ|wl>&1H5)U?UuQJ>{iKyFxY?NZ;#ArXH-b30nMZkNbntLN ztPR-fQwaG8I8|TvzctRr7Smz6?|(XN54MRkm{}^~O~m~&SLCw4S; z*eU2f=PvlKy;fV#JK*$ugM@|u-Jz|T9p|}4_xTITRtbGz%Db|f_O=$eHrA``yEeX7*E{ z*2tP3v`_g3Mv9HrnKYy~pDM16AM6DUYr(tRdpYK3$o@?2nRe^NlH_qSidkz$%w~Ll zdGdUlQ*tTw;;$gL^ZuM)Jhj{5V)tpYW6+SK!_Iz40WPdHR#!{QL-pA>Gg>lhUSy9b z(xp}FTf}tScX@sWG*Bnbvwgom;2_-e`9&*w{BR3BxxBk4Au+MoeS4xdZ+vGS^>v7c zLC~}ZNUyI&BT@|o1Rqu$4Yq{dh-|;_d9)K~bso3M=A5T~$L-E5xp0*-VGBb0~ znDafd>ghYDzq>j5&!)3NadaJS=vuXJAnIW;8pyUnOz13pXvEJL~SnzEEP<{(4}fD#QKp zw)SgyxTIY4l(alH-5Mn9s6RbVO7y;#L?liO-@f}ukb}dEzTNze@LA*0jax&Ti^Ibj znJzoYd#&|n8|_1^u$?(g}2)Io`u$8dqy`1%}{#*XgjFAZQ;6!88vOs=>aCl*t`T{GQk zWzV0#bv?T*D9{^!pCkz%A0@|er_=JQs%nFSeF(CJd)05?He(_RiSsBN1J9h3KH#VC8K21vs z3T`qCbN~KNM~{7rAGu)B;_$(PUt94?SXk)w8#$f${ySNd(2S>N1a$q-%!AqsK>I-L zwdX?9KAklS4&M^#o`gFnbOJWED{d8Zy|C_4_q2i+Z&n%4oblbV2+xM5R zn9MNjl`F+@aRY;bdo_9bm5gFF@oGmyg=ntDW_4V}~7d>Xmv_zR)mNIwF-~Rs3^oy6G z$3!J3&e-<(_PE#y2q6y-J!WR&tCh^{?2$&CraHkTj(W#9<8{nDyUzVY4F{<@9V-_x88Ycjk7N3 z;O%GT-U<&3c%-X2sJ&;?(jIwnEwQh(6h*Ntd*INaJEf(MKQw>&<(CeA3bhvi$DsB) zvG(e9T7*zVd6`RhW$?Pq^b7z1a9PdUGoDOJ3h?*uHtiVz0MKq-BQc|vre~;BUScuL zvTT?BxDWu~BH|~;J@@QFp;sZW7DKatzkWUHa1#K)0SS(?5d@)9 zd5Xni`%!-Y0026|J~T5{t5_sToH?_vudmf=h3yFdK+ojNSsCA*IN`*r0RRAKi`e-1 z$M7n@=(Kyg0RX`Db+J8Wm!k5J3%vwKTzq+;Cs3=D4{EhSuR<6PYPD*WQs`B5PcB~E zTzq+;CxF`98CQ1odCaaXWq#D2-Ir?Xj6yG@1u74D%KRvyR{?rDrMp6_GZdFqJ^Z2F zj#{Nux+{cUMfU`?7XZhg_IAdVAu+d~pP%Qd*As+Z1pqEh>8^m_2%HOQF8~h(wb$vO zD+2%k00000M<6i+000000N@BDW&i*H0000Sfy4{|00000fFqEY0RR91003|V5;Fh* o00000jzD4t000000Kk#|2WN|oXKu~lBme*a07*qoM6N<$f)lLP;s5{u literal 0 HcmV?d00001 diff --git a/doc/image/odoo_first_installation.png b/doc/image/odoo_first_installation.png new file mode 100644 index 0000000000000000000000000000000000000000..1aeef9a7bfd0e5780c5be78ce20e77c01452234a GIT binary patch literal 32314 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 YGBE$R(R2hqtOk&mQIW2eGz ./.venv/repo && \ - chmod +x ./.venv/repo + python -m venv .venv.erplibre + +RUN cd $ODOO_PREFIX && \ + ls -lha /ERPLibre && \ + curl https://storage.googleapis.com/git-repo-downloads/repo > .venv.erplibre/bin/repo && \ + chmod +x .venv.erplibre/bin/repo RUN cd $ODOO_PREFIX && \ ls -lha /ERPLibre && \ @@ -59,10 +63,10 @@ RUN apt update && \ RUN cd $ODOO_PREFIX && \ ls -lha /ERPLibre && \ echo "${ERPLIBRE_VERSION}" && \ - ./.venv/bin/pip install --upgrade pip && git branch && ls . -lha && \ - ./.venv/bin/pip install "poetry==${POETRY_VERSION}" && \ - ./.venv/bin/poetry --version && \ - ./.venv/bin/poetry install + ./.venv.$(cat ".erplibre-version" | xargs)/bin/pip install --upgrade pip && git branch && ls . -lha && \ + ./.venv.$(cat ".erplibre-version" | xargs)/bin/pip install "poetry==${POETRY_VERSION}" && \ + ./.venv.$(cat ".erplibre-version" | xargs)/bin/poetry --version && \ + ./.venv.$(cat ".erplibre-version" | xargs)/bin/poetry install # Install local npm RUN cd $ODOO_PREFIX && \ diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 08bef83..847d272 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -12,7 +12,7 @@ then echo "my repo" $(git rev-parse --abbrev-ref HEAD) repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --abbrev-ref HEAD) -m default.dev.xml - repo sync + repo sync -c -j $(nproc --all) # After sync, terminate the git checkout. We don't need graceful kill as we don't do commit on the git repo during the operation. kill -9 $GIT_PID @@ -79,12 +79,12 @@ case "$1" in if [[ "${STOP_BEFORE_INIT}" == "True" ]] ; then sleep 999999 fi - /ERPLibre/.venv/bin/python ./docker/wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + /ERPLibre/.venv.$(cat ".erplibre-version" | xargs)/bin/python ./docker/wait-for-psql.py ${DB_ARGS[@]} --timeout=30 if [[ "${UPDATE_ALL_DB}" == "True" ]] ; then # --stop-after-init - exec ./.venv/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf -u all -d "${DB_NAME}" + exec ./.venv.$(cat ".erplibre-version" | xargs)/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf -u all -d "${DB_NAME}" else - exec ./.venv/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf + exec ./.venv.$(cat ".erplibre-version" | xargs)/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf fi fi ;; @@ -93,11 +93,11 @@ case "$1" in if [[ "${STOP_BEFORE_INIT}" == "True" ]] ; then sleep 999999 fi - /ERPLibre/.venv/bin/python ./docker/wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + /ERPLibre/.venv.$(cat ".erplibre-version" | xargs)/bin/python ./docker/wait-for-psql.py ${DB_ARGS[@]} --timeout=30 if [[ "${UPDATE_ALL_DB}" == "True" ]] ; then - exec ./.venv/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf -u all -d "${DB_NAME}" + exec ./.venv.$(cat ".erplibre-version" | xargs)/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf -u all -d "${DB_NAME}" else - exec ./.venv/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf + exec ./.venv.$(cat ".erplibre-version" | xargs)/bin/python $ODOO_EXEC_BIN "$@" "${DB_ARGS[@]}" -c /etc/odoo/odoo.conf fi ;; *) diff --git a/env_var.sh b/env_var.sh index 2fc09a5..4c766b9 100755 --- a/env_var.sh +++ b/env_var.sh @@ -5,10 +5,11 @@ ERPLIBRE_VERSION="1.6.0" EL_USER="erplibre" EL_HOME="/${EL_USER}" EL_HOME_ERPLIBRE="${EL_HOME}/erplibre" -EL_HOME_ODOO="${EL_HOME_ERPLIBRE}/odoo" +EL_HOME_ODOO="${EL_HOME_ERPLIBRE}/odoo$(cat ".odoo-version" | xargs)/odoo" EL_ODOO_VERSION=$(cat ".odoo-version" | xargs) EL_POETRY_VERSION=$(cat ".poetry-version" | xargs) -EL_PYTHON_VERSION=$(cat ".python-version" | xargs) +EL_PYTHON_ODOO_VERSION=$(cat ".python-odoo-version" | xargs) +EL_PYTHON_ERPLIBRE_VERSION=$(cat "./conf/python-erplibre-version" | xargs) EL_ERPLIBRE_VERSION=$(cat ".erplibre-version" | xargs) # The default port where this Odoo instance will run under (provided you use the command -c in the terminal) # Set to true if you want to install it, false if you don't need it or have it already installed. @@ -26,4 +27,4 @@ EL_INSTALL_NGINX="False" EL_WEBSITE_NAME="localhost" EL_GITHUB_TOKEN="" EL_MANIFEST_PROD="./default.xml" -EL_MANIFEST_DEV="./manifest/default.dev.xml" +EL_MANIFEST_DEV="./manifest/git_manifest_erplibre.xml" diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..ff04bef --- /dev/null +++ b/install.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./script/todo/todo.py diff --git a/odoo_bin.sh b/odoo_bin.sh index 4d7e308..12aeb29 100755 --- a/odoo_bin.sh +++ b/odoo_bin.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash -source ./.venv/bin/activate +# This is required to change environment for the running Odoo +source ./.venv.$(< .erplibre-version)/bin/activate ODOO_PATH="$(pwd)/odoo$(< .odoo-version)" #export PATH=$ODOO_PATH:$PATH diff --git a/run.sh b/run.sh index 4c49124..f715249 100755 --- a/run.sh +++ b/run.sh @@ -2,6 +2,7 @@ Red='\033[0;31m' # Red Color_Off='\033[0m' # Text Reset +# Search by default local configuration CONFIG_PATH="./config.conf" ORIGIN_CONFIG_PATH=CONFIG_PATH if [ ! -f "${CONFIG_PATH}" ]; then diff --git a/script/database/image_db.py b/script/database/image_db.py index 72e4603..d205239 100755 --- a/script/database/image_db.py +++ b/script/database/image_db.py @@ -16,7 +16,7 @@ logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO")) _logger = logging.getLogger(__name__) -PYTHON_BIN = ".venv/bin/python3" +PYTHON_BIN = ".venv.erplibre/bin/python3" IMAGE_DB_BIN = f"{PYTHON_BIN} ./script/database/image_db.py" diff --git a/script/database/restore_mariadb_sql_example_1.sh b/script/database/restore_mariadb_sql_example_1.sh index 9670726..4ebf95a 100755 --- a/script/database/restore_mariadb_sql_example_1.sh +++ b/script/database/restore_mariadb_sql_example_1.sh @@ -26,4 +26,4 @@ echo "Import SQL file" mysql -u organization -porganization mariadb_sql_example_1 < ${SQL_PATH} echo "Fix SQL in database" -./.venv/bin/python ./script/database/fix_mariadb_sql_example_1.py +./.venv.erplibre/bin/python ./script/database/fix_mariadb_sql_example_1.py diff --git a/script/docker/docker_build.sh b/script/docker/docker_build.sh index 287fcf4..af1d116 100755 --- a/script/docker/docker_build.sh +++ b/script/docker/docker_build.sh @@ -6,7 +6,7 @@ Color_Off='\033[0m' # Text Reset ERPLIBRE_IMAGE_NAME=$(cat .erplibre-semver-version|xargs) ERPLIBRE_VERSION_MAIN=$(cat .erplibre-version|xargs) ODOO_VERSION=$(cat .odoo-version|xargs) -PYTHON_VERSION=$(cat .python-version|xargs) +PYTHON_VERSION=$(cat .python-odoo-version|xargs) POETRY_VERSION=$(cat .poetry-version|xargs) IS_DEBIAN_BOOKWORM=true diff --git a/script/docker/docker_repo_show_status.sh b/script/docker/docker_repo_show_status.sh index a080881..3837cac 100755 --- a/script/docker/docker_repo_show_status.sh +++ b/script/docker/docker_repo_show_status.sh @@ -9,7 +9,7 @@ BASENAME="${BASENAME,,}" docker exec -u root -ti ${BASENAME}-ERPLibre-1 /bin/bash -c "\ cd /ERPLibre; \ -./.venv/repo forall -pc 'git status -s'; \ +.venv.erplibre/bin/repo forall -pc 'git status -s'; \ echo ''; \ git status -s; \ " @@ -18,7 +18,7 @@ retVal=$? if [[ $retVal -ne 0 ]]; then docker exec -u root -ti ${BASENAME}_ERPLibre_1 /bin/bash -c "\ cd /ERPLibre; \ - ./.venv/repo forall -pc 'git status -s'; \ + .venv.erplibre/bin/repo forall -pc 'git status -s'; \ echo ''; \ git status -s; \ " diff --git a/script/generate_config.sh b/script/generate_config.sh index b6586fe..5a54cfb 100755 --- a/script/generate_config.sh +++ b/script/generate_config.sh @@ -4,7 +4,7 @@ EL_USER=${USER} EL_HOME=$PWD -EL_HOME_ODOO="${EL_HOME}/odoo" +EL_HOME_ODOO="${EL_HOME}/odoo${EL_ODOO_VERSION}/odoo" #EL_PORT="8069" #EL_LONGPOLLING_PORT="8072" #EL_SUPERADMIN="admin" @@ -26,11 +26,7 @@ printf "longpolling_port = ${EL_LONGPOLLING_PORT}\n" >> "${EL_CONFIG_FILE}" printf "addons_path = ${EL_HOME_ODOO}/addons,${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/addons," >> "${EL_CONFIG_FILE}" if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/CybroOdoo_CybroAddons," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/CybroOdoo_OpenHRMS," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/ERPLibre_erplibre_addons," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/MathBenTech_development," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/MathBenTech_odoo-business-spending-management-quebec-canada," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_account-analytic," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_account-budgeting," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_account-closing," >> "${EL_CONFIG_FILE}" @@ -44,6 +40,7 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_account-reconcile," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_apps-store," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_bank-payment," >> "${EL_CONFIG_FILE}" + printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_bank-payment-alternative," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_bank-statement-import," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_brand," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_business-requirement," >> "${EL_CONFIG_FILE}" @@ -58,10 +55,12 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_contract," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_credit-control," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_crm," >> "${EL_CONFIG_FILE}" + printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_crowdfunding," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_currency," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_data-protection," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_ddmrp," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_delivery-carrier," >> "${EL_CONFIG_FILE}" + printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_dms," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_donation," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_e-commerce," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_edi," >> "${EL_CONFIG_FILE}" @@ -75,6 +74,7 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_interface-github," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_knowledge," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_l10n-canada," >> "${EL_CONFIG_FILE}" + printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_mail," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_maintenance," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_management-system," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_manufacture," >> "${EL_CONFIG_FILE}" @@ -101,14 +101,11 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_server-backend," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_server-brand," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_server-env," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_server-tools," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_server-ux," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_shift-planning," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_social," >> "${EL_CONFIG_FILE}" + printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_stock-logistics-putaway," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_stock-logistics-warehouse," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_storage," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_survey," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_timesheet," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_vertical-association," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_vertical-hotel," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_vertical-isp," >> "${EL_CONFIG_FILE}" @@ -119,14 +116,10 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OCA_wms," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/OmniaGit_odooplm," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/camptocamp_odoo-cloud-platform," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/cetmix_cetmix-tower," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/dhongu_deltatech," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/it-projects-llc_saas-addons," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/muk-it_muk_web," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/novacode-nl_odoo-formio," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/odoomates_odooapps," >> "${EL_CONFIG_FILE}" printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/openeducat_openeducat_erp," >> "${EL_CONFIG_FILE}" - printf "${EL_HOME}/addons.odoo${EL_ODOO_VERSION}/tegin_medical-fhir," >> "${EL_CONFIG_FILE}" fi printf "\n" >> "${EL_CONFIG_FILE}" @@ -140,6 +133,6 @@ fi # Update and fix the config.conf # Fix only the configuration if installation is done -if [ -f "./.venv/bin/activate" ] && [ -f "./odoo/odoo-bin" ]; then +if [ -f "./.venv.$(< .erplibre-version)/bin/activate" ] && [ -f "./odoo$(< .odoo-version)/odoo/odoo-bin" ]; then make config_update fi diff --git a/script/git/git_merge_repo_manifest.py b/script/git/git_merge_repo_manifest.py index 7266181..3f4940e 100755 --- a/script/git/git_merge_repo_manifest.py +++ b/script/git/git_merge_repo_manifest.py @@ -4,6 +4,7 @@ import argparse import copy +import csv import logging import os import sys @@ -18,6 +19,14 @@ from script.git.git_tool import GitTool _logger = logging.getLogger(__name__) +DEFAULT_PATH_MANIFEST_CONF = os.path.join("conf", "git_manifest.csv") +DEFAULT_PATH_MANIFEST_ODOO_CONF = os.path.join("conf", "git_manifest_odoo.csv") +DEFAULT_PATH_MANIFEST_PRIVATE_CONF = os.path.join( + "private", "default_git_manifest.csv" +) +DEFAULT_PATH_INSTALLED_ODOO_VERSION = os.path.join(".repo", "installed_odoo_version.txt") + + def get_config(): """Parse command line arguments, extracting the config file name, returning the union of config file and command line arguments @@ -32,16 +41,18 @@ def get_config(): """, ) parser.add_argument( - "--input1", required=True, help="First manifest to merge into input2." + "--input", + help="First manifest to merge into input2. Second manifest, overwrite by input1.", + ) + parser.add_argument("--output", default=".repo/local_manifests/erplibre_manifest.xml", help="Output of new manifest") + parser.add_argument( + "--att_revision_only", + action="store_true", + help="Output of new manifest", ) parser.add_argument( - "--input2", required=True, help="Second manifest, overwrite by input1." + "--with_OCA", action="store_true", help="Add OCA manifest" ) - parser.add_argument( - "--output", required=True, help="Output of new manifest" - ) - # parser.add_argument('--clear', action="store_true", - # help="Create a new manifest and clear old configuration.") args = parser.parse_args() return args @@ -50,36 +61,122 @@ def main(): config = get_config() git_tool = GitTool() - ( - dct_remote_1, - dct_project_1, - default_remote_1, - ) = git_tool.get_manifest_xml_info(filename=config.input1, add_root=True) - ( - dct_remote_2, - dct_project_2, - default_remote_2, - ) = git_tool.get_manifest_xml_info(filename=config.input2, add_root=True) + lst_input = config.input + if not lst_input: + lst_input = [] + if config.with_OCA: + append_file_path_manifest( + lst_input, DEFAULT_PATH_MANIFEST_ODOO_CONF + ) + if os.path.exists(".odoo-version"): + with open(".odoo-version", "r") as f: + odoo_version = f.readline() + if odoo_version: + path_manifest_odoo_version = os.path.join( + "manifest", f"git_manifest_odoo{odoo_version}.xml" + ) + if os.path.exists(path_manifest_odoo_version): + lst_input.append(path_manifest_odoo_version) + else: + print( + f"ERROR: {path_manifest_odoo_version} does not exist" + ) + path_manifest_odoo_version = os.path.join( + "manifest", f"git_manifest_odoo{odoo_version}_dev.xml" + ) + if os.path.exists(path_manifest_odoo_version): + lst_input.append(path_manifest_odoo_version) - dct_remote_3 = copy.deepcopy(dct_remote_2) - dct_project_3 = copy.deepcopy(dct_project_2) + if os.path.exists(DEFAULT_PATH_INSTALLED_ODOO_VERSION): + with open(DEFAULT_PATH_INSTALLED_ODOO_VERSION, "r") as f: + lst_installed_odoo_version = [a.strip() for a in f.readlines()] + if lst_installed_odoo_version: + for installed_odoo_version in lst_installed_odoo_version: + path_manifest_odoo_version = os.path.join( + "manifest", f"git_manifest_{installed_odoo_version}.xml" + ) + if os.path.exists(path_manifest_odoo_version): + lst_input.append(path_manifest_odoo_version) + else: + print( + f"ERROR: {path_manifest_odoo_version} does not exist" + ) + path_manifest_odoo_version = os.path.join( + "manifest", f"git_manifest_{installed_odoo_version}_dev.xml" + ) + if os.path.exists(path_manifest_odoo_version): + lst_input.append(path_manifest_odoo_version) - for key, value in dct_project_1.items(): - revision = value.get("@revision") - if revision: - dct_project_3[key]["@revision"] = revision else: - dct_project_3[key]["@upstream"] = "12.0" - dct_project_3[key]["@dest-branch"] = "12.0" + append_file_path_manifest(lst_input, DEFAULT_PATH_MANIFEST_CONF) + append_file_path_manifest( + lst_input, DEFAULT_PATH_MANIFEST_PRIVATE_CONF + ) + + dct_remote_total = {} + dct_project_total = {} + default_remote_total = None + + # Be sure all input is unique + lst_input = list(set(lst_input)) + + for index, input_path in enumerate(lst_input): + ( + dct_remote, + dct_project, + default_remote, + ) = git_tool.get_manifest_xml_info(filename=input_path, add_root=True) + + # Support multiple version odoo + dct_project_copy = dct_project + dct_project = {} + for key, value in dct_project_copy.items(): + new_key = f"{key}+{value.get('@path')}" + dct_project[new_key] = value + + if len(lst_input) == 1: + # Only 1 input, same output + dct_remote_total = dct_remote + dct_project_total = dct_project + break + elif not index: + # Preparation to accumulate data + dct_remote_total = copy.deepcopy(dct_remote) + dct_project_total = copy.deepcopy(dct_project) + continue + for key, value in dct_project.items(): + if key in dct_project_total.keys(): + if config.att_revision_only: + revision = value.get("@revision") + if revision: + dct_project_total[key]["@revision"] = revision + else: + dct_project_total[key].update(value) + else: + dct_project_total[key] = copy.deepcopy(value) + + for key, value in dct_remote.items(): + if key in dct_remote_total.keys(): + dct_remote_total[key].update(value) + else: + dct_remote_total[key] = copy.deepcopy(value) - # Update origin to new repo git_tool.generate_repo_manifest( - dct_remote=dct_remote_3, - dct_project=dct_project_3, + dct_remote=dct_remote_total, + dct_project=dct_project_total, output=config.output, - default_remote=default_remote_2, + default_remote=default_remote_total, ) +def append_file_path_manifest(lst_input, path_manifest): + if os.path.exists(path_manifest): + with open(path_manifest, "r") as f: + csv_file = csv.DictReader(f) + for row in csv_file: + filepath = row.get("filepath") + lst_input.append(filepath) + + if __name__ == "__main__": main() diff --git a/script/git/git_tool.py b/script/git/git_tool.py index 6c69f92..0fdeab8 100644 --- a/script/git/git_tool.py +++ b/script/git/git_tool.py @@ -3,6 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import os +import pathlib import webbrowser from collections import OrderedDict from typing import List @@ -20,8 +21,6 @@ CST_EL_GITHUB_TOKEN = "EL_GITHUB_TOKEN" DEFAULT_PROJECT_NAME = "ERPLibre" DEFAULT_WEBSITE = "erplibre.ca" DEFAULT_REMOTE_URL = "https://github.com/ERPLibre/ERPLibre.git" -with open(".odoo-version", "r") as f: - DEFAULT_BRANCH = f.readline() class Struct(object): @@ -44,7 +43,17 @@ class GitTool: @property def default_branch(self): - return DEFAULT_BRANCH + return self.odoo_version + + @property + def odoo_version(self): + with open(".odoo-version", "r") as f: + default_branch = f.readline() + return default_branch + + @property + def odoo_version_long(self): + return f"odoo{self.odoo_version}" @staticmethod def get_url(url: str) -> object: @@ -270,7 +279,12 @@ class GitTool: xml_as_string = xml.read() xml_dict = xmltodict.parse(xml_as_string) dct_manifest = xml_dict.get("manifest") - default_remote = dct_manifest.get("default").get("@remote") + if not dct_manifest: + return [] + if dct_manifest.get("default"): + default_remote = dct_manifest.get("default").get("@remote") + else: + default_remote = None lst_remote = dct_manifest.get("remote") if type(lst_remote) is dict: lst_remote = [lst_remote] @@ -306,7 +320,7 @@ class GitTool: "path": path, "relative_path": f"{repo_path}/{path}", "name": name, - "group": group, + "group": groups, } lst_repo.append(data) @@ -349,16 +363,28 @@ class GitTool: """ if filename is None: manifest_file = self.get_manifest_file(repo_path=repo_path) - filename = f"{repo_path}/{manifest_file}" + filename = os.path.normpath(os.path.join(repo_path, manifest_file)) with open(filename) as xml: xml_as_string = xml.read() xml_dict = xmltodict.parse(xml_as_string) dct_manifest = xml_dict.get("manifest") + if not dct_manifest: + return {}, {}, None default_remote = dct_manifest.get("default") lst_remote = dct_manifest.get("remote") + if type(lst_remote) is dict: + lst_remote = [lst_remote] lst_project = dct_manifest.get("project") - dct_remote = {a.get("@name"): a for a in lst_remote} - dct_project = {a.get("@name"): a for a in lst_project} + if type(lst_project) is dict: + lst_project = [lst_project] + if lst_remote: + dct_remote = {a.get("@name"): a for a in lst_remote} + else: + dct_remote = {} + if lst_project: + dct_project = {a.get("@name"): a for a in lst_project} + else: + dct_project = {} return dct_remote, dct_project, default_remote @staticmethod @@ -395,6 +421,8 @@ class GitTool: def generate_generate_config(self, repo_path="./", filter_group=None): filename_locally = f"{repo_path}script/generate_config.sh" + if not filter_group: + filter_group = self.odoo_version_long lst_repo = self.get_repo_info( repo_path=repo_path, filter_group=filter_group ) @@ -403,6 +431,7 @@ class GitTool: # Exception, ignore addons/OCA_web and root if repo.get("path") in ["addons/OCA_web", "odoo", "image_db"]: continue + # groups = repo.get("group") update_repo = repo.get("path") # Use variable instead of hardcoded path if update_repo.startswith("addons.odoo"): @@ -460,7 +489,7 @@ class GitTool: dct_project={}, default_remote=None, keep_original=False, - default_branch=DEFAULT_BRANCH, + default_branch=None, ): """ Generate repo manifest @@ -474,10 +503,6 @@ class GitTool: :param default_branch: default branch name :return: """ - if not output: - raise Exception( - "Cannot generate manifest with missing output filename." - ) lst_remote = [] lst_remote_name = [] lst_project = [] @@ -604,7 +629,7 @@ class GitTool: lst_default, key=lambda key: key.get("@remote") ) lst_order_project = sorted( - lst_project, key=lambda key: key.get("@name") + lst_project, key=lambda key: key.get("@name") + key.get("@path") ) dct_repo = OrderedDict( @@ -647,8 +672,14 @@ class GitTool: str_xml_text = str_xml_text.replace("\t", " ") # create file - with open(output, mode="w") as file: - file.writelines(str_xml_text + "\n") + output_dirname = os.path.dirname(output) + if not os.path.exists(output_dirname): + pathlib.Path(output_dirname).mkdir(parents=True, exist_ok=True) + if output: + with open(output, mode="w") as file: + file.writelines(str_xml_text + "\n") + else: + print(str_xml_text + "\n") def generate_git_modules( self, lst_repo: List[Struct], repo_path: str = "./" @@ -742,6 +773,11 @@ class GitTool: :param repo_path: path to search .repo :return: manifest file used for Repo """ + file = os.path.join( + repo_path, ".repo", "local_manifests", "erplibre_manifest.xml" + ) + if os.path.exists(file): + return file file = f"{repo_path}/.repo/manifest.xml" if not os.path.exists(file): return "" diff --git a/script/git/repo_diff_last_version.sh b/script/git/repo_diff_last_version.sh index 6a13911..f919f67 100755 --- a/script/git/repo_diff_last_version.sh +++ b/script/git/repo_diff_last_version.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash LAST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) -./.venv/repo forall -pc "git diff ERPLibre/${LAST_TAG}..HEAD" +.venv.erplibre/bin/repo forall -pc "git diff ERPLibre/${LAST_TAG}..HEAD" # For actual repo git diff ${LAST_TAG}..HEAD diff --git a/script/git/repo_diff_stat_last_version.sh b/script/git/repo_diff_stat_last_version.sh index 40ebae1..3dbd749 100755 --- a/script/git/repo_diff_stat_last_version.sh +++ b/script/git/repo_diff_stat_last_version.sh @@ -4,7 +4,7 @@ Color_Off='\033[0m' # Text Reset BOLD='\033[1m' # Black LAST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) -./.venv/repo forall -pc "git diff --stat ERPLibre/${LAST_TAG}..HEAD" +.venv.erplibre/bin/repo forall -pc "git diff --stat ERPLibre/${LAST_TAG}..HEAD" echo "" echo -e "${BOLD}project /${Color_Off}" diff --git a/script/ide/pycharm_configuration.py b/script/ide/pycharm_configuration.py index 75a3c60..8d24fcc 100755 --- a/script/ide/pycharm_configuration.py +++ b/script/ide/pycharm_configuration.py @@ -376,7 +376,7 @@ def add_configuration(dct_xml, file_name, config): {"@name": "PARENT_ENVS", "@value": "true"}, { "@name": "SDK_HOME", - "@value": "$PROJECT_DIR$/.venv/bin/python", + "@value": "$PROJECT_DIR$/.venv.erplibre/bin/python", }, { "@name": "WORKING_DIRECTORY", diff --git a/script/install/install_daemon.sh b/script/install/install_daemon.sh index e3fae19..409d368 100755 --- a/script/install/install_daemon.sh +++ b/script/install/install_daemon.sh @@ -49,11 +49,12 @@ sudo systemctl daemon-reload sudo systemctl enable ${EL_CONFIG}.service sudo su ${EL_USER} -c "sudo rm -f /tmp/${EL_USER}run.sh" +# TODO this is outdated cat < /tmp/${EL_USER}run.sh #!/usr/bin/env bash cd ${EL_HOME_ERPLIBRE} -source ./.venv/bin/activate -python3 ${EL_HOME_ERPLIBRE}/odoo/odoo-bin -c ${EL_HOME_ERPLIBRE}/config.conf --limit-time-real 99999 --limit-time-cpu 99999 $@ +source ./.venv.erplibre/bin/activate +python3 ${EL_HOME_ERPLIBRE}/odoo18.0/odoo/odoo-bin -c ${EL_HOME_ERPLIBRE}/config.conf --limit-time-real 99999 --limit-time-cpu 99999 $@ EOF echo -e "* Security Run File" diff --git a/script/install/install_erplibre.sh b/script/install/install_erplibre.sh new file mode 100755 index 0000000..9173baf --- /dev/null +++ b/script/install/install_erplibre.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# TODO deprecated, this is moved into install_locally.sh to be sure venv is installed and force take specified supported version +python3 -m venv .venv.erplibre +source .venv.erplibre/bin/activate +pip3 install -r requirement/erplibre_require-ments.txt diff --git a/script/install/install_git_repo.sh b/script/install/install_git_repo.sh new file mode 100755 index 0000000..54c7214 --- /dev/null +++ b/script/install/install_git_repo.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +VENV_ERPLIBRE_PATH=$(cat "conf/python-erplibre-venv" | xargs) + +VENV_REPO_PATH=${VENV_ERPLIBRE_PATH}/bin/repo +# Install git-repo if missing +if [[ ! -f ${VENV_REPO_PATH} ]]; then + echo "\n---- Install git-repo from Google APIS ----" + curl https://storage.googleapis.com/git-repo-downloads/repo > ${VENV_REPO_PATH} + chmod +x ${VENV_REPO_PATH} + sed -i 1d ${VENV_REPO_PATH} + PYTHON_HASHBANG="#!./${VENV_ERPLIBRE_PATH}/bin/python" + sed -i "1 i ${PYTHON_HASHBANG}" ${VENV_REPO_PATH} +fi diff --git a/script/install/install_locally.sh b/script/install/install_locally.sh index cb90b31..733bb00 100755 --- a/script/install/install_locally.sh +++ b/script/install/install_locally.sh @@ -3,7 +3,7 @@ . ./env_var.sh EL_USER=${USER} EL_HOME=$PWD -EL_HOME_ODOO="${EL_HOME}/odoo" +EL_HOME_ODOO="${EL_HOME}/odoo${EL_ODOO_VERSION}/odoo" #EL_INSTALL_WKHTMLTOPDF="True" #EL_PORT="8069" #EL_LONGPOLLING_PORT="8072" @@ -12,132 +12,68 @@ EL_HOME_ODOO="${EL_HOME}/odoo" #EL_CONFIG="${EL_USER}" #EL_MINIMAL_ADDONS="False" #EL_INSTALL_NGINX="True" +FILE_INSTALLATION_VERSION=".repo/installed_odoo_version.txt" Red='\033[0;31m' # Red Color_Off='\033[0m' # Text Reset ./script/generate_config.sh -#echo -e "\n---- Install Odoo with addons module ----" -#git submodule update --init - # Generate empty addons if missing path_addons_addons="./addons.odoo${EL_ODOO_VERSION}/addons" if [[ ! -d "${path_addons_addons}" ]]; then mkdir -p "${path_addons_addons}" fi -PYENV_PATH=~/.pyenv # example, 3.7.8 will be 3.7 into PYTHON_VERSION_MAJOR -PYTHON_VERSION_MAJOR=$(echo "$EL_PYTHON_VERSION" | sed 's/\.[^\.]*$//') -PYENV_VERSION_PATH=${PYENV_PATH}/versions/${EL_PYTHON_VERSION} -PYTHON_EXEC=${PYENV_VERSION_PATH}/bin/python -VENV_PATH=./.venv -LOCAL_PYTHON_EXEC=${VENV_PATH}/bin/python -VENV_REPO_PATH=${VENV_PATH}/repo -VENV_MULTILINGUAL_MARKDOWN_PATH=${VENV_PATH}/multilang_md.py -#POETRY_PATH=~/.local/bin/poetry -POETRY_PATH=${VENV_PATH}/bin/poetry +PYTHON_VERSION_MAJOR=$(echo "$EL_PYTHON_ODOO_VERSION" | sed 's/\.[^\.]*$//') +VENV_ERPLIBRE_PATH=$(cat "conf/python-erplibre-venv" | xargs) +VENV_ODOO_PATH=".venv.${EL_ERPLIBRE_VERSION}" +POETRY_ODOO_PATH=${VENV_ERPLIBRE_PATH}/bin/poetry export WITH_POETRY_INSTALLATION=1 if [[ ! -n "${DOCKER_BUILD}" ]]; then - echo "Python path version home" - echo ${PYENV_VERSION_PATH} - echo "Python path version local" - echo ${LOCAL_PYTHON_EXEC} - - if [[ ! -d "${PYENV_PATH}" ]]; then - echo -e "\n---- Installing pyenv in ${PYENV_PATH} ----" - # export PYENV_GIT_TAG=v2.3.35 - # To change version - # rm ~/.pyenv to uninstall it - curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash - fi - - echo -e "\n---- Export pyenv in ${PYENV_PATH} ----" - export PATH="${PYENV_PATH}/bin:$PATH" - eval "$(pyenv init -)" - eval "$(pyenv virtualenv-init -)" - - if [[ ! -d "${PYENV_VERSION_PATH}" ]]; then - echo -e "\n---- Installing python ${PYTHON_VERSION} with pyenv in ${PYENV_VERSION_PATH} ----" - yes n|pyenv install ${PYTHON_VERSION} - if [[ $retVal -ne 0 ]]; then - echo -e "${Red}Error${Color_Off} when installing pyenv" - exit 1 - fi - fi - - pyenv local ${PYTHON_VERSION} - - if [[ ! -d ${VENV_PATH} ]]; then - echo -e "\n---- Create Virtual environment Python ----" - if [[ -e ${PYTHON_EXEC} ]]; then - ${PYTHON_EXEC} -m venv .venv - retVal=$? - if [[ $retVal -ne 0 ]]; then - echo "Virtual environment, error when creating .venv" - exit 1 - fi - else - echo "Missing pyenv, please refer installation guide." - exit 1 - fi - fi - source ./.venv/bin/activate + # Install ERPLibre venv + echo -e "Install ${VENV_ERPLIBRE_PATH} with ${EL_PYTHON_ERPLIBRE_VERSION}" + ./script/install/install_venv.sh "ERPLibre" "${VENV_ERPLIBRE_PATH}" "${EL_PYTHON_ERPLIBRE_VERSION}" + # Install Odoo venv + echo -e "Install ${VENV_ODOO_PATH} with ${EL_PYTHON_ODOO_VERSION}" + ./script/install/install_venv.sh "Odoo" "${VENV_ODOO_PATH}" "${EL_PYTHON_ODOO_VERSION}" else mkdir .venv fi -#if [[ ! -d "${POETRY_PATH}" ]]; then -# # Delete directory ~/.poetry and .venv to force update to new version -# echo -e "\n---- Installing poetry ${LOCAL_PYTHON_EXEC} for reliable python package ----" -# # TODO self update poetry with `poetry self update ${POETRY_VERSION}` -# curl -sSL https://install.python-poetry.org | POETRY_VERSION=${EL_POETRY_VERSION} ${LOCAL_PYTHON_EXEC} - -y -#fi +source ./${VENV_ERPLIBRE_PATH}/bin/activate +echo -e "Upgrade pip to ${VENV_ERPLIBRE_PATH}" +pip install --upgrade pip +pip install -r requirement/erplibre_require-ments.txt -# Install git-repo if missing -if [[ ! -f ${VENV_REPO_PATH} ]]; then - echo "\n---- Install git-repo from Google APIS ----" - curl https://storage.googleapis.com/git-repo-downloads/repo > ${VENV_REPO_PATH} - chmod +x ${VENV_REPO_PATH} - sed -i 1d ${VENV_REPO_PATH} - PYTHON_HASHBANG="#!./.venv/bin/python" - sed -i "1 i ${PYTHON_HASHBANG}" ${VENV_REPO_PATH} -fi +./script/install/install_git_repo.sh + +source ${VENV_ODOO_PATH}/bin/activate +echo -e "Upgrade pip to ${VENV_ODOO_PATH}" +pip install --upgrade pip -# Make .venv active -if [[ "${OSTYPE}" == "darwin"* ]]; then - echo -e "=======>source .venv/bin/activate here!!! <===============" - source .venv/bin/activate -fi echo -e "\n---- Installing poetry dependency ----" -${VENV_PATH}/bin/pip install --upgrade pip -# Force python instead of changing env -#/home/"${USER}"/.poetry/bin/poetry env use ${LOCAL_PYTHON_EXEC} -# source $HOME/.poetry/env -#${LOCAL_PYTHON_EXEC} ~/.poetry/bin/poetry env use ${VENV_PATH}/bin/python3 -#${LOCAL_PYTHON_EXEC} ~/.poetry/bin/poetry install -#${POETRY_PATH} install if [[ -z "${EL_POETRY_VERSION}" ]]; then echo -e "${Red}Error${Color_Off} missing poetry version, please check file .poetry-version" cat .poetry-version + ls -la exit 1 fi # Delete artifacts created by pip, cause error in next "poetry install" -if [[ ! -f "${POETRY_PATH}" ]]; then - ${VENV_PATH}/bin/pip install poetry==${EL_POETRY_VERSION} - ${VENV_PATH}/bin/poetry --version +if [[ ! -f "${POETRY_ODOO_PATH}" ]]; then + echo -e "Install Poetry ${POETRY_ODOO_PATH}" + pip install poetry==${EL_POETRY_VERSION} + poetry --version # Fix broken poetry by installing ignored dependence - # ${VENV_PATH}/bin/pip install vatnumber - # ${VENV_PATH}/bin/pip install suds-jurko - # ${VENV_PATH}/bin/poetry lock --no-update + # poetry lock --no-update # To fix keyring problem when installation is blocked, use export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring if [[ ${WITH_POETRY_INSTALLATION} -ne 0 ]]; then - ${VENV_PATH}/bin/poetry install --no-root -vvv + poetry install --no-root -vvv fi retVal=$? if [[ $retVal -ne 0 ]]; then @@ -149,6 +85,18 @@ fi # Delete artifacts created by pip, cause error in next "poetry install" rm -rf artifacts -# Link for dev +# Link for dev tools into Odoo echo -e "\n---- Add link dependency in site-packages of Python ----" -ln -fs "${EL_HOME_ODOO}/odoo" "${EL_HOME}/.venv/lib/python${PYTHON_VERSION_MAJOR}/site-packages/" +# TODO this link can break, the symbolic link is maybe not created +ln -fs "${EL_HOME_ODOO}/odoo" "${EL_HOME}/${VENV_ODOO_PATH}/lib/python${PYTHON_VERSION_MAJOR}/site-packages/" + +# Force to return to erplibre source +source ./${VENV_ERPLIBRE_PATH}/bin/activate + +# Add trace of installation +LINE_TO_ADD="odoo${EL_ODOO_VERSION}" +mkdir -p "$(dirname "$FILE_INSTALLATION_VERSION")" +touch "$FILE_INSTALLATION_VERSION" +if ! grep -qxF "$LINE_TO_ADD" "$FILE_INSTALLATION_VERSION"; then + echo "$LINE_TO_ADD" >> "$FILE_INSTALLATION_VERSION" +fi diff --git a/script/install/install_locally_dev.sh b/script/install/install_locally_dev.sh index def7ad4..e0e9e8d 100755 --- a/script/install/install_locally_dev.sh +++ b/script/install/install_locally_dev.sh @@ -32,7 +32,7 @@ npm install #cd script/OCA_maintainer-tools || exit ## virtualenv is not installed by default ##virtualenv env -#../../.venv/bin/python -m venv env +#../../.venv.erplibre/bin/python -m venv env #. env/bin/activate #pip install setuptools-rust ## Delete all tag before installing, or break installation, will generate a new one after diff --git a/script/install/install_venv.sh b/script/install/install_venv.sh new file mode 100755 index 0000000..3019feb --- /dev/null +++ b/script/install/install_venv.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Check if all 3 parameters are present +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "Error: One or more parameters are missing." + echo "Usage: $0 " + exit 1 +fi + +# Assign arguments to variables +CONTEXT="$1" +VENV_PATH="$2" +PYTHON_VERSION="$3" + +# Display variables (for verification) +echo "Context: $CONTEXT" +echo "Venv Path: $VENV_PATH" +echo "Python Version: $PYTHON_VERSION" + +PYENV_PATH=~/.pyenv +PYENV_VERSION_PATH=${PYENV_PATH}/versions/${PYTHON_VERSION} +PYTHON_EXEC=${PYENV_VERSION_PATH}/bin/python +echo "Python path version home" +echo ${PYENV_VERSION_PATH} +#echo "Python path version local" +#echo ${LOCAL_PYTHON_EXEC} + +if [[ ! -d "${PYENV_PATH}" ]]; then + echo -e "\n---- Installing pyenv in ${PYENV_PATH} ----" + # export PYENV_GIT_TAG=v2.3.35 + # To change version + # rm ~/.pyenv to uninstall it + curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash +fi + +echo -e "\n---- Export pyenv in ${PYENV_PATH} ----" +export PATH="${PYENV_PATH}/bin:$PATH" +eval "$(pyenv init -)" +eval "$(pyenv virtualenv-init -)" + +if [[ ! -d "${PYENV_VERSION_PATH}" ]]; then + echo -e "\n---- Installing python ${PYTHON_VERSION} with pyenv in ${PYENV_VERSION_PATH} ----" + # Update all python version list + cd "${PYENV_PATH}" && git pull && cd - + yes n|pyenv install ${PYTHON_VERSION} + if [[ $retVal -ne 0 ]]; then + echo -e "${Red}Error${Color_Off} when installing pyenv" + exit 1 + fi +fi + +# This will write .python-version +# pyenv local ${PYTHON_VERSION} + +if [[ ! -d ${VENV_PATH} ]]; then + echo -e "\n---- Create Virtual environment Python ----" + if [[ -e ${PYTHON_EXEC} ]]; then + ${PYTHON_EXEC} -m venv "${VENV_PATH}" + retVal=$? + if [[ $retVal -ne 0 ]]; then + echo "Virtual environment, error when creating ${VENV_PATH}" + exit 1 + fi + else + echo "Missing pyenv, please refer installation guide. Check variable '${PYTHON_EXEC}'." + exit 1 + fi +fi \ No newline at end of file diff --git a/script/maintenance/autopep8.sh b/script/maintenance/autopep8.sh index 3245c30..9f3d670 100755 --- a/script/maintenance/autopep8.sh +++ b/script/maintenance/autopep8.sh @@ -5,7 +5,7 @@ Color_Off='\033[0m' # Text Reset # This will format all python file # argument 1: directory or file to format NPROC=$(nproc) -source ./script/OCA_maintainer-tools/env/bin/activate +source ./.venv.erplibre/bin/activate oca-autopep8 -j ${NPROC} --max-line-length 79 -ari $@ retVal=$? if [[ $retVal -ne 0 ]]; then diff --git a/script/maintenance/black.sh b/script/maintenance/black.sh index 1ed2812..2205edd 100755 --- a/script/maintenance/black.sh +++ b/script/maintenance/black.sh @@ -4,7 +4,7 @@ Color_Off='\033[0m' # Text Reset # This will format all python file # argument 1: directory or file to format -source ./.venv/bin/activate +source ./.venv.erplibre/bin/activate black -l 79 --preview -t py37 "$@" retVal=$? if [[ $retVal -ne 0 ]]; then diff --git a/script/maintenance/format_python.sh b/script/maintenance/format_python.sh index f17ec1e..d685032 100755 --- a/script/maintenance/format_python.sh +++ b/script/maintenance/format_python.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source ./.venv/bin/activate +source ./.venv.erplibre/bin/activate isort --profile black -l 79 "$@" -#./.venv/bin/isort --profile black -l 79 "$@" +#./.venv.erplibre/bin/isort --profile black -l 79 "$@" ./script/maintenance/black.sh "$@" diff --git a/script/manifest/update_manifest_dev.sh b/script/manifest/update_manifest_dev.sh index 91623bc..3558c24 100755 --- a/script/manifest/update_manifest_dev.sh +++ b/script/manifest/update_manifest_dev.sh @@ -6,5 +6,5 @@ #EL_MANIFEST_DEV="./manifest/default.dev.xml" # Update git-repo -./.venv/repo init -u https://github.com/ERPLibre/ERPLibre -b $(git rev-parse --verify HEAD) -m ${EL_MANIFEST_DEV} -./.venv/repo sync -v +.venv.erplibre/bin/repo init -u https://github.com/ERPLibre/ERPLibre -b $(git rev-parse --verify HEAD) -m ${EL_MANIFEST_DEV} +.venv.erplibre/bin/repo sync -v diff --git a/script/manifest/update_manifest_local_dev.sh b/script/manifest/update_manifest_local_dev.sh index 418e29a..fdeccde 100755 --- a/script/manifest/update_manifest_local_dev.sh +++ b/script/manifest/update_manifest_local_dev.sh @@ -14,7 +14,10 @@ else MANIFEST_TARGET="$EL_MANIFEST_DEV" fi -./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} "$@" -./.venv/repo sync -v -m ${MANIFEST_TARGET} +# Generate local manifest +.venv.erplibre/bin/python ./script/git/git_merge_repo_manifest.py --output .repo/local_manifests/erplibre_manifest.xml --with_OCA + +.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} "$@" +.venv.erplibre/bin/repo sync -c -j $(nproc --all) -v -m ${MANIFEST_TARGET} kill ${DAEMON_PID} diff --git a/script/manifest/update_manifest_local_dev_code_generator.sh b/script/manifest/update_manifest_local_dev_code_generator.sh index 251067a..0aa689e 100755 --- a/script/manifest/update_manifest_local_dev_code_generator.sh +++ b/script/manifest/update_manifest_local_dev_code_generator.sh @@ -15,7 +15,7 @@ else MANIFEST_TARGET="$EL_MANIFEST_DEV" fi -./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} -g base,code_generator -./.venv/repo sync -v -m ${MANIFEST_TARGET} +.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} -g base,code_generator +.venv.erplibre/bin/repo sync -c -j $(nproc --all) -v -m ${MANIFEST_TARGET} kill ${DAEMON_PID} diff --git a/script/manifest/update_manifest_local_prod.sh b/script/manifest/update_manifest_local_prod.sh index b3df781..c5a962a 100755 --- a/script/manifest/update_manifest_local_prod.sh +++ b/script/manifest/update_manifest_local_prod.sh @@ -15,7 +15,7 @@ else MANIFEST_TARGET="$EL_MANIFEST_DEV" fi -./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} -./.venv/repo sync -v -m ${MANIFEST_TARGET} +.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} +.venv.erplibre/bin/repo sync -c -j $(nproc --all) -v -m ${MANIFEST_TARGET} kill ${DAEMON_PID} diff --git a/script/manifest/update_manifest_prod.sh b/script/manifest/update_manifest_prod.sh index 1e1eaaa..c2f8755 100755 --- a/script/manifest/update_manifest_prod.sh +++ b/script/manifest/update_manifest_prod.sh @@ -6,5 +6,5 @@ #EL_MANIFEST_DEV="./manifest/default.dev.xml" # Update git-repo -./.venv/repo init -u https://github.com/ERPLibre/ERPLibre -b $(git rev-parse --verify HEAD) -./.venv/repo sync -v +.venv.erplibre/bin/repo init -u https://github.com/ERPLibre/ERPLibre -b $(git rev-parse --verify HEAD) +.venv.erplibre/bin/repo sync -v -j $(nproc --all) diff --git a/script/poetry/poetry_add_build_dependency.sh b/script/poetry/poetry_add_build_dependency.sh index 6699e2b..6c1cfa2 100755 --- a/script/poetry/poetry_add_build_dependency.sh +++ b/script/poetry/poetry_add_build_dependency.sh @@ -2,7 +2,7 @@ Red='\033[0;31m' # Red Color_Off='\033[0m' # Text Reset -./.venv/bin/poetry add -vv $(grep -v ";" ./.venv/build_dependency.txt | grep -v "*" ) +./.venv.$(cat ".erplibre-version" | xargs)/bin/poetry add -vv $(grep -v ";" ./.venv.$(cat ".erplibre-version" | xargs)/build_dependency.txt | grep -v "*" ) # poetry add -vv $(grep -v ";" ./.venv/build_dependency.txt | grep -v "*" | sed 's/==/@^/' ) # poetry export -f ./.venv/build_dependency.txt --dev | poetry run -- pip install -r /dev/stdin retVal=$? diff --git a/script/selenium/install.md b/script/selenium/install.md index c44407f..ef6d25c 100644 --- a/script/selenium/install.md +++ b/script/selenium/install.md @@ -1,6 +1,6 @@ wget https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-linux64.tar.gz tar xvf geckodriver-v0.34.0-linux64.tar.gz -sudo mv ./.venv/geckodriver /usr/bin/geckdriver +sudo mv ./.venv.erplibre/geckodriver /usr/bin/geckdriver pip install selenium diff --git a/script/statistic/code_count.sh b/script/statistic/code_count.sh index 4eeb285..992f436 100755 --- a/script/statistic/code_count.sh +++ b/script/statistic/code_count.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash # all argument is directory/file separate by space -./.venv/bin/pygount --duplicates --folders-to-skip="[...],*/libs/*,*/lib/*,lib" --names-to-skip="[...],*.min.*" --suffix=py,xml,html,js,csv,css,scss --format=summary "$@" +./.venv.erplibre/bin/pygount --duplicates --folders-to-skip="[...],*/libs/*,*/lib/*,lib" --names-to-skip="[...],*.min.*" --suffix=py,xml,html,js,csv,css,scss --format=summary "$@" diff --git a/script/test/run_parallel_test.py b/script/test/run_parallel_test.py index bb17616..474a1c2 100755 --- a/script/test/run_parallel_test.py +++ b/script/test/run_parallel_test.py @@ -38,7 +38,7 @@ if not os.path.isfile(FILENAME_ODOO_VERSION): with open(".odoo-version", "r") as f: ODOO_VERSION = f.readline() -LOG_FILE = "./.venv/make_test.log" +LOG_FILE = "./.venv.erplibre/make_test.log" CONFIG_TESTCASE_JSON = f"./script/test/config_testcase.odoo{ODOO_VERSION}.json" diff --git a/script/todo/todo.json b/script/todo/todo.json index 282ab3f..7f74333 100644 --- a/script/todo/todo.json +++ b/script/todo/todo.json @@ -18,7 +18,7 @@ "function": [ { "prompt_description": "Ouvrir ERPLibre avec TODO \uD83E\uDD16", - "command": "./.venv/bin/python ./script/selenium/web_login.py" + "command": "./.venv.erplibre/bin/python ./script/selenium/web_login.py" } ], "update_from_makefile": [ diff --git a/script/version/change_python_version.sh b/script/version/change_python_version.sh index e33fff8..86cbb5e 100755 --- a/script/version/change_python_version.sh +++ b/script/version/change_python_version.sh @@ -6,7 +6,7 @@ input=".python-version" while IFS= read -r line do echo -e "Actual version $line" - sed -i -e "s/$line/$1/g" ./.python-version + sed -i -e "s/$line/$1/g" ./.python-odoo-version sed -i -e "s/$line/$1/g" ./docker/Dockerfile.base sed -i -e "s/$line/$1/g" ./script/install/install_OSX_dependency.sh sed -i -e "s/$line/$1/g" ./pyproject.toml diff --git a/script/version/update_env_version.py b/script/version/update_env_version.py index 5d5a4e9..132a901 100755 --- a/script/version/update_env_version.py +++ b/script/version/update_env_version.py @@ -2,7 +2,7 @@ # © 2021-2024 TechnoLibre (http://www.technolibre.ca) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) -# This script need only basic importation +# This script need only basic importation, it needs to be supported by python of your system import argparse import json import logging @@ -18,11 +18,11 @@ _logger = logging.getLogger(__name__) PROJECT_NAME = os.path.basename(os.getcwd()) VERSION_DATA_FILE = os.path.join("conf", "supported_version_erplibre.json") -VERSION_PYTHON_FILE = os.path.join(".python-version") +VERSION_PYTHON_FILE = os.path.join(".python-odoo-version") +INSTALLED_ODOO_VERSION_FILE = ".repo/installed_odoo_version.txt" VERSION_ERPLIBRE_FILE = os.path.join(".erplibre-version") VERSION_ODOO_FILE = os.path.join(".odoo-version") VERSION_POETRY_FILE = os.path.join(".poetry-version") -VENV_FILE = os.path.join(".venv") ADDONS_PATH = os.path.join("addons") ODOO_PATH = os.path.join(".", "odoo") VENV_TEMPLATE_FILE = ".venv.%s" @@ -110,7 +110,7 @@ def get_config(): parser.add_argument( "--force_install", action="store_true", - help="Will erase .venv and create symbolic link after installation.", + help="Will erase .venv.odooVersion and create symbolic link after installation.", ) parser.add_argument( "--force_repo", @@ -157,7 +157,6 @@ class Update: self.expected_pyproject_path = None self.expected_poetry_lock_name = None self.expected_poetry_lock_path = None - self.do_backup_venv = False def check_version_data(self): die( @@ -184,10 +183,13 @@ class Update: self.python_version = txt.read().strip() with open(VERSION_ODOO_FILE) as txt: self.odoo_version = txt.read().strip() + with open(VERSION_POETRY_FILE) as txt: + poetry_version = txt.read().strip() # Show actual version _logger.info(f"Python version: {self.python_version}") _logger.info(f"Odoo version: {self.odoo_version}") + _logger.info(f"Poetry version: {poetry_version}") erplibre_version_to_search = ERPLIBRE_TEMPLATE_VERSION % ( self.odoo_version, self.python_version, @@ -212,6 +214,13 @@ class Update: ) return False + if os.path.exists(INSTALLED_ODOO_VERSION_FILE): + with open(INSTALLED_ODOO_VERSION_FILE) as txt: + lst_version_installed = sorted(txt.read().splitlines()) + str_installed_version = "Installed version: " + ", ".join( + lst_version_installed + ) + _logger.info(str_installed_version) return True def validate_version(self): @@ -323,7 +332,9 @@ class Update: ADDONS_TEMPLATE_FILE % self.new_version_odoo ) self.expected_odoo_name = ODOO_TEMPLATE_FILE % self.new_version_odoo - self.expected_odoo_path = os.path.join(".", self.expected_odoo_name, "odoo", ".") + self.expected_odoo_path = os.path.join( + ".", self.expected_odoo_name, "odoo", "." + ) self.expected_pip_requirement_path = os.path.join( ".", "requirement", self.expected_pip_requirement_name ) @@ -339,16 +350,7 @@ class Update: def validate_environment(self): status = True - # Validate .venv - status &= self.update_link_file( - "Virtual environnement", - VENV_FILE, - self.expected_venv_name, - is_directory=True, - do_delete_source=self.config.install_dev - or self.config.force_install, - ) - venv_exist = os.path.exists(VENV_FILE) + venv_exist = os.path.exists(self.expected_venv_name) if not venv_exist and not self.config.install_dev: _logger.info("Relaunch this script with --install_dev argument.") # Validate Odoo repo @@ -405,24 +407,21 @@ class Update: def update_environment(self): status = True - do_action = bool(any([self.config.install_dev, self.config.install])) - if self.do_backup_venv and do_action: - venv_backup_name = ( - f".venv_backup_{time.strftime('%Yy%mm%dd-%Hh%Mm%Ss')}" - ) - shutil.move(VENV_FILE, venv_backup_name) - self.execute_log.append(f"Move .venv to backup {venv_backup_name}") if self.config.force_repo: # TODO add script to check difference before erase all os.system("./script/git/clean_repo_manifest.sh") self.execute_log.append( f"Clear all repo from manifest, everything is deleted" ) - if self.config.force_install: - os.system(f"rm -rf ./{VENV_FILE}") - self.execute_log.append(f"Remove ./{VENV_FILE}") # Always overwrite version + _logger.info( + f"Update local file, " + f"python version '{self.new_version_python}', " + f"erplibre version '{self.new_version_erplibre}', " + f"odoo version '{self.new_version_odoo}', " + f"poetry version '{self.new_version_poetry}'" + ) with open(VERSION_PYTHON_FILE, "w") as txt: txt.write(self.new_version_python) with open(VERSION_ERPLIBRE_FILE, "w") as txt: @@ -433,28 +432,21 @@ class Update: txt.write(self.new_version_poetry) if self.config.is_in_installation or self.config.is_in_switch: - addons_path_with_version = ( - ADDONS_TEMPLATE_FILE % self.new_version_odoo - ) - # To support multiple addons directory, change name before run git repo - for addons_path in os.listdir("."): - if ( - addons_path.startswith("addons") - and addons_path != addons_path_with_version - ): - os.rename(addons_path, addons_path + "TEMP") + # addons_path_with_version = ( + # ADDONS_TEMPLATE_FILE % self.new_version_odoo + # ) + # # To support multiple addons directory, change name before run git repo + # for addons_path in os.listdir("."): + # if ( + # addons_path.startswith("addons") + # and addons_path != addons_path_with_version + # ): + # os.rename(addons_path, addons_path + "TEMP") # TODO need to be force if installation path is all good, return True if self.config.install_dev: _logger.info("Installation.") status = self.install_erplibre() - - # Re-update if launch installation - if self.config.install_dev: - self._update_directory_to_link( - VENV_FILE, self.expected_venv_name - ) - # self._update_directory_to_link(ADDONS_PATH, self.expected_addons_name) elif self.config.is_in_switch: _logger.info("Switch") self.execute_log.append(f"System update") @@ -463,13 +455,13 @@ class Update: ) # To support multiple addons directory, remove TEMP - for addons_path in os.listdir("."): - if ( - addons_path.startswith("addons") - and addons_path != addons_path_with_version - and addons_path.endswith("TEMP") - ): - os.rename(addons_path, addons_path[:-4]) + # for addons_path in os.listdir("."): + # if ( + # addons_path.startswith("addons") + # and addons_path != addons_path_with_version + # and addons_path.endswith("TEMP") + # ): + # os.rename(addons_path, addons_path[:-4]) for addons_path in os.listdir("."): if addons_path.startswith("addons"): # In same time, force to create addons if not existing @@ -478,29 +470,19 @@ class Update: os.makedirs(addons_dir_path) # Force create addons link - if os.path.isdir(ADDONS_PATH): - if os.path.islink(ADDONS_PATH): - os.remove(ADDONS_PATH) - else: - os.rename( - ADDONS_PATH, - ADDONS_PATH - + "_" - + time.strftime("%Yy%mm%dd-%Hh%Mm%Ss"), - ) - os.symlink(addons_path_with_version, ADDONS_PATH) + # if os.path.isdir(ADDONS_PATH): + # if os.path.islink(ADDONS_PATH): + # os.remove(ADDONS_PATH) + # else: + # os.rename( + # ADDONS_PATH, + # ADDONS_PATH + # + "_" + # + time.strftime("%Yy%mm%dd-%Hh%Mm%Ss"), + # ) + # os.symlink(addons_path_with_version, ADDONS_PATH) return status - def _update_directory_to_link(self, dir_to_check, link_name): - actuel_venv_is_symlink = os.path.islink(dir_to_check) - if not actuel_venv_is_symlink: - # Move it and create a symlink - shutil.move(dir_to_check, link_name) - os.symlink(link_name, dir_to_check) - msg = f"Create symbolic link {link_name} to {dir_to_check}" - _logger.info(msg) - self.execute_log.append(msg) - def print_log(self): if not self.execute_log: _logger.info("Nothing to do") @@ -514,7 +496,7 @@ class Update: if not pycharm_is_installed or not self.execute_log: return os.system( - "./.venv/bin/python ./script/ide/pycharm_configuration.py --init" + "./.venv.erplibre/bin/python ./script/ide/pycharm_configuration.py --init" ) def install_erplibre(self): @@ -554,7 +536,7 @@ class Update: source_file_is_symlink = os.path.islink(source_file) target_file_exist = os.path.exists(target_file) if not target_file_exist: - _logger.warning(f"'{target_file}' not exist.") + _logger.error(f"'{target_file}' not exist.") do_symlink = False # Case 4 if source_file_is_symlink and not source_file_exist: @@ -581,8 +563,8 @@ class Update: ) os.system(f"ls -lha {source_file}") sys.exit(1) - else: - do_switch_origin_sim = True + # else: + # do_switch_origin_sim = True else: source_file_is_file = os.path.isfile(source_file) if not source_file_is_file: @@ -592,18 +574,18 @@ class Update: ) os.system(f"ls -lha {source_file}") sys.exit(1) - else: - do_switch_origin_sim = True - if do_switch_origin_sim: - # Check if not erase an existing - if target_file_exist: - # Create a backup - new_target_file = f"{target_file}.backup_{time.strftime('%Yy%mm%dd-%Hh%Mm%Ss')}" - else: - new_target_file = target_file + # else: + # do_switch_origin_sim = True + # if do_switch_origin_sim: + # # Check if not erase an existing + # if target_file_exist: + # # Create a backup + # new_target_file = f"{target_file}.backup_{time.strftime('%Yy%mm%dd-%Hh%Mm%Ss')}" + # else: + # new_target_file = target_file # Move it and create a symlink - shutil.move(source_file, new_target_file) - do_symlink = True + # shutil.move(source_file, new_target_file) + # do_symlink = True else: # Case 3 # Is symlink @@ -742,18 +724,20 @@ def main(): update.pycharm_update() # Update OCB configuration - os.system("./.venv/bin/python ./script/git/git_repo_update_group.py") + os.system( + "./.venv.erplibre/bin/python ./script/git/git_repo_update_group.py" + ) os.system("./script/generate_config.sh") # TODO ignore this if installation fail - # TODO this cause an error at first execution, need to source ./.venv/bin/activate and rerun - # subprocess.run(['source', './.venv/bin/activate'], shell=True) + # TODO this cause an error at first execution, need to source ./.venv.erplibre/bin/activate and rerun + # subprocess.run(['source', './.venv.erplibre/bin/activate'], shell=True) # subprocess.run(['make', 'config_gen_all']) # status = os.system(f"make config_gen_all") # # if not status: # print("Please run:") - # print("source ./.venv/bin/activate") + # print("source ./.venv.erplibre/bin/activate") # print("make config_gen_all")