Merge branch 'dev_1.2.2'
- Update to python 3.7.12 - Security update - New repo like themes - Improve test for code generator
This commit is contained in:
commit
fcc94e1822
67 changed files with 7272 additions and 1024 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -10,7 +10,9 @@ config.conf
|
|||
*.pyc
|
||||
|
||||
.repo
|
||||
addons
|
||||
!addons/
|
||||
addons/*
|
||||
!script/addons
|
||||
doc/itpp*
|
||||
doc/odoo*
|
||||
script/OCA*
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.7.7
|
||||
3.7.12
|
||||
|
|
|
|||
302
Makefile
302
Makefile
|
|
@ -1,4 +1,5 @@
|
|||
SHELL := /bin/bash
|
||||
LOG_FILE := ./.venv/make_test.log
|
||||
#############
|
||||
# General #
|
||||
#############
|
||||
|
|
@ -112,6 +113,10 @@ db_drop_db_code_generator:
|
|||
db_drop_db_template:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database template
|
||||
|
||||
.PHONY: db_drop_all
|
||||
db_drop_all:
|
||||
./script/database/db_drop_all.py
|
||||
|
||||
.PHONY: db_clean_cache
|
||||
db_clean_cache:
|
||||
./script/db_restore.py --clean_cache
|
||||
|
|
@ -121,7 +126,8 @@ db_restore_erplibre_base_db_test:
|
|||
./script/db_restore.py --database test
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_test_module_test
|
||||
db_restore_erplibre_base_db_test_module_test: db_restore_erplibre_base_db_test
|
||||
db_restore_erplibre_base_db_test_module_test:
|
||||
./script/make.sh db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons.sh test test
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_test_image_test
|
||||
|
|
@ -157,7 +163,8 @@ db_restore_erplibre_base_db_template:
|
|||
./script/db_restore.py --database template
|
||||
|
||||
.PHONY: db_create_db_test
|
||||
db_create_db_test: db_drop_db_test
|
||||
db_create_db_test:
|
||||
./script/make.sh db_drop_db_test
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --create --database test
|
||||
|
||||
########################
|
||||
|
|
@ -166,7 +173,7 @@ db_create_db_test: db_drop_db_test
|
|||
.PHONY: image_db_create_erplibre_base
|
||||
image_db_create_erplibre_base:
|
||||
./script/make.sh db_create_db_test
|
||||
./script/addons/install_addons.sh test web_responsive,disable_odoo_online,remove_odoo_enterprise,auth_user_case_insensitive,muk_web_theme,muk_utils,muk_branding,muk_mail_branding,muk_web_branding,muk_web_theme_mail,muk_web_utils,fetchmail_notify_error_to_sender,mail_debrand,partner_quebec_tz,erplibre_info
|
||||
./script/addons/install_addons.sh test web_responsive,disable_odoo_online,remove_odoo_enterprise,auth_user_case_insensitive,muk_web_theme,muk_utils,muk_branding,muk_mail_branding,muk_web_branding,muk_web_theme_mail,muk_web_utils,fetchmail_notify_error_to_sender,mail_debrand,partner_quebec_tz,erplibre_info,web_timeline,web_diagram_position
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --backup --database test --restore_image erplibre_base
|
||||
|
||||
.PHONY: image_db_create_erplibre_website
|
||||
|
|
@ -216,15 +223,18 @@ image_diff_base_website:
|
|||
# Addons installation #
|
||||
#########################
|
||||
.PHONY: addons_install_code_generator_basic
|
||||
addons_install_code_generator_basic: db_restore_erplibre_base_db_code_generator
|
||||
addons_install_code_generator_basic:
|
||||
./script/make.sh db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator
|
||||
|
||||
.PHONY: addons_install_code_generator_featured
|
||||
addons_install_code_generator_featured: db_restore_erplibre_base_db_code_generator
|
||||
addons_install_code_generator_featured:
|
||||
./script/make.sh db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_cron,code_generator_hook,code_generator_portal
|
||||
|
||||
.PHONY: addons_install_code_generator_full
|
||||
addons_install_code_generator_full: db_restore_erplibre_base_db_code_generator
|
||||
addons_install_code_generator_full:
|
||||
./script/make.sh db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_cron,code_generator_hook,code_generator_portal,code_generator_db_servers,code_generator_website_snippet,code_generator_geoengine,code_generator_theme_website,code_generator_website_leaflet
|
||||
|
||||
.PHONY: addons_install_code_generator_demo
|
||||
|
|
@ -236,27 +246,40 @@ addons_uninstall_code_generator_demo:
|
|||
./script/addons/uninstall_addons.sh code_generator code_generator_demo
|
||||
|
||||
.PHONY: addons_reinstall_code_generator_demo
|
||||
addons_reinstall_code_generator_demo: addons_uninstall_code_generator_demo addons_install_code_generator_demo
|
||||
addons_reinstall_code_generator_demo:
|
||||
./script/make.sh addons_uninstall_code_generator_demo
|
||||
./script/make.sh addons_install_code_generator_demo
|
||||
|
||||
.PHONY: addons_install_all_code_generator_demo
|
||||
addons_install_all_code_generator_demo: db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo,code_generator_demo_export_helpdesk,code_generator_demo_internal,code_generator_demo_portal,code_generator_demo_theme_website,code_generator_demo_website_leaflet,code_generator_demo_website_snippet
|
||||
addons_install_all_code_generator_demo:
|
||||
./script/make.sh db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo,code_generator_demo_export_helpdesk,code_generator_demo_internal,code_generator_demo_internal_inherit,code_generator_demo_portal,code_generator_demo_theme_website,code_generator_demo_website_leaflet,code_generator_demo_website_snippet,code_generator_auto_backup
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_export_helpdesk
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_internal
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_internal_inherit
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_portal
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_auto_backup
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_theme_website
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_leaflet
|
||||
# ./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
|
||||
.PHONY: addons_install_all_code_generator_template
|
||||
addons_install_all_code_generator_template:
|
||||
./script/addons/install_addons_dev.sh template demo_portal,auto_backup
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_portal code_generator_template_demo_sysadmin_cron
|
||||
./script/make.sh db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template demo_portal,auto_backup,demo_internal_inherit
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_portal,code_generator_template_demo_sysadmin_cron,code_generator_template_demo_internal_inherit
|
||||
#./script/addons/install_addons_dev.sh template demo_portal
|
||||
#./script/addons/install_addons_dev.sh template code_generator_template_demo_portal
|
||||
#./script/addons/install_addons_dev.sh template auto_backup
|
||||
#./script/addons/install_addons_dev.sh template code_generator_template_demo_sysadmin_cron
|
||||
#./script/addons/install_addons_dev.sh template demo_internal_inherit
|
||||
#./script/addons/install_addons_dev.sh template code_generator_template_demo_internal_inherit
|
||||
|
||||
.PHONY: addons_install_all_generated_demo
|
||||
addons_install_all_generated_demo:
|
||||
./script/addons/install_addons_dev.sh template demo_export_helpdesk,demo_internal,demo_portal,demo_website_leaflet,demo_website_snippet
|
||||
./script/make.sh db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template demo_helpdesk_data,demo_internal,demo_internal_inherit,demo_portal,demo_website_leaflet,demo_website_snippet,auto_backup
|
||||
# TODO support installation theme with cli
|
||||
#./script/addons/install_addons_dev.sh template theme_website_demo_code_generator
|
||||
|
||||
|
|
@ -264,51 +287,196 @@ addons_install_all_generated_demo:
|
|||
addons_install_all_code_generator:
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_auto_backup
|
||||
|
||||
##################
|
||||
# Code generator #
|
||||
##################
|
||||
.PHONY: addons_install_code_generator_template_code_generator
|
||||
addons_install_code_generator_template_code_generator:
|
||||
./script/db_restore.py --database template
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/TechnoLibre_odoo-code-generator/code_generator -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_code_generator --with_inherit
|
||||
./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator-template/code_generator_template_code_generator
|
||||
./script/addons/install_addons_dev.sh template code_generator
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_code_generator
|
||||
./script/git/remote_code_generation_git_compare.py --quiet --git_gui --clear --replace_directory --directory1 ./addons/TechnoLibre_odoo-code-generator-template/code_generator_code_generator --directory2 ./addons/TechnoLibre_odoo-code-generator/code_generator_code_generator
|
||||
|
||||
.PHONY: addons_install_code_generator_code_generator
|
||||
addons_install_code_generator_code_generator:
|
||||
./script/db_restore.py --database code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_code_generator
|
||||
./script/git/remote_code_generation_git_compare.py --quiet --git_gui --clear --replace_directory --directory1 ./addons/TechnoLibre_odoo-code-generator/code_generator --directory2 ./addons/TechnoLibre_odoo-code-generator-template/code_generator
|
||||
|
||||
.PHONY: meld_code_generator_template_code_generator
|
||||
meld_code_generator_template_code_generator:
|
||||
./script/make.sh clean
|
||||
meld ./addons/TechnoLibre_odoo-code-generator/code_generator_code_generator ./addons/TechnoLibre_odoo-code-generator-template/code_generator_code_generator
|
||||
|
||||
.PHONY: meld_code_generator_code_generator
|
||||
meld_code_generator_code_generator:
|
||||
./script/make.sh clean
|
||||
meld ./addons/TechnoLibre_odoo-code-generator-template/code_generator ./addons/TechnoLibre_odoo-code-generator/code_generator
|
||||
|
||||
########################
|
||||
# Extra migrator sql #
|
||||
########################
|
||||
.PHONY: addons_install_code_generator_mariadb_sql_example_1
|
||||
addons_install_code_generator_mariadb_sql_example_1:
|
||||
./script/database/restore_mariadb_sql_example_1.sh
|
||||
./script/db_restore.py --database code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_portal
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_migrator_demo_mariadb_sql_example_1
|
||||
|
||||
./script/db_restore.py --database template
|
||||
./script/addons/install_addons_dev.sh template code_generator_portal,demo_mariadb_sql_example_1
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/TechnoLibre_odoo-code-generator-template/demo_mariadb_sql_example_1 -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_demo_mariadb_sql_example_1
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_mariadb_sql_example_1
|
||||
|
||||
./script/db_restore.py --database code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_portal
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_mariadb_sql_example_1
|
||||
|
||||
##########
|
||||
# test #
|
||||
##########
|
||||
.PHONY: test
|
||||
test: test_format test_code_generator_generation test_code_generator_generation_extra test_code_generator_code_i18n test_code_generator_code_i18n_extra
|
||||
test:
|
||||
./script/make.sh clean
|
||||
-rm ${LOG_FILE}
|
||||
./script/make.sh test_base |& tee -a ${LOG_FILE}
|
||||
./script/test/check_result_test.sh ${LOG_FILE}
|
||||
|
||||
.PHONY: test_full
|
||||
test_full:
|
||||
./script/make.sh clean
|
||||
-rm ${LOG_FILE}
|
||||
./script/make.sh test_base |& tee -a ${LOG_FILE}
|
||||
./script/make.sh test_extra |& tee -a ${LOG_FILE}
|
||||
#./script/make.sh doc |& tee -a ${LOG_FILE}
|
||||
./script/test/check_result_test.sh ${LOG_FILE}
|
||||
|
||||
.PHONY: test_full_fast
|
||||
test_full_fast:
|
||||
./script/make.sh clean
|
||||
./script/test/run_parallel_test.py
|
||||
|
||||
.PHONY: test_base
|
||||
test_base:
|
||||
./script/make.sh test_format
|
||||
./script/make.sh test_code_generator_hello_world
|
||||
./script/make.sh test_installation_demo
|
||||
./script/make.sh test_code_generator_generation
|
||||
./script/make.sh test_code_generator_generation_template
|
||||
|
||||
.PHONY: test_extra
|
||||
test_extra:
|
||||
./script/make.sh test_code_generator_migrator_demo_mariadb_sql_example_1
|
||||
./script/make.sh test_code_generator_template_demo_mariadb_sql_example_1
|
||||
./script/make.sh test_code_generator_demo_mariadb_sql_example_1
|
||||
|
||||
.PHONY: test_format
|
||||
test_format:
|
||||
./script/maintenance/black.sh --check ./addons/TechnoLibre_odoo-code-generator/
|
||||
./script/maintenance/black.sh --check ./addons/TechnoLibre_odoo-code-generator-template/
|
||||
|
||||
.PHONY: test_code_generator_hello_world
|
||||
test_code_generator_hello_world:
|
||||
./test/code_generator/hello_world.sh
|
||||
|
||||
.PHONY: test_installation_demo
|
||||
test_installation_demo:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database test_demo
|
||||
./script/addons/install_addons.sh test_demo demo_helpdesk_data,demo_internal,demo_internal_inherit,demo_mariadb_sql_example_1,demo_portal,demo_website_data,demo_website_leaflet,demo_website_snippet
|
||||
# TODO cannot install from command line (CLI)
|
||||
#./script/addons/install_addons.sh test_demo theme_website_demo_code_generator ./addons/TechnoLibre_odoo-code-generator-template
|
||||
|
||||
.PHONY: test_code_generator_generation
|
||||
test_code_generator_generation:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database code_generator
|
||||
./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo,code_generator_demo_export_helpdesk,code_generator_demo_internal,code_generator_demo_portal,code_generator_demo_theme_website,code_generator_demo_website_leaflet,code_generator_demo_website_snippet ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_export_helpdesk ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_internal ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_portal ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_theme_website ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_website_leaflet ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# ./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_demo_website_snippet ./addons/TechnoLibre_odoo-code-generator-template
|
||||
|
||||
.PHONY: test_code_generator_generation_extra
|
||||
test_code_generator_generation_extra:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/OCA_server-tools/auto_backup
|
||||
./script/db_restore.py --database code_generator
|
||||
./script/code_generator/install_and_test_code_generator.sh code_generator code_generator_auto_backup ./addons/OCA_server-tools/auto_backup
|
||||
# Multiple
|
||||
./script/db_restore.py --database test_code_generator
|
||||
./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo,code_generator_demo_export_helpdesk,code_generator_demo_export_website,code_generator_demo_internal,code_generator_demo_portal,code_generator_demo_theme_website,code_generator_demo_website_leaflet,code_generator_demo_website_snippet ./addons/TechnoLibre_odoo-code-generator-template code_generator_demo,demo_helpdesk_data,demo_website_data,demo_internal,demo_portal,theme_website_demo_code_generator,demo_website_leaflet,demo_website_snippet
|
||||
# inherit
|
||||
# TODO should be in multiple list, need to support it
|
||||
./script/db_restore.py --database test_code_generator
|
||||
./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_internal_inherit ./addons/TechnoLibre_odoo-code-generator-template demo_internal_inherit
|
||||
# auto_backup
|
||||
./script/db_restore.py --database test_code_generator
|
||||
./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_auto_backup ./addons/OCA_server-tools/auto_backup auto_backup
|
||||
|
||||
.PHONY: test_code_generator_code_i18n
|
||||
test_code_generator_code_i18n:
|
||||
# Single
|
||||
#./script/db_restore.py --database test_code_generator
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo ./addons/TechnoLibre_odoo-code-generator-template code_generator_demo
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_export_helpdesk ./addons/TechnoLibre_odoo-code-generator-template demo_helpdesk_data
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_export_website ./addons/TechnoLibre_odoo-code-generator-template demo_website_data
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_internal ./addons/TechnoLibre_odoo-code-generator-template demo_internal
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_portal ./addons/TechnoLibre_odoo-code-generator-template demo_portal
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_theme_website ./addons/TechnoLibre_odoo-code-generator-template theme_website_demo_code_generator
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_website_leaflet ./addons/TechnoLibre_odoo-code-generator-template demo_website_leaflet
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_website_snippet ./addons/TechnoLibre_odoo-code-generator-template demo_website_snippet
|
||||
#./script/db_restore.py --database test_code_generator
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_internal_inherit ./addons/TechnoLibre_odoo-code-generator-template demo_internal_inherit
|
||||
#./script/db_restore.py --database test_code_generator
|
||||
#./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_auto_backup ./addons/OCA_server-tools/auto_backup auto_backup
|
||||
|
||||
.PHONY: test_code_generator_generation_template
|
||||
test_code_generator_generation_template:
|
||||
./script/make.sh test_code_generator_code_template_demo_portal
|
||||
./script/make.sh test_code_generator_code_template_demo_internal_inherit
|
||||
./script/make.sh test_code_generator_code_template_demo_sysadmin_cron
|
||||
|
||||
.PHONY: test_code_generator_code_template_demo_portal
|
||||
test_code_generator_code_template_demo_portal:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database template
|
||||
./script/addons/install_addons_dev.sh template demo_portal
|
||||
./script/code_generator/install_and_test_code_generator.sh template code_generator_template_demo_portal ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database test_template
|
||||
./script/addons/install_addons_dev.sh test_template demo_portal
|
||||
#./script/addons/install_addons_dev.sh test_template code_generator_template_demo_portal
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/TechnoLibre_odoo-code-generator-template/demo_portal -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_demo_portal --with_inherit
|
||||
./script/code_generator/install_and_test_code_generator.sh test_template code_generator_template_demo_portal ./addons/TechnoLibre_odoo-code-generator-template code_generator_demo_portal
|
||||
|
||||
.PHONY: test_code_generator_code_i18n_extra
|
||||
test_code_generator_code_i18n_extra:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/OCA_server-tools/auto_backup
|
||||
./script/db_restore.py --database template
|
||||
./script/addons/install_addons_dev.sh template auto_backup
|
||||
./script/code_generator/install_and_test_code_generator.sh template code_generator_template_demo_sysadmin_cron ./addons/TechnoLibre_odoo-code-generator-template
|
||||
# To support i18n in auto_backup
|
||||
.PHONY: test_code_generator_code_template_demo_internal_inherit
|
||||
test_code_generator_code_template_demo_internal_inherit:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database test_template
|
||||
./script/addons/install_addons_dev.sh test_template demo_internal_inherit
|
||||
#./script/addons/install_addons_dev.sh test_template code_generator_template_demo_internal_inherit
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/TechnoLibre_odoo-code-generator-template/demo_internal_inherit -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_demo_internal_inherit --with_inherit
|
||||
./script/code_generator/install_and_test_code_generator.sh test_template code_generator_template_demo_internal_inherit ./addons/TechnoLibre_odoo-code-generator-template code_generator_demo_internal_inherit
|
||||
|
||||
.PHONY: test_code_generator_code_template_demo_sysadmin_cron
|
||||
test_code_generator_code_template_demo_sysadmin_cron:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/OCA_server-tools/auto_backup
|
||||
./script/db_restore.py --database test_template
|
||||
./script/addons/install_addons_dev.sh test_template auto_backup
|
||||
#./script/addons/install_addons_dev.sh test_template code_generator_template_demo_sysadmin_cron
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/OCA_server-tools/auto_backup -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_demo_sysadmin_cron --with_inherit
|
||||
./script/code_generator/install_and_test_code_generator.sh test_template code_generator_template_demo_sysadmin_cron ./addons/TechnoLibre_odoo-code-generator-template code_generator_auto_backup
|
||||
|
||||
.PHONY: test_code_generator_migrator_demo_mariadb_sql_example_1
|
||||
test_code_generator_migrator_demo_mariadb_sql_example_1:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/database/restore_mariadb_sql_example_1.sh
|
||||
./script/db_restore.py --database test_code_generator
|
||||
./script/addons/install_addons_dev.sh test_code_generator code_generator_portal
|
||||
#./script/addons/install_addons_dev.sh test_code_generator code_generator_migrator_demo_mariadb_sql_example_1
|
||||
./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_migrator_demo_mariadb_sql_example_1 ./addons/TechnoLibre_odoo-code-generator-template demo_mariadb_sql_example_1
|
||||
|
||||
.PHONY: test_code_generator_template_demo_mariadb_sql_example_1
|
||||
test_code_generator_template_demo_mariadb_sql_example_1:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database test_template
|
||||
./script/addons/install_addons_dev.sh test_template code_generator_portal,demo_mariadb_sql_example_1
|
||||
./script/code_generator/search_class_model.py --quiet -d addons/TechnoLibre_odoo-code-generator-template/demo_mariadb_sql_example_1 -t addons/TechnoLibre_odoo-code-generator-template/code_generator_template_demo_mariadb_sql_example_1 --with_inherit
|
||||
#./script/addons/install_addons_dev.sh test_template code_generator_template_demo_mariadb_sql_example_1
|
||||
./script/code_generator/install_and_test_code_generator.sh test_template code_generator_template_demo_mariadb_sql_example_1 ./addons/TechnoLibre_odoo-code-generator-template code_generator_demo_mariadb_sql_example_1
|
||||
|
||||
.PHONY: test_code_generator_demo_mariadb_sql_example_1
|
||||
test_code_generator_demo_mariadb_sql_example_1:
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/TechnoLibre_odoo-code-generator-template
|
||||
./script/db_restore.py --database test_code_generator
|
||||
./script/addons/install_addons_dev.sh test_code_generator code_generator_portal
|
||||
#./script/addons/install_addons_dev.sh test_code_generator code_generator_demo_mariadb_sql_example_1
|
||||
./script/code_generator/install_and_test_code_generator.sh test_code_generator code_generator_demo_mariadb_sql_example_1 ./addons/TechnoLibre_odoo-code-generator-template demo_mariadb_sql_example_1
|
||||
|
||||
##############
|
||||
# tag #
|
||||
|
|
@ -328,22 +496,39 @@ open_terminal:
|
|||
# format #
|
||||
############
|
||||
.PHONY: format
|
||||
format: format_code_generator format_code_generator_template format_script
|
||||
format:
|
||||
./script/make.sh format_code_generator
|
||||
./script/make.sh format_code_generator_template
|
||||
./script/make.sh format_script
|
||||
|
||||
.PHONY: format_code_generator
|
||||
format_code_generator:
|
||||
.venv/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_code_generator_template
|
||||
format_code_generator_template:
|
||||
.venv/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
|
||||
./script/maintenance/black.sh ./script/
|
||||
|
||||
.PHONY: format_script_isort_only
|
||||
format_script_isort_only:
|
||||
.venv/bin/isort --profile black -l 79 ./script/ --gitignore
|
||||
|
||||
#########
|
||||
# log #
|
||||
#########
|
||||
.PHONY: log_show_test
|
||||
log_show_test:
|
||||
vim ${LOG_FILE}
|
||||
|
||||
###########
|
||||
# clean #
|
||||
###########
|
||||
|
|
@ -372,7 +557,9 @@ docker_stop:
|
|||
docker-compose down
|
||||
|
||||
.PHONY: docker_restart_daemon
|
||||
docker_restart_daemon: docker_stop docker_run_daemon
|
||||
docker_restart_daemon:
|
||||
./script/make.sh docker_stop
|
||||
./script/make.sh docker_run_daemon
|
||||
|
||||
.PHONY: docker_show_databases
|
||||
docker_show_databases:
|
||||
|
|
@ -500,21 +687,41 @@ config_gen_image_db:
|
|||
i18n_generate_demo_portal:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin i18n --database code_generator --module demo_portal --addons_path addons/TechnoLibre_odoo-code-generator
|
||||
|
||||
###########
|
||||
# Clean #
|
||||
###########
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
|
||||
|
||||
###################
|
||||
# Documentation #
|
||||
###################
|
||||
# documentation all
|
||||
.PHONY: doc
|
||||
doc: doc_dev doc_migration doc_test doc_user
|
||||
doc:
|
||||
./script/make.sh doc_dev
|
||||
./script/make.sh doc_migration
|
||||
./script/make.sh doc_test
|
||||
./script/make.sh doc_user
|
||||
./script/make.sh doc_markdown
|
||||
|
||||
# documentation clean all
|
||||
.PHONY: doc_clean
|
||||
doc_clean: doc_clean_dev doc_clean_migration doc_clean_test doc_clean_user
|
||||
doc_clean:
|
||||
./script/make.sh doc_clean_dev
|
||||
./script/make.sh doc_clean_migration
|
||||
./script/make.sh doc_clean_test
|
||||
./script/make.sh doc_clean_user
|
||||
|
||||
# documentation dev
|
||||
.PHONY: doc_dev
|
||||
doc_dev:
|
||||
source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-development/docs html || exit 1
|
||||
|
||||
.PHONY: open_doc_dev
|
||||
open_doc_dev:
|
||||
-$(BROWSER) doc/itpp-labs_odoo-development/docs/_build/html/index.html
|
||||
|
||||
.PHONY: doc_clean_dev
|
||||
|
|
@ -525,6 +732,9 @@ doc_clean_dev:
|
|||
.PHONY: doc_migration
|
||||
doc_migration:
|
||||
source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-port-docs/docs html || exit 1
|
||||
|
||||
.PHONY: open_doc_migration
|
||||
open_doc_migration:
|
||||
-$(BROWSER) doc/itpp-labs_odoo-port-docs/docs/_build/html/index.html
|
||||
|
||||
.PHONY: doc_clean_migration
|
||||
|
|
@ -535,6 +745,9 @@ doc_clean_migration:
|
|||
.PHONY: doc_test
|
||||
doc_test:
|
||||
source ./.venv/bin/activate && make -C doc/itpp-labs_odoo-test-docs/doc-src html || exit 1
|
||||
|
||||
.PHONY: open_doc_test
|
||||
open_doc_test:
|
||||
-$(BROWSER) doc/itpp-labs_odoo-test-docs/doc-src/_build/html/index.html
|
||||
|
||||
.PHONY: doc_clean_test
|
||||
|
|
@ -545,6 +758,9 @@ doc_clean_test:
|
|||
.PHONY: doc_user
|
||||
doc_user:
|
||||
source ./.venv/bin/activate && make -C doc/odoo_documentation-user html || exit 1
|
||||
|
||||
.PHONY: open_doc_user
|
||||
open_doc_user:
|
||||
-$(BROWSER) doc/odoo_documentation-user/_build/html/index.html
|
||||
|
||||
.PHONY: doc_clean_user
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
Select a guide to install your environment.
|
||||
|
||||
## Easy way to run locally
|
||||
Into Ubuntu, minimal dependency:
|
||||
```bash
|
||||
sudo apt install make git
|
||||
```
|
||||
Clone the project:
|
||||
```bash
|
||||
git clone https://github.com/ERPLibre/ERPLibre.git
|
||||
|
|
|
|||
|
|
@ -197,6 +197,24 @@ source ./.venv/bin/activate
|
|||
python odoo/odoo-bin scaffold MODULE_NAME addons/REPO_NAME/
|
||||
```
|
||||
|
||||
## Use Code generator
|
||||
|
||||
Read CODE_GENERATOR.md.
|
||||
|
||||
# Version
|
||||
|
||||
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.12` to change to version 3.7.12 .
|
||||
|
||||
Run the installation, `make install_dev`.
|
||||
|
||||
Update poetry, `./script/poetry_update.py`.
|
||||
|
||||
Create docker, `make docker_build`.
|
||||
|
||||
# Pull request
|
||||
|
||||
## Show all pull requests from organization
|
||||
|
|
|
|||
14
doc/FAQ.md
14
doc/FAQ.md
|
|
@ -1,5 +1,19 @@
|
|||
# FAQ
|
||||
|
||||
## Scripting
|
||||
|
||||
### Search all duplicate file recursively in given directory
|
||||
|
||||
```bash
|
||||
find . -type f -printf '%p/ %f\n' | sort -k2 | uniq -f1 --all-repeated=separate
|
||||
```
|
||||
|
||||
### Search all duplicate directory recursively in given directory
|
||||
|
||||
```bash
|
||||
find . -type d -printf '%p/ %f\n' | sort -k2 | uniq -f1 --all-repeated=separate
|
||||
```
|
||||
|
||||
## Networking
|
||||
|
||||
Show all open port
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ make format
|
|||
To generate database images in directory `./image_db`, run:
|
||||
|
||||
```bash
|
||||
make config_gen_all
|
||||
make image_db_create_all
|
||||
```
|
||||
|
||||
|
|
@ -73,6 +74,8 @@ grep --color=always --exclude-dir={.repo,.venv,.git} --exclude="*.svg" -nri v1.2
|
|||
|
||||
Replace if need it to new version.
|
||||
|
||||
Update file `./pyproject.toml` in [tool.poetry], line `version =`.
|
||||
|
||||
### Test production Ubuntu environment
|
||||
|
||||
Follow instructions in [PRODUCTION.md](./PRODUCTION.md).
|
||||
|
|
@ -185,6 +188,10 @@ List your docker version
|
|||
You need to push your docker image and update your tag, like 1.0.1:
|
||||
> docker push technolibre/erplibre:VERSION
|
||||
|
||||
## Do a release on github
|
||||
|
||||
Visit `https://github.com/ERPLibre/ERPLibre/releases/new` and create a release named `v#.#.#` and copy information from CHANGELOG.md.
|
||||
|
||||
# TIPS
|
||||
|
||||
## Compare repo differences with another ERPLibre project
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.7.7-slim-buster
|
||||
FROM python:3.7.12-slim-buster
|
||||
MAINTAINER TechnoLibre <docker@technolibre.ca>
|
||||
|
||||
SHELL ["/bin/bash", "-xo", "pipefail", "-c"]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.7.7
|
||||
3.7.12
|
||||
|
|
@ -15,3 +15,4 @@ pythonjsonlogger
|
|||
python-alipay-sdk
|
||||
pyrfc
|
||||
MySQLdb
|
||||
formiodata
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
<remote name="itpp-labs" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="kinjal-sorathiya" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="muk-it" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="novacode-nl" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="obayit" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="odoo" fetch="https://github.com/ERPLibre/"/>
|
||||
<remote name="odooaktiv" fetch="https://github.com/ERPLibre/"/>
|
||||
|
|
@ -59,6 +60,7 @@
|
|||
<project name="ddmrp.git" path="addons/OCA_ddmrp" remote="OCA" groups="addons"/>
|
||||
<project name="delivery-carrier.git" path="addons/OCA_delivery-carrier" remote="OCA" groups="addons"/>
|
||||
<project name="deltatech.git" path="addons/dhongu_deltatech" remote="dhongu" groups="addons"/>
|
||||
<project name="design-themes.git" path="addons/odoo_design-themes" remote="odoo" revision="12.0_dev" groups="addons,code_generator,image_db"/>
|
||||
<project name="development.git" path="addons/MathBenTech_development" remote="MathBenTech" groups="addons,base"/>
|
||||
<project name="documentation-user.git" path="doc/odoo_documentation-user" remote="odoo" groups="odoo"/>
|
||||
<project name="donation.git" path="addons/OCA_donation" remote="OCA" revision="12.0_module_donation_website" groups="addons"/>
|
||||
|
|
@ -85,7 +87,7 @@
|
|||
<project name="muk_base.git" path="addons/muk-it_muk_base" remote="muk-it" revision="12.0_dev" groups="addons,base"/>
|
||||
<project name="muk_dms.git" path="addons/muk-it_muk_dms" remote="muk-it" groups="addons"/>
|
||||
<project name="muk_docs.git" path="addons/muk-it_muk_docs" remote="muk-it" groups="addons"/>
|
||||
<project name="muk_misc.git" path="addons/muk-it_muk_misc" remote="muk-it" groups="addons,base"/>
|
||||
<project name="muk_misc.git" path="addons/muk-it_muk_misc" remote="muk-it" revision="12.0_dev" groups="addons,base"/>
|
||||
<project name="muk_quality.git" path="addons/muk-it_muk_quality" remote="muk-it" groups="addons"/>
|
||||
<project name="muk_web.git" path="addons/muk-it_muk_web" remote="muk-it" revision="12.0_dev" groups="addons,base"/>
|
||||
<project name="muk_website.git" path="addons/muk-it_muk_website" remote="muk-it" revision="12.0_remove_autoinstall" groups="addons,base"/>
|
||||
|
|
@ -98,9 +100,10 @@
|
|||
<project name="odoo-development.git" path="doc/itpp-labs_odoo-development" remote="itpp-labs" revision="12.0_dev" groups="odoo"/>
|
||||
<project name="odoo-entertainment-addons.git" path="addons/Numigi_odoo-entertainment-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-git-addons.git" path="addons/Numigi_odoo-git-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-formio.git" path="addons/novacode-nl_odoo-formio" remote="novacode-nl" groups="addons"/>
|
||||
<project name="odoo-hr-addons.git" path="addons/Numigi_odoo-hr-addons" remote="Numigi" groups="addons"/>
|
||||
<project name="odoo-module-migrator.git" path="script/OCA_odoo-module-migrator" remote="OCA" revision="master" groups="odoo"/>
|
||||
<project name="odoo-partner-addons.git" path="addons/Numigi_odoo-partner-addons" remote="Numigi" revision="12.0_dev" groups="addons,image_db"/>
|
||||
<project name="odoo-partner-addons.git" path="addons/Numigi_odoo-partner-addons" remote="Numigi" revision="12.0_dev" groups="addons,base,image_db"/>
|
||||
<project name="odoo-product-addons.git" path="addons/Numigi_odoo-product-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-port-docs.git" path="doc/itpp-labs_odoo-port-docs" remote="itpp-labs" revision="master" groups="odoo"/>
|
||||
<project name="odoo-product-configurator.git" path="addons/pledra_odoo-product-configurator" remote="pledra" groups="addons"/>
|
||||
|
|
@ -133,8 +136,8 @@
|
|||
<project name="saas-addons.git" path="addons/it-projects-llc_saas-addons" remote="it-projects-llc" groups="addons"/>
|
||||
<project name="sale-reporting.git" path="addons/OCA_sale-reporting" remote="OCA" groups="addons"/>
|
||||
<project name="sale-workflow.git" path="addons/OCA_sale-workflow" remote="OCA" revision="12.0_modules_sale_order_line" groups="addons"/>
|
||||
<project name="scrummer.git" path="addons/MathBenTech_scrummer" remote="MathBenTech" revision="12.0_dev" groups="addons"/>
|
||||
<project name="server-auth.git" path="addons/OCA_server-auth" remote="OCA" groups="addons"/>
|
||||
<project name="scrummer.git" path="addons/MathBenTech_scrummer" remote="MathBenTech" revision="12.0_dev" groups="addons,base"/>
|
||||
<project name="server-auth.git" path="addons/OCA_server-auth" remote="OCA" groups="addons,base,image_db"/>
|
||||
<project name="server-backend.git" path="addons/OCA_server-backend" remote="OCA" groups="addons"/>
|
||||
<project name="server-brand.git" path="addons/OCA_server-brand" remote="OCA" groups="addons,base"/>
|
||||
<project name="server-env.git" path="addons/OCA_server-env" remote="OCA" groups="addons"/>
|
||||
|
|
|
|||
2216
poetry.lock
generated
2216
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -2,58 +2,68 @@
|
|||
requires = [ "poetry>=1.0.0",]
|
||||
build-backend = "poetry.masonry.api"
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
py_version = 37
|
||||
|
||||
[tool.black]
|
||||
line-length = 79
|
||||
target-version = [ "py37",]
|
||||
|
||||
[tool.poetry]
|
||||
name = "ERPLibre"
|
||||
version = "1.1.0"
|
||||
version = "1.2.1"
|
||||
description = "Easy way to configure Odoo community"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = [ "Mathieu Benoit <mathben@technolibre.ca>",]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7.7"
|
||||
python = "^3.7.12"
|
||||
Asterisk = "^0.0.8"
|
||||
Babel = "2.3.4"
|
||||
Babel = "2.9.1"
|
||||
BeautifulSoup4 = "^4.10.0"
|
||||
GitPython = "3.1.12"
|
||||
Jinja2 = "2.11.3"
|
||||
Mako = "1.0.4"
|
||||
MarkupSafe = "0.23"
|
||||
Pillow = "8.3.2"
|
||||
Pillow = "9.0.0"
|
||||
PyJWT = "1.7.1"
|
||||
PyPDF2 = "1.26.0"
|
||||
PyYAML = "4.2b4"
|
||||
SOAPpy = "^0.12.22"
|
||||
Sphinx = ">=2.4.0"
|
||||
Voicent-Python = "^1.0"
|
||||
Werkzeug = "0.15.3"
|
||||
Werkzeug = "0.11.15"
|
||||
XlsxWriter = "0.9.3"
|
||||
agithub = "^2.2.2"
|
||||
altair = "^4.1.0"
|
||||
argcomplete = "^1.12.3"
|
||||
altair = "^4.2.0"
|
||||
argcomplete = "^2.0.0"
|
||||
astor = "^0.8.1"
|
||||
bokeh = "1.1.0"
|
||||
boto3 = "1.9.102"
|
||||
cachetools = ">=2.0.1"
|
||||
cerberus = "^1.3.4"
|
||||
chardet = "3.0.4"
|
||||
click = "^8.0.1"
|
||||
click = "^8.0.3"
|
||||
cloudflare = "^2.8.15"
|
||||
code_writer = "^1.1.1"
|
||||
colorama = "^0.4.4"
|
||||
cryptography = "3.4.8"
|
||||
css-html-prettify = "^2.5.5"
|
||||
cython = "^0.29.24"
|
||||
cython = "^0.29.26"
|
||||
ddt = "1.2.0"
|
||||
decorator = "4.0.10"
|
||||
docutils = "0.16"
|
||||
ebaysdk = "2.1.5"
|
||||
email_validator = "^1.1.3"
|
||||
emoji = "^1.5.0"
|
||||
emoji = "^1.6.3"
|
||||
escpos = "^1.9"
|
||||
extract-msg = "^0.28.7"
|
||||
extract_msg = "^0.28.7"
|
||||
extract-msg = "^0.30.0"
|
||||
extract_msg = "^0.30.0"
|
||||
factur-x = "^2.3"
|
||||
feedparser = "5.2.1"
|
||||
flake8 = "^3.9.2"
|
||||
flake8 = "^4.0.1"
|
||||
formio-data = "^0.3.14"
|
||||
freezegun = "0.3.11"
|
||||
geojson = "2.4.1"
|
||||
gevent = "1.3.4"
|
||||
|
|
@ -63,30 +73,31 @@ html2text = "2016.9.19"
|
|||
html5print = "^0.1.2"
|
||||
invoice2data = "^0.3.6"
|
||||
iscompatible = "^0.1.1"
|
||||
isort = "^5.10.1"
|
||||
jira = "2.0.0"
|
||||
js2py = "^0.71"
|
||||
keystoneauth1 = "3.14.0"
|
||||
lasso = "^0.0.5"
|
||||
libsass = "0.12.3"
|
||||
lxml = "4.6.3"
|
||||
lxml = "4.7.1"
|
||||
matplotlib = ">=2.0.0"
|
||||
mock = "2.0.0"
|
||||
mpld3 = "0.3"
|
||||
mysqlclient = "^2.0.3"
|
||||
mysqlclient = "^2.1.0"
|
||||
num2words = "0.5.6"
|
||||
numpy = "1.21.1"
|
||||
oauthlib = "2.1.0"
|
||||
"oca.decorators" = "^0.0.1"
|
||||
ofxparse = "0.16"
|
||||
openpyxl = "^3.0.9"
|
||||
openupgradelib = "^3.1.1"
|
||||
openupgradelib = "^3.3.1"
|
||||
pandas = "1.2.0"
|
||||
paramiko = "^2.7.2"
|
||||
paramiko = "^2.9.2"
|
||||
passlib = "1.6.5"
|
||||
pdf2image = "^1.16.0"
|
||||
pdfminer = "^20191125"
|
||||
pexpect = "^4.8.0"
|
||||
phonenumbers = "^8.12.33"
|
||||
phonenumbers = "^8.12.41"
|
||||
plotly = "4.1.0"
|
||||
premailer = "^3.10.0"
|
||||
psutil = "5.6.6"
|
||||
|
|
@ -94,15 +105,17 @@ psycopg2 = "2.7.3.1"
|
|||
py-Asterisk = "^0.5.18"
|
||||
"py3o.formats" = "^0.3"
|
||||
"py3o.template" = "^0.10.0"
|
||||
pycountry = "^20.7.3"
|
||||
pycountry = "^22.1.10"
|
||||
pycrypto = "^2.6.1"
|
||||
pydot = "1.2.3"
|
||||
pygount = "<1.2.0"
|
||||
pyjsparser = "^2.7.1"
|
||||
pyldap = "2.4.28"
|
||||
pymssql = "^2.2.2"
|
||||
pymssql = "^2.2.3"
|
||||
pymysql = "^1.0.2"
|
||||
pyotp = "^2.6.0"
|
||||
pyparsing = "2.1.10"
|
||||
pyproj = "^3.2.1"
|
||||
pyproj = "3.2.1"
|
||||
pyserial = "3.1.1"
|
||||
pysftp = "^0.2.9"
|
||||
python-chess = "<0.24"
|
||||
|
|
@ -112,7 +125,7 @@ python-git = "^2018.2.1"
|
|||
python-json-logger = "0.1.5"
|
||||
python-keystoneclient = "3.22.0"
|
||||
python-slugify = ">=3.0.2"
|
||||
python-stdnum = "^1.16"
|
||||
python-stdnum = "^1.17"
|
||||
python-swiftclient = "3.9.0"
|
||||
python-u2flib-server = "^5.0.1"
|
||||
python-u2flib_server = "^5.0.1"
|
||||
|
|
@ -130,13 +143,13 @@ requests-toolbelt = "0.9.1"
|
|||
retrying = "^1.3.3"
|
||||
serial = "^0.0.97"
|
||||
shapely = "1.6.4.post2"
|
||||
simplejson = "^3.17.5"
|
||||
simplejson = "^3.17.6"
|
||||
slugify = "^0.0.1"
|
||||
sphinx = ">=1.6.7"
|
||||
sphinx-intl = "^2.0.1"
|
||||
sphinx-patchqueue = ">=1.0"
|
||||
sphinx_rtd_theme = "^1.0.0"
|
||||
sqlalchemy = "^1.4.25"
|
||||
sqlalchemy = "^1.4.31"
|
||||
statsd = "3.2.1"
|
||||
suds-jurko = "0.6"
|
||||
toml = "^0.10.2"
|
||||
|
|
@ -149,10 +162,10 @@ vcrpy-unittest = "^0.1.7"
|
|||
vobject = "0.9.3"
|
||||
voicent-python = "^1.0"
|
||||
webcolors = "1.10"
|
||||
websocket-client = "^1.2.1"
|
||||
wechatpy = "^1.8.15"
|
||||
websocket-client = "^1.2.3"
|
||||
wechatpy = "^1.8.18"
|
||||
wget = "^3.2"
|
||||
wheel = "^0.37.0"
|
||||
wheel = "^0.37.1"
|
||||
xlrd = "1.0.0"
|
||||
xlwt = "1.3"
|
||||
xmlformatter = "^0.2.4"
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ html5print
|
|||
css-html-prettify
|
||||
BeautifulSoup4
|
||||
git+https://github.com/psf/black.git@21.6b0
|
||||
isort
|
||||
|
||||
# For updating poetry
|
||||
toml
|
||||
|
|
@ -59,6 +60,9 @@ emoji
|
|||
# Code generator
|
||||
mysqlclient
|
||||
|
||||
# pyproj >=3.3.0 is not compatible with python 3.7
|
||||
pyproj==3.2.1
|
||||
|
||||
# Force update dependency to fix poetry
|
||||
numpy==1.21.1
|
||||
|
||||
|
|
@ -67,8 +71,9 @@ numpy==1.21.1
|
|||
# error with 5.x (ConstructorError: could not determine a constructor for the tag '!record')
|
||||
# pyyaml==5.4
|
||||
Jinja2==2.11.3
|
||||
lxml==4.6.3
|
||||
lxml==4.7.1
|
||||
cryptography==3.4.8
|
||||
psutil==5.6.6
|
||||
Pillow==8.3.2
|
||||
Werkzeug==0.15.3
|
||||
Pillow==9.0.0
|
||||
Werkzeug==0.11.15
|
||||
Babel==2.9.1
|
||||
|
|
|
|||
115
script/addons/check_addons_exist.py
Executable file
115
script/addons/check_addons_exist.py
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
CONFIG_PATH = "./config.conf"
|
||||
|
||||
logging.basicConfig(
|
||||
format=(
|
||||
"%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d]"
|
||||
" %(message)s"
|
||||
),
|
||||
datefmt="%Y-%m-%d:%H:%M:%S",
|
||||
level=logging.INFO,
|
||||
)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Check if module exist and is not multiple here to manage conflict.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--module",
|
||||
required=True,
|
||||
help="Module name to search, a list can be use separate by ,",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug",
|
||||
action="store_true",
|
||||
help="Enable debug output",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if config.debug:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
|
||||
config_parser = configparser.ConfigParser()
|
||||
config_parser.read(CONFIG_PATH)
|
||||
if "options" in config_parser:
|
||||
if "addons_path" in config_parser["options"]:
|
||||
addons_path = config_parser["options"]["addons_path"]
|
||||
else:
|
||||
_logger.error(
|
||||
"Missing item 'addons_path' in section 'options' in"
|
||||
f" '{CONFIG_PATH}'"
|
||||
)
|
||||
return -1
|
||||
else:
|
||||
_logger.error(f"Missing section 'options' in '{CONFIG_PATH}'")
|
||||
return -1
|
||||
|
||||
lst_addons_path = addons_path.split(",")
|
||||
lst_module = config.module.split(",")
|
||||
|
||||
dct_module_exist = defaultdict(list)
|
||||
dct_module_exist_empty = defaultdict(list)
|
||||
lst_module_not_exist = []
|
||||
|
||||
for module in lst_module:
|
||||
for path in lst_addons_path:
|
||||
module_path = os.path.join(path, module)
|
||||
manifest_file_path = os.path.join(module_path, "__manifest__.py")
|
||||
if os.path.isdir(module_path):
|
||||
if os.path.isfile(manifest_file_path):
|
||||
dct_module_exist[module].append(module_path)
|
||||
else:
|
||||
dct_module_exist_empty[module].append(module_path)
|
||||
|
||||
if module not in dct_module_exist.keys():
|
||||
lst_module_not_exist.append(module)
|
||||
|
||||
is_good = True
|
||||
if lst_module_not_exist:
|
||||
is_good = False
|
||||
module_list = "'" + "', '".join(lst_module_not_exist) + "'"
|
||||
_logger.error(
|
||||
"Missing"
|
||||
f" module{'s' if len(lst_module_not_exist) > 1 else ''} {module_list}"
|
||||
)
|
||||
if dct_module_exist:
|
||||
for key, lst_value in dct_module_exist.items():
|
||||
if len(lst_value) != 1:
|
||||
is_good = False
|
||||
module_list = "'" + "', '".join(lst_value) + "'"
|
||||
_logger.error(f"Conflict modules: {module_list}")
|
||||
for value in lst_value:
|
||||
print(value)
|
||||
|
||||
if dct_module_exist_empty:
|
||||
for key, lst_value in dct_module_exist_empty.items():
|
||||
module_list = "'" + "', '".join(lst_value) + "'"
|
||||
_logger.warning(
|
||||
"Found this directory, but missing __manifest__.py:"
|
||||
f" {module_list}"
|
||||
)
|
||||
|
||||
return 0 if is_good else -1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
./run.sh --no-http --stop-after-init -d $1 -i $2 -u $2
|
||||
./script/addons/check_addons_exist.py -m "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
exit 1
|
||||
fi
|
||||
./run.sh --no-http --stop-after-init -d "$1" -i "$2" -u "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
./run.sh --no-http --stop-after-init --dev qweb -d $1 -i $2 -u $2
|
||||
./script/addons/check_addons_exist.py -m "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
exit 1
|
||||
fi
|
||||
./run.sh --no-http --stop-after-init --dev qweb -d "$1" -i "$2" -u "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons_dev.sh"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
./script/addons/uninstall_addons.sh $1 $2
|
||||
./script/addons/install_addons_dev.sh $1 $2
|
||||
./script/addons/check_addons_exist.py -m "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
exit 1
|
||||
fi
|
||||
./script/addons/uninstall_addons.sh "$1" "$2"
|
||||
./script/addons/install_addons_dev.sh "$1" "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error reinstall_addons.sh"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
./run.sh --no-http --stop-after-init -d $1 --uninstall $2
|
||||
./script/addons/check_addons_exist.py -m "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
exit 1
|
||||
fi
|
||||
./run.sh --no-http --stop-after-init -d "$1" --uninstall "$2"
|
||||
|
|
|
|||
|
|
@ -73,27 +73,41 @@ On_IPurple='\033[0;105m' # Purple
|
|||
On_ICyan='\033[0;106m' # Cyan
|
||||
On_IWhite='\033[0;107m' # White
|
||||
|
||||
# TODO support argument to test only specified path
|
||||
|
||||
check_git() {
|
||||
REP=$1
|
||||
cd ${REP}
|
||||
cd "${REP}" || exit
|
||||
|
||||
output=$(git status --porcelain)
|
||||
if [ -z "$output" ]; then
|
||||
echo "PASS - ${REP}"
|
||||
if [ $# -gt 1 ]; then
|
||||
output=$(git status --porcelain "$2")
|
||||
else
|
||||
echo -e "${Red}FAIL - ${REP}${Color_Off}"
|
||||
output=$(git status --porcelain)
|
||||
fi
|
||||
if [ -z "$output" ]; then
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "PASS - ${REP}/${2}"
|
||||
else
|
||||
echo "PASS - ${REP}"
|
||||
fi
|
||||
else
|
||||
if [ $# -gt 1 ]; then
|
||||
echo -e "${Red}FAIL - ${REP}${2}${Color_Off}"
|
||||
else
|
||||
echo -e "${Red}FAIL - ${REP}${Color_Off}"
|
||||
fi
|
||||
echo -e "${BRed}${output}${Color_Off}"
|
||||
cd - >/dev/null
|
||||
cd - >/dev/null || exit
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd - >/dev/null
|
||||
cd - >/dev/null || exit
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
check_git "$1"
|
||||
if [ $# -gt 1 ]; then
|
||||
check_git "$1" "$2"
|
||||
else
|
||||
check_git "$1"
|
||||
fi
|
||||
else
|
||||
# check_git "./addons/TechnoLibre_odoo-code-generator"
|
||||
check_git "./addons/TechnoLibre_odoo-code-generator-template"
|
||||
|
|
|
|||
60
script/code_generator/create_from_existing_module.py
Executable file
60
script/code_generator/create_from_existing_module.py
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# TODO Check if exist, (A) master[template], (B) replicator[code_generator], (C) module
|
||||
# TODO if force, recreate from C
|
||||
# TODO if c is code_generator_demo with a different name, execute it.
|
||||
# TODO if a exist, execute it, and execute b.
|
||||
# TODO open commit view
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Get the list of updating module in a working path,
|
||||
for each module, search where it's suppose to generate new code,
|
||||
compare if the date change of directory is after the starting date.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--directory",
|
||||
required=True,
|
||||
help="Directory of the module.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--module_name",
|
||||
required=True,
|
||||
help="Module name to create",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
required=True,
|
||||
help="Force override directory and module.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if not os.path.exists(config.directory):
|
||||
_logger.error(f"Path directory {config.directory} not exist.")
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -1,29 +1,47 @@
|
|||
#!/usr/bin/env bash
|
||||
# $1 is database name
|
||||
# $2 is module name
|
||||
# $2 is module name separate by ,
|
||||
# $3 is directory path to check
|
||||
# $4 is generated module name separate by ,
|
||||
|
||||
./script/addons/install_addons_dev.sh $1 $2
|
||||
if (($# < 4)); then
|
||||
echo "ERROR, need 4 arguments: 1-database name, 2-list of module to install, 3-directory to check difference, 4-list of generated module"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INIT_DATETIME=$(date +%s)
|
||||
|
||||
./script/addons/install_addons_dev.sh "$1" "$2"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/addons/install_addons_dev.sh ${1} ${2}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the code was updated
|
||||
./script/code_generator/test_code_generator_update_module.py -m "$4" -d "$3" --datetime "${INIT_DATETIME}"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/code_generator/test_code_generator_update_module.py ${4} ${3}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO check output when got warning
|
||||
./script/repo_revert_git_diff_date_from_code_generator.py
|
||||
# Remove pot and po diff
|
||||
cd $3
|
||||
cd "$3" || exit 1
|
||||
# git 2.22 and more, else use next command
|
||||
#BRANCH=$(git branch --show-current)
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
#BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# Support old version git < 2.23.0
|
||||
# git restore --source="${BRANCH}" "*.po*"
|
||||
git checkout -- "*.po*"
|
||||
|
||||
cd -
|
||||
./script/maintenance/black.sh $3
|
||||
cd - || exit 1
|
||||
./script/maintenance/black.sh "$3"
|
||||
echo "TEST ${2}"
|
||||
./script/code_generator/check_git_change_code_generator.sh $3
|
||||
./script/code_generator/check_git_change_code_generator.sh "$3"
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/code_generator/check_git_change_code_generator.sh"
|
||||
|
|
|
|||
498
script/code_generator/new_project.py
Executable file
498
script/code_generator/new_project.py
Executable file
|
|
@ -0,0 +1,498 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from git import Repo
|
||||
from git.exc import InvalidGitRepositoryError, NoSuchPathError
|
||||
|
||||
CODE_GENERATOR_DIRECTORY = "./addons/TechnoLibre_odoo-code-generator-template/"
|
||||
CODE_GENERATOR_DEMO_NAME = "code_generator_demo"
|
||||
KEY_REPLACE_CODE_GENERATOR_DEMO = 'MODULE_NAME = "%s"'
|
||||
|
||||
logging.basicConfig(
|
||||
format=(
|
||||
"%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d]"
|
||||
" %(message)s"
|
||||
),
|
||||
datefmt="%Y-%m-%d:%H:%M:%S",
|
||||
level=logging.INFO,
|
||||
)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# TODO Check if exist DONE
|
||||
# TODO change name into code_generator_demo DONE
|
||||
# TODO Create code generator empty module with demo DONE
|
||||
# TODO revert code_generator_demo DONE
|
||||
# TODO execute create_code_generator_from_existing_module.sh with force option
|
||||
# TODO open web interface on right database already selected locally with make run
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Create new project for a single module with code generator suite.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--directory",
|
||||
required=True,
|
||||
help="Directory of the module, need to be a git root directory.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--module",
|
||||
required=True,
|
||||
help="Module name to create",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--directory_code_generator",
|
||||
help="The directory of the code_generator to use.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--code_generator_name",
|
||||
help="The name of the code_generator to use.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--directory_template_name",
|
||||
help="The directory of the template to use.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_name",
|
||||
help="The name of the template to use.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Force override directory and module.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--do_not_update_config",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Ignore updating config file. This is a patch for a bug for"
|
||||
" duplicate path, but 1 relative and the other is absolute."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--keep_bd_alive",
|
||||
action="store_true",
|
||||
help="By default, the bd is cleaned after a run.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug",
|
||||
action="store_true",
|
||||
help="Enable debug output",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
class ProjectManagement:
|
||||
def __init__(
|
||||
self,
|
||||
module_name,
|
||||
module_directory,
|
||||
cg_name="",
|
||||
cg_directory="",
|
||||
template_name="",
|
||||
template_directory="",
|
||||
force=False,
|
||||
ignore_config=False,
|
||||
keep_bd_alive=False,
|
||||
):
|
||||
self.force = force
|
||||
self.ignore_config = ignore_config
|
||||
self.keep_bd_alive = keep_bd_alive
|
||||
self.msg_error = ""
|
||||
self.origin_config_txt = ""
|
||||
self.has_config_update = False
|
||||
|
||||
self.module_directory = module_directory
|
||||
if not os.path.exists(self.module_directory):
|
||||
self.msg_error = (
|
||||
f"Path directory '{self.module_directory}' not exist."
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return
|
||||
|
||||
self.cg_directory = cg_directory if cg_directory else module_directory
|
||||
if not os.path.exists(self.cg_directory):
|
||||
self.msg_error = (
|
||||
f"Path cg directory '{self.cg_directory}' not exist."
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return
|
||||
|
||||
self.template_directory = (
|
||||
template_directory if template_directory else module_directory
|
||||
)
|
||||
if not os.path.exists(self.template_directory):
|
||||
self.msg_error = (
|
||||
f"Path template directory '{self.template_directory}' not"
|
||||
" exist."
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return
|
||||
|
||||
if not module_name:
|
||||
self.msg_error = "Module name is missing."
|
||||
_logger.error(self.msg_error)
|
||||
return
|
||||
|
||||
# Get module name
|
||||
self.module_name = module_name
|
||||
# Get code_generator name
|
||||
self.cg_name = self._generate_cg_name(default=cg_name)
|
||||
# Get template name
|
||||
self.template_name = self._generate_template_name(
|
||||
default=template_name
|
||||
)
|
||||
|
||||
def _generate_cg_name(self, default=""):
|
||||
if default:
|
||||
return default
|
||||
return f"code_generator_{self.module_name}"
|
||||
|
||||
def _generate_template_name(self, default=""):
|
||||
if default:
|
||||
return default
|
||||
return f"code_generator_template_{self.module_name}"
|
||||
|
||||
def search_and_replace_file(self, filepath, lst_search_and_replace):
|
||||
"""
|
||||
lst_search_and_replace is a list of tuple, first item is search, second is replace
|
||||
"""
|
||||
with open(filepath, "r") as file:
|
||||
txt = file.read()
|
||||
for search, replace in lst_search_and_replace:
|
||||
if search not in txt:
|
||||
self.msg_error = (
|
||||
f"Cannot find '{search}' in file '{filepath}'"
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return False
|
||||
txt = txt.replace(search, replace)
|
||||
with open(filepath, "w") as file:
|
||||
file.write(txt)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def validate_path_ready_to_be_override(name, directory, path=""):
|
||||
if not path:
|
||||
path = os.path.join(directory, name)
|
||||
if not os.path.exists(path):
|
||||
return True
|
||||
# Check if in git
|
||||
try:
|
||||
git_repo = Repo(directory)
|
||||
except NoSuchPathError:
|
||||
_logger.error(f"Directory not existing '{directory}'")
|
||||
return False
|
||||
except InvalidGitRepositoryError:
|
||||
_logger.error(
|
||||
f"The path '{path}' exist, but no git repo, use force to"
|
||||
" ignore it."
|
||||
)
|
||||
return False
|
||||
|
||||
status = git_repo.git.status(name, porcelain=True)
|
||||
if status:
|
||||
_logger.error(
|
||||
f"The directory '{path}' has git difference, use force to"
|
||||
" ignore it."
|
||||
)
|
||||
print(status)
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def restore_git_code_generator_demo(
|
||||
code_generator_demo_path, relative_path
|
||||
):
|
||||
try:
|
||||
git_repo = Repo(code_generator_demo_path)
|
||||
except NoSuchPathError:
|
||||
_logger.error(
|
||||
f"Directory not existing '{code_generator_demo_path}'"
|
||||
)
|
||||
return False
|
||||
except InvalidGitRepositoryError:
|
||||
_logger.error(
|
||||
f"The path '{code_generator_demo_path}' exist, but no git repo"
|
||||
)
|
||||
return False
|
||||
|
||||
git_repo.git.restore(relative_path)
|
||||
|
||||
def generate_module(self):
|
||||
module_path = os.path.join(self.module_directory, self.module_name)
|
||||
if not self.force and not self.validate_path_ready_to_be_override(
|
||||
self.module_name, self.module_directory, path=module_path
|
||||
):
|
||||
self.msg_error = f"Cannot generate on module path '{module_path}'"
|
||||
_logger.error(self.msg_error)
|
||||
return False
|
||||
|
||||
cg_path = os.path.join(self.cg_directory, self.cg_name)
|
||||
if not self.force and not self.validate_path_ready_to_be_override(
|
||||
self.cg_name, self.cg_directory, path=cg_path
|
||||
):
|
||||
self.msg_error = f"Cannot generate on cg path '{cg_path}'"
|
||||
_logger.error(self.msg_error)
|
||||
return False
|
||||
|
||||
template_path = os.path.join(
|
||||
self.template_directory, self.template_name
|
||||
)
|
||||
template_hooks_py = os.path.join(template_path, "hooks.py")
|
||||
if not self.force and not self.validate_path_ready_to_be_override(
|
||||
self.template_name, self.template_directory, path=template_path
|
||||
):
|
||||
self.msg_error = (
|
||||
f"Cannot generate on template path '{template_path}'"
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return False
|
||||
|
||||
# Validate code_generator_demo
|
||||
code_generator_demo_path = os.path.join(
|
||||
CODE_GENERATOR_DIRECTORY, CODE_GENERATOR_DEMO_NAME
|
||||
)
|
||||
code_generator_demo_hooks_py = os.path.join(
|
||||
code_generator_demo_path, "hooks.py"
|
||||
)
|
||||
code_generator_hooks_path_relative = os.path.join(
|
||||
CODE_GENERATOR_DEMO_NAME, "hooks.py"
|
||||
)
|
||||
if not os.path.exists(code_generator_demo_path):
|
||||
self.msg_error = (
|
||||
"code_generator_demo is not accessible"
|
||||
f" '{code_generator_demo_path}'"
|
||||
)
|
||||
_logger.error(self.msg_error)
|
||||
return False
|
||||
|
||||
if not (
|
||||
self.validate_path_ready_to_be_override(
|
||||
CODE_GENERATOR_DEMO_NAME, CODE_GENERATOR_DIRECTORY
|
||||
)
|
||||
and self.search_and_replace_file(
|
||||
code_generator_demo_hooks_py,
|
||||
[
|
||||
(
|
||||
KEY_REPLACE_CODE_GENERATOR_DEMO
|
||||
% CODE_GENERATOR_DEMO_NAME,
|
||||
KEY_REPLACE_CODE_GENERATOR_DEMO % self.template_name,
|
||||
),
|
||||
(
|
||||
'value["enable_sync_template"] = False',
|
||||
'value["enable_sync_template"] = True',
|
||||
),
|
||||
(
|
||||
"# path_module_generate ="
|
||||
" os.path.normpath(os.path.join(os.path.dirname(__file__),"
|
||||
" '..'))",
|
||||
f'path_module_generate = "{self.module_directory}"',
|
||||
),
|
||||
(
|
||||
'# "path_sync_code": path_module_generate,',
|
||||
'"path_sync_code": path_module_generate,',
|
||||
),
|
||||
(
|
||||
'# value["template_module_path_generated_extension"]'
|
||||
' = "."',
|
||||
'value["template_module_path_generated_extension"] ='
|
||||
f' "{self.cg_directory}"',
|
||||
),
|
||||
],
|
||||
)
|
||||
):
|
||||
return False
|
||||
self.update_config()
|
||||
|
||||
bd_name_demo = f"new_project_code_generator_demo_{uuid.uuid4()}"[:63]
|
||||
cmd = f"./script/db_restore.py --database {bd_name_demo}"
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
_logger.info("========= GENERATE code_generator_demo =========")
|
||||
cmd = (
|
||||
f"./script/addons/install_addons_dev.sh {bd_name_demo}"
|
||||
" code_generator_demo"
|
||||
)
|
||||
os.system(cmd)
|
||||
|
||||
if not self.keep_bd_alive:
|
||||
cmd = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {bd_name_demo}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# Revert code_generator_demo
|
||||
self.restore_git_code_generator_demo(
|
||||
CODE_GENERATOR_DIRECTORY, code_generator_hooks_path_relative
|
||||
)
|
||||
|
||||
# Validate
|
||||
if not os.path.exists(template_path):
|
||||
_logger.error(f"Module template not exists '{template_path}'")
|
||||
self.revert_config()
|
||||
return False
|
||||
else:
|
||||
_logger.info(f"Module template exists '{template_path}'")
|
||||
|
||||
self.search_and_replace_file(
|
||||
template_hooks_py,
|
||||
[
|
||||
(
|
||||
'value["enable_template_wizard_view"] = False',
|
||||
'value["enable_template_wizard_view"] = True',
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
# Execute all
|
||||
bd_name_template = (
|
||||
f"new_project_code_generator_template_{uuid.uuid4()}"[:63]
|
||||
)[:63]
|
||||
cmd = f"./script/db_restore.py --database {bd_name_template}"
|
||||
os.system(cmd)
|
||||
_logger.info(cmd)
|
||||
_logger.info(f"========= GENERATE {self.template_name} =========")
|
||||
# TODO maybe the module exist somewhere else
|
||||
if os.path.exists(module_path):
|
||||
# Install module before running code generator
|
||||
cmd = (
|
||||
"./script/code_generator/search_class_model.py --quiet -d"
|
||||
f" {module_path} -t {template_path}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
cmd = (
|
||||
f"./script/addons/install_addons_dev.sh {bd_name_template}"
|
||||
f" {self.module_name}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
cmd = (
|
||||
f"./script/addons/install_addons_dev.sh {bd_name_template}"
|
||||
f" {self.template_name}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
if not self.keep_bd_alive:
|
||||
cmd = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {bd_name_template}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# Validate
|
||||
if not os.path.exists(cg_path):
|
||||
_logger.error(f"Module cg not exists '{cg_path}'")
|
||||
self.revert_config()
|
||||
return False
|
||||
else:
|
||||
_logger.info(f"Module cg exists '{cg_path}'")
|
||||
|
||||
bd_name_generator = f"new_project_code_generator_{uuid.uuid4()}"[:63]
|
||||
cmd = f"./script/db_restore.py --database {bd_name_generator}"
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
_logger.info(f"========= GENERATE {self.cg_name} =========")
|
||||
|
||||
cmd = (
|
||||
f"./script/addons/install_addons_dev.sh {bd_name_generator}"
|
||||
f" {self.cg_name}"
|
||||
)
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
if not self.keep_bd_alive:
|
||||
cmd = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {bd_name_generator}"
|
||||
)[:63]
|
||||
_logger.info(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# Validate
|
||||
if not os.path.exists(template_path):
|
||||
_logger.error(f"Module not exists '{module_path}'")
|
||||
self.revert_config()
|
||||
return False
|
||||
else:
|
||||
_logger.info(f"Module exists '{module_path}'")
|
||||
|
||||
self.revert_config()
|
||||
return True
|
||||
|
||||
def update_config(self):
|
||||
if self.ignore_config:
|
||||
return
|
||||
# Backup config and restore it after, check if path exist or add it temporary
|
||||
with open("./config.conf") as config:
|
||||
config_txt = config.read()
|
||||
self.origin_config_txt = config_txt
|
||||
lst_directory = list(
|
||||
{
|
||||
self.cg_directory,
|
||||
self.module_directory,
|
||||
self.template_directory,
|
||||
}
|
||||
)
|
||||
lst_directory_to_add = []
|
||||
for directory in lst_directory:
|
||||
if directory not in config_txt:
|
||||
self.has_config_update = True
|
||||
lst_directory_to_add.append(directory)
|
||||
|
||||
if lst_directory_to_add:
|
||||
new_str = "addons_path = " + ",".join(lst_directory_to_add) + ","
|
||||
config_txt = config_txt.replace("addons_path = ", new_str)
|
||||
with open("./config.conf", "w") as config:
|
||||
config.write(config_txt)
|
||||
|
||||
def revert_config(self):
|
||||
if self.ignore_config:
|
||||
return
|
||||
with open("./config.conf", "w") as config:
|
||||
config.write(self.origin_config_txt)
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if config.debug:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
project = ProjectManagement(
|
||||
config.module,
|
||||
config.directory,
|
||||
cg_name=config.code_generator_name,
|
||||
template_name=config.template_name,
|
||||
force=config.force,
|
||||
ignore_config=config.do_not_update_config,
|
||||
keep_bd_alive=config.keep_bd_alive,
|
||||
)
|
||||
if project.msg_error:
|
||||
return -1
|
||||
|
||||
if not project.generate_module():
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
223
script/code_generator/search_class_model.py
Executable file
223
script/code_generator/search_class_model.py
Executable file
|
|
@ -0,0 +1,223 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
|
||||
# import glob
|
||||
import ast
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_config():
|
||||
"""Parse command line arguments, extracting the config file name,
|
||||
returning the union of config file and command line arguments
|
||||
|
||||
:return: dict of config file settings and command line arguments
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Search all method class and give a list separate by ;
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--directory",
|
||||
dest="directory",
|
||||
required=True,
|
||||
help="Directory to execute search in recursive.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--template_dir",
|
||||
dest="template_dir",
|
||||
help=(
|
||||
"Overwrite value template_model_name in template module, give only"
|
||||
" template source directory, will update file hooks.py"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--with_inherit",
|
||||
action="store_true",
|
||||
help="Will search inherit model",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
action="store_true",
|
||||
help="Don't show output of found model.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def search_and_replace(
|
||||
f_lines, hooks_file_path, models_name, search_word="template_model_name"
|
||||
):
|
||||
if not models_name:
|
||||
return f_lines
|
||||
t_index = f_lines.find(search_word)
|
||||
if t_index == -1:
|
||||
_logger.error(f"Cannot find {search_word} in file {hooks_file_path}")
|
||||
return -1
|
||||
t_index_equation = f_lines.index("=", t_index + 1)
|
||||
if t_index_equation == -1:
|
||||
_logger.error(f"Cannot find {search_word} = in file {hooks_file_path}")
|
||||
return -1
|
||||
# find next character
|
||||
i = 1
|
||||
while f_lines[t_index_equation + i] in (" ", "\n"):
|
||||
i += 1
|
||||
first_char = f_lines[t_index_equation + i]
|
||||
if first_char == "(":
|
||||
second_char = ")"
|
||||
elif f_lines[t_index_equation + i : t_index_equation + i + 3] == '"""':
|
||||
first_char = '"""'
|
||||
second_char = '"""'
|
||||
else:
|
||||
second_char = first_char
|
||||
# t_index_first_quote = f_lines.index(first_char, t_index + 1)
|
||||
t_index_second_quote = f_lines.index(first_char, t_index_equation + i)
|
||||
if t_index_second_quote == -1:
|
||||
_logger.error(
|
||||
f'Cannot find {search_word} = "##" in file {hooks_file_path}'
|
||||
)
|
||||
return -1
|
||||
t_index_third_quote = f_lines.index(second_char, t_index_second_quote + 1)
|
||||
if t_index_third_quote == -1:
|
||||
_logger.error(f"Cannot find third quote in file {hooks_file_path}")
|
||||
return -1
|
||||
# if "\n" in models_name:
|
||||
# new_file_content = (
|
||||
# f'{f_lines[:t_index_second_quote]}"""{models_name}"""{f_lines[t_index_third_quote + len(second_char):]}'
|
||||
# )
|
||||
# else:
|
||||
# new_file_content = (
|
||||
# f'{f_lines[:t_index_second_quote]}"{models_name}"{f_lines[t_index_third_quote + len(second_char):]}'
|
||||
# )
|
||||
new_file_content = (
|
||||
f'{f_lines[:t_index_second_quote]}"{models_name}"{f_lines[t_index_third_quote + len(second_char):]}'
|
||||
)
|
||||
return new_file_content
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if not os.path.exists(config.directory):
|
||||
_logger.error(f"Path directory {config.directory} not exist.")
|
||||
return -1
|
||||
lst_model_name = []
|
||||
lst_model_inherit_name = []
|
||||
lst_search_target = ("_name",)
|
||||
|
||||
lst_search_inherit_target = ("_inherit",) if config.with_inherit else []
|
||||
|
||||
# lst_py_file = glob.glob(os.path.join(config.directory, "***", "*.py"))
|
||||
lst_py_file = Path(config.directory).rglob("*.py")
|
||||
for py_file in lst_py_file:
|
||||
if py_file == "__init__.py":
|
||||
continue
|
||||
with open(py_file, "r") as source:
|
||||
f_lines = source.read()
|
||||
try:
|
||||
f_ast = ast.parse(f_lines)
|
||||
except Exception as e:
|
||||
_logger.error(f"Cannot parse file {py_file}")
|
||||
continue
|
||||
for children in f_ast.body:
|
||||
if type(children) == ast.ClassDef:
|
||||
# Detect good _name
|
||||
for node in children.body:
|
||||
if (
|
||||
type(node) is ast.Assign
|
||||
and node.targets
|
||||
and type(node.targets[0]) is ast.Name
|
||||
# and node.targets[0].id in ("_name",)
|
||||
and type(node.value) is ast.Str
|
||||
):
|
||||
if (
|
||||
lst_search_target
|
||||
and node.targets[0].id in lst_search_target
|
||||
):
|
||||
if node.value.s in lst_model_name:
|
||||
_logger.warning(
|
||||
"Duplicated model name"
|
||||
f" {node.value.s} from file {py_file}"
|
||||
)
|
||||
else:
|
||||
lst_model_name.append(node.value.s)
|
||||
|
||||
if (
|
||||
lst_search_inherit_target
|
||||
and node.targets[0].id
|
||||
in lst_search_inherit_target
|
||||
):
|
||||
if node.value.s in lst_model_inherit_name:
|
||||
_logger.warning(
|
||||
"Duplicated model inherit name"
|
||||
f" {node.value.s} from file {py_file}"
|
||||
)
|
||||
else:
|
||||
lst_model_inherit_name.append(node.value.s)
|
||||
lst_model_name.sort()
|
||||
lst_model_inherit_name.sort()
|
||||
models_name = "; ".join(lst_model_name)
|
||||
# TODO temporary fix, remove this when it's supported
|
||||
lst_ignored_inherit = ["portal.mixin", "mail.thread"]
|
||||
for ignored_inherit in lst_ignored_inherit:
|
||||
if ignored_inherit in lst_model_inherit_name:
|
||||
lst_model_inherit_name.remove(ignored_inherit)
|
||||
models_inherit_name = "; ".join(lst_model_inherit_name)
|
||||
if not models_name:
|
||||
_logger.warning(f"Missing models class in {config.directory}")
|
||||
elif not config.quiet:
|
||||
# _logger.info(models_name)
|
||||
print(models_name)
|
||||
print(models_inherit_name)
|
||||
|
||||
if config.template_dir:
|
||||
if not os.path.exists(config.template_dir):
|
||||
_logger.error(
|
||||
f"Path template dir {config.template_dir} not exist."
|
||||
)
|
||||
return -1
|
||||
hooks_file_path = os.path.join(config.template_dir, "hooks.py")
|
||||
if not os.path.exists(hooks_file_path):
|
||||
_logger.error(
|
||||
f"Path template hooks.py file {hooks_file_path} not exist."
|
||||
)
|
||||
return -1
|
||||
|
||||
with open(hooks_file_path, "r") as source:
|
||||
f_lines = source.read()
|
||||
# Throw exception if not found
|
||||
new_file_content = search_and_replace(
|
||||
f_lines, hooks_file_path, models_name
|
||||
)
|
||||
if models_inherit_name:
|
||||
new_file_content = search_and_replace(
|
||||
new_file_content,
|
||||
hooks_file_path,
|
||||
models_inherit_name,
|
||||
search_word="template_inherit_model_name",
|
||||
)
|
||||
|
||||
with open(hooks_file_path, "w") as source:
|
||||
source.write(new_file_content)
|
||||
|
||||
# Call black
|
||||
os.system(f"./script/maintenance/black.sh {hooks_file_path}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
status = main()
|
||||
sys.exit(status)
|
||||
89
script/code_generator/test_code_generator_update_module.py
Executable file
89
script/code_generator/test_code_generator_update_module.py
Executable file
|
|
@ -0,0 +1,89 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Get the list of updating module in a working path,
|
||||
for each module, search where it's suppose to generate new code,
|
||||
compare if the date change of directory is after the starting date.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--directory",
|
||||
dest="directory",
|
||||
required=True,
|
||||
help="Directory of the module to check.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--module_list",
|
||||
dest="module_list",
|
||||
required=True,
|
||||
help="List of module, separate by ','",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--datetime",
|
||||
dest="datetime",
|
||||
required=True,
|
||||
help="The datetime to check if the generated module is after.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if not os.path.exists(config.directory):
|
||||
_logger.error(f"Path directory {config.directory} not exist.")
|
||||
return -1
|
||||
lst_module = [a for a in config.module_list.split(",") if a.split()]
|
||||
if not lst_module:
|
||||
_logger.error(f"No module was selected, be sure to use --module_list")
|
||||
return -1
|
||||
|
||||
lst_result_good = []
|
||||
lst_result_wrong = []
|
||||
for module_name in lst_module:
|
||||
if config.directory.endswith(module_name):
|
||||
module_path = config.directory
|
||||
else:
|
||||
module_path = os.path.join(config.directory, module_name)
|
||||
if not os.path.exists(module_path):
|
||||
_logger.error(
|
||||
f"Module '{module_name}' not existing in path"
|
||||
f" '{config.directory}'."
|
||||
)
|
||||
return -1
|
||||
stat = os.stat(module_path)
|
||||
result = stat.st_mtime > float(config.datetime)
|
||||
if result:
|
||||
lst_result_good.append(module_name)
|
||||
else:
|
||||
lst_result_wrong.append(module_name)
|
||||
|
||||
if lst_result_wrong:
|
||||
_logger.error(
|
||||
"FAIL - Some modules wasn't updated, did you execute the code"
|
||||
f" generator? {lst_result_wrong}"
|
||||
)
|
||||
return -1
|
||||
elif lst_result_good:
|
||||
_logger.info("SUCCESS - All modules are updated.")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -1,15 +1,16 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from code_writer import CodeWriter
|
||||
|
||||
# import tokenize
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
||||
# import tokenize
|
||||
|
||||
|
||||
def get_config():
|
||||
"""Parse command line arguments, extracting the config file name,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from xml.dom import Node, minidom
|
||||
|
||||
from code_writer import CodeWriter
|
||||
from xml.dom import minidom, Node
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import csv
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import csv
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
14
script/database/README.md
Normal file
14
script/database/README.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Database
|
||||
|
||||
This section is for code generator database migrator.
|
||||
|
||||
This configuration is for development environnement.
|
||||
|
||||
You need to install script `./script/install_dev_extra_ubuntu.sh`.
|
||||
|
||||
## Restore database
|
||||
|
||||
Run script to restore database:
|
||||
```bash
|
||||
./script/database/restore_mariadb_sql_example_1.sh
|
||||
```
|
||||
44
script/database/db_drop_all.py
Executable file
44
script/database/db_drop_all.py
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def execute_shell(cmd):
|
||||
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
|
||||
return out.decode().strip() if out else ""
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Drop all database, caution!
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
|
||||
out_db = execute_shell("./.venv/bin/python3 ./odoo/odoo-bin db --list")
|
||||
lst_db = out_db.split("\n")
|
||||
for db_name in lst_db:
|
||||
execute_shell(
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {db_name}"
|
||||
)
|
||||
print(f"{db_name} deleted")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
2086
script/database/fix_mariadb_sql_example_1.py
Executable file
2086
script/database/fix_mariadb_sql_example_1.py
Executable file
File diff suppressed because it is too large
Load diff
1297
script/database/mariadb_sql_example_1.sql
Normal file
1297
script/database/mariadb_sql_example_1.sql
Normal file
File diff suppressed because it is too large
Load diff
29
script/database/restore_mariadb_sql_example_1.sh
Executable file
29
script/database/restore_mariadb_sql_example_1.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
SQL_PATH=./script/database/mariadb_sql_example_1.sql
|
||||
|
||||
# You need to set no password to mysql root user
|
||||
# SET PASSWORD FOR root@localhost='';
|
||||
# FLUSH PRIVILEGES;
|
||||
|
||||
# Second solution
|
||||
# ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
|
||||
# FLUSH PRIVILEGES;
|
||||
|
||||
echo "Create database and user"
|
||||
mysql -u root << EOF
|
||||
DROP DATABASE IF EXISTS mariadb_sql_example_1;
|
||||
CREATE USER IF NOT EXISTS 'organization'@'localhost' IDENTIFIED BY 'organization';
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'organization'@'localhost' IDENTIFIED BY 'organization';
|
||||
FLUSH PRIVILEGES;
|
||||
CREATE DATABASE mariadb_sql_example_1;
|
||||
EOF
|
||||
|
||||
echo "Fix SQL file"
|
||||
sed -i "s/'0000-00-00'/NULL/g" ${SQL_PATH}
|
||||
|
||||
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
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import configparser
|
||||
import getpass
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from subprocess import check_output
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
import CloudFlare
|
||||
import requests
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
new_path = os.path.normpath(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
import shutil
|
||||
|
||||
import yaml # pip install PyYAML
|
||||
from agithub.GitHub import GitHub # pip install agithub
|
||||
from git import Repo # pip install gitpython
|
||||
from giturlparse import parse # pip install giturlparse
|
||||
from retrying import retry # pip install retrying
|
||||
import yaml # pip install PyYAML
|
||||
|
||||
DEFAULT_CONFIG_FILENAME = "~/.github/fork_github_repo.yaml"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from git import Repo
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
from git import Repo
|
||||
import os
|
||||
import sys
|
||||
|
||||
import git
|
||||
from git import Repo
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -142,7 +142,9 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then
|
|||
printf "${EL_HOME}/addons/muk-it_muk_quality," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/muk-it_muk_web," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/muk-it_muk_website," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/novacode-nl_odoo-formio," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/obayit_odoo_dhtmlxgantt," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/odoo_design-themes," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/odooaktiv_QuotationRevision," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/odooaktiv_product_rating_app," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/odoomates_odooapps," >> ${EL_CONFIG_FILE}
|
||||
|
|
|
|||
104
script/git/remote_code_generation_git_compare.py
Executable file
104
script/git/remote_code_generation_git_compare.py
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
#!./.venv/bin/python
|
||||
# © 2021 TechnoLibre (http://www.technolibre.ca)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
from git import Repo
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_config():
|
||||
"""Parse command line arguments, extracting the config file name,
|
||||
returning the union of config file and command line arguments
|
||||
|
||||
:return: dict of config file settings and command line arguments
|
||||
"""
|
||||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Copy a directory in a temporary directory to compare with a generated code to understand the difference.""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--directory1",
|
||||
required=True,
|
||||
help="Compare input1 to input2. Input1 is older config.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--directory2",
|
||||
required=True,
|
||||
help="The generated code directory",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--replace_directory",
|
||||
action="store_true",
|
||||
help="Erase after first commit to see removing file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
action="store_true",
|
||||
help="Don't show output of difference.",
|
||||
)
|
||||
parser.add_argument("--git_gui", action="store_true", help="Open git gui.")
|
||||
parser.add_argument("--meld", action="store_true", help="Open meld.")
|
||||
parser.add_argument(
|
||||
"--clear",
|
||||
action="store_true",
|
||||
help="Delete temporary directory at the end of execution.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
# path = tempfile.mkdtemp()
|
||||
path = tempfile.NamedTemporaryFile().name
|
||||
if os.path.exists(config.directory1) and os.path.exists(config.directory2):
|
||||
if config.git_gui:
|
||||
shutil.copytree(config.directory1, path)
|
||||
shutil.copy2("./.gitignore", path)
|
||||
# repo = Repo(path)
|
||||
repo = Repo.init(path=path)
|
||||
repo.git.add(".")
|
||||
repo.git.commit("-m", "First commit")
|
||||
# shutil.copy2(config.directory2, path)
|
||||
if config.replace_directory:
|
||||
subprocess.call(f"rm -r {path}/*", shell=True)
|
||||
subprocess.call(f"cp -r {config.directory2}/* {path}", shell=True)
|
||||
status = repo.git.diff()
|
||||
if not config.quiet:
|
||||
print(status)
|
||||
|
||||
try:
|
||||
subprocess.call(f"cd {path};git gui", shell=True)
|
||||
except:
|
||||
pass
|
||||
if config.clear:
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
elif config.meld:
|
||||
try:
|
||||
subprocess.call(f"make clean", shell=True)
|
||||
subprocess.call(
|
||||
f"meld {config.directory1} {config.directory2}", shell=True
|
||||
)
|
||||
except:
|
||||
pass
|
||||
elif not os.path.exists(config.directory1):
|
||||
_logger.error(f"Path is not existing {config.directory1}")
|
||||
# elif not os.path.exists(config.directory2):
|
||||
else:
|
||||
_logger.error(f"Path is not existing {config.directory2}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
from git import Repo
|
||||
import os
|
||||
import sys
|
||||
|
||||
from git import Repo
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from git import Repo
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import copy
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import copy
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
from git import Repo
|
||||
import os
|
||||
import sys
|
||||
|
||||
import git
|
||||
from git import Repo
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
from colorama import Fore, Style
|
||||
from git import Repo
|
||||
from git.exc import GitCommandError, NoSuchPathError
|
||||
from colorama import Fore
|
||||
from colorama import Style
|
||||
from collections import defaultdict
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -3,16 +3,16 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import os
|
||||
import webbrowser
|
||||
from retrying import retry # pip install retrying
|
||||
from agithub.GitHub import GitHub # pip install agithub
|
||||
from giturlparse import parse # pip install giturlparse
|
||||
import xmltodict
|
||||
from collections import OrderedDict
|
||||
|
||||
from git import Repo
|
||||
import git
|
||||
from typing import List
|
||||
|
||||
import git
|
||||
import xmltodict
|
||||
from agithub.GitHub import GitHub # pip install agithub
|
||||
from git import Repo
|
||||
from giturlparse import parse # pip install giturlparse
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
CST_FILE_SOURCE_REPO_ADDONS = "source_repo_addons.csv"
|
||||
CST_EL_GITHUB_TOKEN = "EL_GITHUB_TOKEN"
|
||||
DEFAULT_PROJECT_NAME = "ERPLibre"
|
||||
|
|
@ -391,11 +391,7 @@ class GitTool:
|
|||
lst_result = []
|
||||
for repo in lst_repo:
|
||||
# Exception, ignore addons/OCA_web and root
|
||||
if (
|
||||
"addons/OCA_web" == repo.get("path")
|
||||
or "odoo" == repo.get("path")
|
||||
or "image_db" == repo.get("path")
|
||||
):
|
||||
if repo.get("path") in ["addons/OCA_web", "odoo", "image_db"]:
|
||||
continue
|
||||
str_repo = (
|
||||
f' printf "${{EL_HOME}}/{repo.get("path")}," >> '
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from git import Repo # pip install gitpython
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ sudo npm install -g rtlcss
|
|||
sudo npm install -g less
|
||||
sudo npm install -g prettier
|
||||
sudo npm install -g prettier @prettier/plugin-xml
|
||||
yes n|pyenv install 3.7.7
|
||||
pyenv local 3.7.7
|
||||
yes n|pyenv install 3.7.12
|
||||
pyenv local 3.7.12
|
||||
|
||||
echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
|
||||
|
||||
|
|
@ -49,8 +49,8 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet
|
|||
# Install Wkhtmltopdf if needed
|
||||
#--------------------------------------------------
|
||||
echo "\n---- Installing Wkhtmltopdf if needed ----"
|
||||
if [ ! -f "wkhtmltox-0.12.6-1.macos-cocoa.pkg" ]; then
|
||||
sudo wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.macos-cocoa.pkg
|
||||
sudo sudo installer -pkg wkhtmltox-0.12.6-1.macos-cocoa.pkg -target /
|
||||
if [ ! -f "wkhtmltox-0.12.6-2.macos-cocoa.pkg" ]; then
|
||||
sudo wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-2/wkhtmltox-0.12.6-2.macos-cocoa.pkg
|
||||
sudo sudo installer -pkg wkhtmltox-0.12.6-2.macos-cocoa.pkg -target /
|
||||
else echo "Wkhtmltopdf already installed"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ sudo apt-get install libmariadbd-dev -y
|
|||
sudo apt-get install make libssl-dev zlib1g-dev libreadline-dev libsqlite3-dev curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev liblzma-dev -y
|
||||
|
||||
echo -e "\n---- Installing nodeJS NPM and rtlcss for LTR support ----"
|
||||
sudo apt-get install nodejs npm -y
|
||||
curl -fsSL https://deb.nodesource.com/setup_current.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
sudo npm install npm@latest -g
|
||||
sudo npm install -g rtlcss
|
||||
sudo npm install -g less
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
################################################################################
|
||||
# Script for installing ERPLibre locally for dev
|
||||
# Author: Alexandre Ferreira Benevides
|
||||
################################################################################
|
||||
|
||||
if [[ "${OSTYPE}" == "linux-gnu" ]]; then
|
||||
OS=$(lsb_release -si)
|
||||
VERSION=$(cat /etc/issue)
|
||||
if [[ "${OS}" == "Ubuntu" ]]; then
|
||||
echo "\n---- linux-gnu installation process started ----"
|
||||
./script/install_debian_dependency.sh
|
||||
if [[ "${VERSION}" == Ubuntu\ 18.04* || "${VERSION}" == Ubuntu\ 20.04* ]]; then
|
||||
echo "\n---- linux-gnu installation process started ----"
|
||||
./script/install_debian_dependency.sh
|
||||
else
|
||||
echo "Your version is not supported, only support 18.04 and 20.04 : ${VERSION}"
|
||||
fi
|
||||
else
|
||||
echo "Your Linux system is not supported."
|
||||
echo "Your Linux system is not supported, only support Ubuntu 18.04 or Ubuntu 20.04."
|
||||
fi
|
||||
elif [[ "${OSTYPE}" == "darwin"* ]]; then
|
||||
echo "\n---- Darwin installation process started ----"
|
||||
|
|
|
|||
40
script/install_dev_extra_ubuntu.sh
Executable file
40
script/install_dev_extra_ubuntu.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Need this for test extra
|
||||
|
||||
if [[ "${OSTYPE}" == "linux-gnu" ]]; then
|
||||
OS=$(lsb_release -si)
|
||||
VERSION=$(cat /etc/issue)
|
||||
if [[ "${OS}" == "Ubuntu" ]]; then
|
||||
if [[ "${VERSION}" == Ubuntu\ 18.04* || "${VERSION}" == Ubuntu\ 20.04* ]]; then
|
||||
# Install mariadb
|
||||
sudo apt install mariadb-client mariadb-server
|
||||
echo "This is not for production, this is for development. Mysql user root will be accessible without password."
|
||||
sudo mysql -u root << EOF
|
||||
SET PASSWORD FOR root@localhost='';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
# Install docker
|
||||
sudo apt-get update
|
||||
sudo apt-get install ca-certificates curl gnupg lsb-release
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update
|
||||
sudo apt-get install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
# Run without root
|
||||
#sudo groupadd docker
|
||||
sudo usermod -aG docker "$USER"
|
||||
#newgrp docker
|
||||
|
||||
# Install docker-compose
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
else
|
||||
echo "Your version is not supported, only support 18.04 and 20.04 : ${VERSION}"
|
||||
fi
|
||||
else
|
||||
echo "Your Linux system is not supported, only support Ubuntu 18.04 or Ubuntu 20.04."
|
||||
fi
|
||||
fi
|
||||
|
|
@ -25,7 +25,7 @@ if [[ ! -d "./addons/addons" ]]; then
|
|||
fi
|
||||
|
||||
PYENV_PATH=~/.pyenv
|
||||
PYTHON_VERSION=3.7.7
|
||||
PYTHON_VERSION=3.7.12
|
||||
PYENV_VERSION_PATH=${PYENV_PATH}/versions/${PYTHON_VERSION}
|
||||
PYTHON_EXEC=${PYENV_VERSION_PATH}/bin/python
|
||||
POETRY_PATH=~/.poetry
|
||||
|
|
|
|||
|
|
@ -1,4 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
echo "==$&%== Begin ${@}"
|
||||
echo "
|
||||
===> ${@}
|
||||
"
|
||||
time make $@
|
||||
echo "==$&%== End ${@}"
|
||||
retVal=$?
|
||||
|
||||
echo "
|
||||
<=== ${@}
|
||||
"
|
||||
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error make ${@}"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import zipfile
|
||||
import json
|
||||
from colorama import Fore
|
||||
from colorama import Style
|
||||
|
||||
from colorama import Fore, Style
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ paths=(
|
|||
"${working_path}/"
|
||||
"${working_path}/addons/TechnoLibre_odoo-code-generator"
|
||||
"${working_path}/addons/TechnoLibre_odoo-code-generator-template"
|
||||
"${working_path}/addons/OCA_server-tools"
|
||||
|
||||
)
|
||||
cmd_before="cd "
|
||||
|
|
@ -13,7 +14,7 @@ cmd_after=";gnome-terminal --tab -- bash -c 'git status;bash';"
|
|||
#cmd_after=";gnome-terminal --tab;"
|
||||
|
||||
LONGCMD=""
|
||||
for t in ${paths[@]}; do
|
||||
for t in "${paths[@]}"; do
|
||||
LONGCMD+=${cmd_before}${t}${cmd_after}
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import ast
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import toml
|
||||
import ast
|
||||
from collections import OrderedDict, defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
import iscompatible
|
||||
import toml
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from git import Repo # pip install gitpython
|
||||
from git.exc import GitCommandError
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import git
|
||||
from unidiff import PatchSet
|
||||
import re
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s %(levelname)s: %(message)s",
|
||||
datefmt="%Y-%m-%d %I:%M:%S",
|
||||
)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -62,6 +67,7 @@ def main():
|
|||
with open(file_real_path, "r") as file:
|
||||
lst_data = file.readlines()
|
||||
for data in lst_data:
|
||||
# TODO this remove code begin with this string, why do we remove it?
|
||||
if data.startswith("#: code:addons/addons/"):
|
||||
is_modified = True
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from colorama import Fore, Style
|
||||
from git import Repo # pip install gitpython
|
||||
from retrying import retry # pip install retrying
|
||||
from colorama import Fore
|
||||
from colorama import Style
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
|
|
|||
77
script/test/check_result_test.sh
Executable file
77
script/test/check_result_test.sh
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env bash
|
||||
if (($# < 1)); then
|
||||
echo "ERROR, need 1 arguments: log file path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Color_Off='\033[0m'
|
||||
Red='\033[0;31m'
|
||||
Blue='\033[0;34m'
|
||||
Yellow='\033[0;33m'
|
||||
LOG_FILE="${1}"
|
||||
|
||||
echo "== RESULT from ${LOG_FILE} =="
|
||||
WARNING_MESSAGE=$(grep -i warning "${LOG_FILE}")
|
||||
WARNING_MESSAGE=$(echo "${WARNING_MESSAGE}"|grep -v "have the same label:")
|
||||
WARNING_MESSAGE=$(echo "${WARNING_MESSAGE}"|grep -v "odoo.addons.code_generator.extractor_module_file: Ignore next error about ALTER TABLE DROP CONSTRAINT.")
|
||||
# Remove empty line
|
||||
if [[ -z "${WARNING_MESSAGE// }" ]]; then
|
||||
COUNT_WARNING=0
|
||||
else
|
||||
COUNT_WARNING=$(echo "${WARNING_MESSAGE}"|wc -l)
|
||||
fi
|
||||
|
||||
ERROR_MESSAGE=$(grep -i error "${LOG_FILE}")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "fetchmail_notify_error_to_sender")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "odoo.sql_db: bad query: ALTER TABLE \"db_backup\" DROP CONSTRAINT \"db_backup_db_backup_name_unique\"")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "ERROR: constraint \"db_backup_db_backup_name_unique\" of relation \"db_backup\" does not exist")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "odoo.sql_db: bad query: ALTER TABLE \"db_backup\" DROP CONSTRAINT \"db_backup_db_backup_days_to_keep_positive\"")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "ERROR: constraint \"db_backup_db_backup_days_to_keep_positive\" of relation \"db_backup\" does not exist")
|
||||
ERROR_MESSAGE=$(echo "${ERROR_MESSAGE}"|grep -v "odoo.addons.code_generator.extractor_module_file: Ignore next error about ALTER TABLE DROP CONSTRAINT.")
|
||||
# Remove empty line
|
||||
if [[ -z "${ERROR_MESSAGE// }" ]]; then
|
||||
COUNT_ERROR=0
|
||||
else
|
||||
COUNT_ERROR=$(echo "${ERROR_MESSAGE}"|wc -l)
|
||||
fi
|
||||
|
||||
echo_count_warnings () {
|
||||
if (("${COUNT_WARNING}" > 1)); then
|
||||
echo -e "${Yellow}${COUNT_WARNING} WARNINGS${Color_Off}"
|
||||
else
|
||||
echo -e "${Yellow}${COUNT_WARNING} WARNING${Color_Off}"
|
||||
fi
|
||||
}
|
||||
echo_count_errors () {
|
||||
if (("${COUNT_ERROR}" > 1)); then
|
||||
echo -e "${Red}${COUNT_ERROR} ERRORS${Color_Off}"
|
||||
else
|
||||
echo -e "${Red}${COUNT_ERROR} ERROR${Color_Off}"
|
||||
fi
|
||||
}
|
||||
|
||||
echo -e "${Blue}Summary of check result${Color_Off}"
|
||||
if (("${COUNT_WARNING}" > 0)); then
|
||||
echo_count_warnings
|
||||
fi
|
||||
|
||||
if (("${COUNT_ERROR}" > 0)); then
|
||||
echo_count_errors
|
||||
fi
|
||||
|
||||
echo -e "${Blue}Log result${Color_Off}"
|
||||
if (("${COUNT_WARNING}" > 0)); then
|
||||
if (("${COUNT_ERROR}" > 0)); then
|
||||
echo_count_warnings
|
||||
fi
|
||||
echo -e "${WARNING_MESSAGE}"
|
||||
fi
|
||||
|
||||
if (("${COUNT_ERROR}" > 0)); then
|
||||
if (("${COUNT_WARNING}" > 0)); then
|
||||
echo_count_errors
|
||||
fi
|
||||
echo -e "${ERROR_MESSAGE}"
|
||||
fi
|
||||
|
||||
echo -e "${Blue}End of check result${Color_Off}"
|
||||
607
script/test/run_parallel_test.py
Executable file
607
script/test/run_parallel_test.py
Executable file
|
|
@ -0,0 +1,607 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import asyncio
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
from typing import Tuple
|
||||
|
||||
from colorama import Fore
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
LOG_FILE = "./.venv/make_test.log"
|
||||
|
||||
|
||||
def get_config():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Run code generator test in parallel.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore_init_check_git",
|
||||
action="store_true",
|
||||
help="Will not stop or init check if contain git change.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
lst_ignore_warning = [
|
||||
"have the same label:",
|
||||
"odoo.addons.code_generator.extractor_module_file: Ignore next error about"
|
||||
" ALTER TABLE DROP CONSTRAINT.",
|
||||
]
|
||||
|
||||
lst_ignore_error = [
|
||||
"fetchmail_notify_error_to_sender",
|
||||
'odoo.sql_db: bad query: ALTER TABLE "db_backup" DROP CONSTRAINT'
|
||||
' "db_backup_db_backup_name_unique"',
|
||||
'ERROR: constraint "db_backup_db_backup_name_unique" of relation'
|
||||
' "db_backup" does not exist',
|
||||
'odoo.sql_db: bad query: ALTER TABLE "db_backup" DROP CONSTRAINT'
|
||||
' "db_backup_db_backup_days_to_keep_positive"',
|
||||
'ERROR: constraint "db_backup_db_backup_days_to_keep_positive" of relation'
|
||||
' "db_backup" does not exist',
|
||||
"odoo.addons.code_generator.extractor_module_file: Ignore next error about"
|
||||
" ALTER TABLE DROP CONSTRAINT.",
|
||||
]
|
||||
|
||||
|
||||
def extract_result(result, test_name, lst_error, lst_warning):
|
||||
lst_log = result[0].split("\n")
|
||||
for log_line in lst_log:
|
||||
is_ignore_error = False
|
||||
if "error" in log_line.lower():
|
||||
# Remove ignore error
|
||||
for ignore_error in lst_ignore_error:
|
||||
if ignore_error in log_line:
|
||||
is_ignore_error = True
|
||||
break
|
||||
if not is_ignore_error:
|
||||
lst_error.append(log_line)
|
||||
|
||||
is_ignore_warning = False
|
||||
if "warning" in log_line.lower():
|
||||
# Remove ignore warning
|
||||
for ignore_warning in lst_ignore_warning:
|
||||
if ignore_warning in log_line:
|
||||
is_ignore_warning = True
|
||||
break
|
||||
if not is_ignore_warning:
|
||||
lst_warning.append(log_line)
|
||||
if result[1]:
|
||||
lst_error.append(f"Return status error for test {test_name}")
|
||||
|
||||
|
||||
def check_result(task_list, tpl_result):
|
||||
lst_error = []
|
||||
lst_warning = []
|
||||
|
||||
for i, result in enumerate(tpl_result):
|
||||
extract_result(
|
||||
result, task_list[i].cr_code.co_name, lst_error, lst_warning
|
||||
)
|
||||
|
||||
if lst_warning:
|
||||
print(f"{Fore.YELLOW}{len(lst_warning)} WARNING{Fore.RESET}")
|
||||
i = 0
|
||||
for warning in lst_warning:
|
||||
i += 1
|
||||
print(f"[{i}]{warning}")
|
||||
|
||||
if lst_error:
|
||||
print(f"{Fore.RED}{len(lst_error)} ERROR{Fore.RESET}")
|
||||
i = 0
|
||||
for error in lst_error:
|
||||
i += 1
|
||||
print(f"[{i}]{error}")
|
||||
|
||||
if lst_error or lst_warning:
|
||||
str_result = (
|
||||
f"{Fore.RED}{len(lst_error)} ERROR"
|
||||
f" {Fore.YELLOW}{len(lst_warning)} WARNING"
|
||||
)
|
||||
else:
|
||||
str_result = f"{Fore.GREEN}SUCCESS 🍰"
|
||||
|
||||
print(f"{Fore.BLUE}Summary TEST {str_result}{Fore.RESET}")
|
||||
|
||||
|
||||
def print_log(lst_task, tpl_result):
|
||||
if len(lst_task) != len(tpl_result):
|
||||
_logger.error("Different length for log... What happen?")
|
||||
return
|
||||
with open(LOG_FILE, "w") as f:
|
||||
for i, task in enumerate(lst_task):
|
||||
result = tpl_result[i]
|
||||
status_str = "PASS" if not result[1] else "FAIL"
|
||||
f.write(
|
||||
f"\nTest execution {i + 1} - {status_str} -"
|
||||
f" {task.cr_code.co_name}\n\n"
|
||||
)
|
||||
if result[0]:
|
||||
f.write(result[0])
|
||||
f.write("\n")
|
||||
print(f"Log file {LOG_FILE}")
|
||||
|
||||
|
||||
async def run_command(*args, test_name=None):
|
||||
# Create subprocess
|
||||
start_time = time.time()
|
||||
cmd_str = " ".join(args)
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
# stdout must a pipe to be accessible as process.stdout
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
# Wait for the subprocess to finish
|
||||
stdout, stderr = await process.communicate()
|
||||
end_time = time.time()
|
||||
diff_sec = end_time - start_time
|
||||
# Return stdout + stderr, returncode
|
||||
str_out = "\n" + stdout.decode().strip() + "\n" if stdout else ""
|
||||
str_err = "\n" + stderr.decode().strip() + "\n" if stderr else ""
|
||||
status_str = "FAIL" if process.returncode else "PASS"
|
||||
if test_name:
|
||||
str_output_init = (
|
||||
f"\n\n{status_str} [{test_name}] [{diff_sec:.3f}s] Execute"
|
||||
f' "{cmd_str}"\n\n'
|
||||
)
|
||||
else:
|
||||
str_output_init = (
|
||||
f'\n\n{status_str} [{diff_sec:.3f}s] Execute "{cmd_str}"\n\n'
|
||||
)
|
||||
all_output = str_out + str_err
|
||||
print(str_output_init)
|
||||
if process.returncode:
|
||||
lst_error = []
|
||||
lst_warning = []
|
||||
extract_result(
|
||||
(all_output, process.returncode), test_name, lst_error, lst_warning
|
||||
)
|
||||
for error in lst_error:
|
||||
print(f"\t{error}")
|
||||
for warning in lst_warning:
|
||||
print(f"\t{warning}")
|
||||
return str_output_init + all_output, process.returncode
|
||||
|
||||
|
||||
async def test_exec(
|
||||
path_module_check: str,
|
||||
generated_module=None,
|
||||
tested_module=None,
|
||||
search_class_module=None,
|
||||
script_after_init_check=None,
|
||||
lst_init_module_name=None,
|
||||
test_name=None,
|
||||
install_path=None,
|
||||
) -> Tuple[str, int]:
|
||||
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
if install_path is None:
|
||||
install_path = path_module_check
|
||||
|
||||
# Check code, init module to install
|
||||
if lst_init_module_name:
|
||||
for module_name in lst_init_module_name:
|
||||
res, status = await run_command(
|
||||
"./script/code_generator/check_git_change_code_generator.sh",
|
||||
path_module_check,
|
||||
module_name,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
# Check code, module to generate
|
||||
if tested_module:
|
||||
res, status = await run_command(
|
||||
"./script/code_generator/check_git_change_code_generator.sh",
|
||||
path_module_check,
|
||||
tested_module,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
# Leave when detect anomaly in check before start
|
||||
if test_status:
|
||||
return test_result, test_status
|
||||
|
||||
# Execute script before start
|
||||
if script_after_init_check and not test_status:
|
||||
res, status = await run_command(script_after_init_check)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
is_db_create = False
|
||||
unique_database_name = f"test_demo_{uuid.uuid4()}"[:63]
|
||||
if not test_status:
|
||||
res, status = await run_command(
|
||||
"./script/db_restore.py",
|
||||
"--database",
|
||||
unique_database_name,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
is_db_create = not status
|
||||
|
||||
if not test_status and lst_init_module_name:
|
||||
# Parallel execution here
|
||||
|
||||
# No parallel execution here
|
||||
str_test = ",".join(lst_init_module_name)
|
||||
script_name = (
|
||||
"./script/addons/install_addons_dev.sh"
|
||||
if tested_module
|
||||
else "./script/addons/install_addons.sh"
|
||||
)
|
||||
res, status = await run_command(
|
||||
script_name,
|
||||
unique_database_name,
|
||||
str_test,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
if not test_status and search_class_module and generated_module:
|
||||
path_template_to_generate = os.path.join(
|
||||
path_module_check, tested_module
|
||||
)
|
||||
path_module_to_generate = os.path.join(
|
||||
path_module_check, search_class_module
|
||||
)
|
||||
# Parallel execution here
|
||||
|
||||
# No parallel execution here
|
||||
res, status = await run_command(
|
||||
"./script/code_generator/search_class_model.py",
|
||||
"--quiet",
|
||||
"-d",
|
||||
path_module_to_generate,
|
||||
"-t",
|
||||
path_template_to_generate,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
if not test_status and tested_module and generated_module:
|
||||
# Parallel execution here
|
||||
|
||||
# No parallel execution here
|
||||
res, status = await run_command(
|
||||
"./script/code_generator/install_and_test_code_generator.sh",
|
||||
unique_database_name,
|
||||
tested_module,
|
||||
install_path,
|
||||
generated_module,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
if is_db_create:
|
||||
res, status = await run_command(
|
||||
"./.venv/bin/python3",
|
||||
"./odoo/odoo-bin",
|
||||
"db",
|
||||
"--drop",
|
||||
"--database",
|
||||
unique_database_name,
|
||||
test_name=test_name,
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
def check_git_change():
|
||||
"""
|
||||
return True if success
|
||||
"""
|
||||
loop = asyncio.get_event_loop()
|
||||
task_list = [
|
||||
run_command(
|
||||
"./script/code_generator/check_git_change_code_generator.sh",
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
test_name="Init check_git_change",
|
||||
)
|
||||
]
|
||||
commands = asyncio.gather(*task_list)
|
||||
tpl_result = loop.run_until_complete(commands)
|
||||
status = any([a[1] for a in tpl_result])
|
||||
loop.close()
|
||||
return not status
|
||||
|
||||
|
||||
def print_summary_task(task_list):
|
||||
for task in task_list:
|
||||
print(task.cr_code.co_name)
|
||||
|
||||
|
||||
# START TEST
|
||||
|
||||
|
||||
async def run_demo_test() -> Tuple[str, int]:
|
||||
lst_test_name = [
|
||||
"demo_helpdesk_data",
|
||||
"demo_internal",
|
||||
"demo_internal_inherit",
|
||||
"demo_mariadb_sql_example_1",
|
||||
"demo_portal",
|
||||
"demo_website_data",
|
||||
"demo_website_leaflet",
|
||||
"demo_website_snippet",
|
||||
]
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
lst_init_module_name=lst_test_name,
|
||||
test_name="demo_test",
|
||||
)
|
||||
|
||||
return res, status
|
||||
|
||||
|
||||
async def run_mariadb_test() -> Tuple[str, int]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
# Migrator
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module="demo_mariadb_sql_example_1",
|
||||
tested_module="code_generator_migrator_demo_mariadb_sql_example_1",
|
||||
script_after_init_check=(
|
||||
"./script/database/restore_mariadb_sql_example_1.sh"
|
||||
),
|
||||
lst_init_module_name=[
|
||||
"code_generator_portal",
|
||||
],
|
||||
test_name="mariadb_test-migrator",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
# Template
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module="code_generator_demo_mariadb_sql_example_1",
|
||||
tested_module="code_generator_template_demo_mariadb_sql_example_1",
|
||||
search_class_module="demo_mariadb_sql_example_1",
|
||||
lst_init_module_name=[
|
||||
"code_generator_portal",
|
||||
"demo_mariadb_sql_example_1",
|
||||
],
|
||||
test_name="mariadb_test-template",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
# Code generator
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module="demo_mariadb_sql_example_1",
|
||||
lst_init_module_name=[
|
||||
"code_generator_portal",
|
||||
],
|
||||
tested_module="code_generator_demo_mariadb_sql_example_1",
|
||||
test_name="mariadb_test-code-generator",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_multiple_test() -> Tuple[str, int]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
lst_generated_module = [
|
||||
"code_generator_demo",
|
||||
"demo_helpdesk_data",
|
||||
"demo_website_data",
|
||||
"demo_internal",
|
||||
"demo_portal",
|
||||
"theme_website_demo_code_generator",
|
||||
"demo_website_leaflet",
|
||||
"demo_website_snippet",
|
||||
]
|
||||
lst_tested_module = [
|
||||
"code_generator_demo",
|
||||
"code_generator_demo_export_helpdesk",
|
||||
"code_generator_demo_export_website",
|
||||
"code_generator_demo_internal",
|
||||
"code_generator_demo_portal",
|
||||
"code_generator_demo_theme_website",
|
||||
"code_generator_demo_website_leaflet",
|
||||
"code_generator_demo_website_snippet",
|
||||
]
|
||||
# Multiple
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module=",".join(lst_generated_module),
|
||||
tested_module=",".join(lst_tested_module),
|
||||
test_name="code_generator_multiple_test",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_inherit_test() -> Tuple[str, int]:
|
||||
# TODO can be merge into code_generator_multiple
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
lst_generated_module = [
|
||||
"demo_internal_inherit",
|
||||
]
|
||||
lst_tested_module = [
|
||||
"code_generator_demo_internal_inherit",
|
||||
]
|
||||
# Inherit
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module=",".join(lst_generated_module),
|
||||
tested_module=",".join(lst_tested_module),
|
||||
test_name="code_generator_inherit_test",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_auto_backup_test() -> Tuple[str, int]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
lst_generated_module = [
|
||||
"auto_backup",
|
||||
]
|
||||
lst_tested_module = [
|
||||
"code_generator_auto_backup",
|
||||
]
|
||||
# Auto-backup
|
||||
res, status = await test_exec(
|
||||
"./addons/OCA_server-tools/auto_backup",
|
||||
generated_module=",".join(lst_generated_module),
|
||||
tested_module=",".join(lst_tested_module),
|
||||
test_name="code_generator_auto_backup_test",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_template_demo_portal_test() -> Tuple[str, int]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
# Template
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module="code_generator_demo_portal",
|
||||
tested_module="code_generator_template_demo_portal",
|
||||
# search_class_module="demo_mariadb_sql_example_1",
|
||||
lst_init_module_name=[
|
||||
"demo_portal",
|
||||
],
|
||||
test_name="code_generator_template_demo_portal",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_template_demo_internal_inherit_test() -> Tuple[
|
||||
str, int
|
||||
]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
# Template
|
||||
res, status = await test_exec(
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
generated_module="code_generator_demo_internal_inherit",
|
||||
tested_module="code_generator_template_demo_internal_inherit",
|
||||
# search_class_module="code_generator_demo_internal_inherit",
|
||||
lst_init_module_name=[
|
||||
"demo_internal_inherit",
|
||||
],
|
||||
test_name="code_generator_template_demo_internal_inherit",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_code_generator_template_demo_sysadmin_cron_test() -> Tuple[
|
||||
str, int
|
||||
]:
|
||||
test_result = ""
|
||||
test_status = 0
|
||||
# Template
|
||||
res, status = await test_exec(
|
||||
"./addons/OCA_server-tools/auto_backup",
|
||||
generated_module="code_generator_auto_backup",
|
||||
tested_module="code_generator_template_demo_sysadmin_cron",
|
||||
# search_class_module="code_generator_demo_internal_inherit",
|
||||
lst_init_module_name=[
|
||||
"auto_backup",
|
||||
],
|
||||
test_name="code_generator_template_demo_sysadmin_cron",
|
||||
install_path="./addons/TechnoLibre_odoo-code-generator-template",
|
||||
)
|
||||
test_result += res
|
||||
test_status += status
|
||||
|
||||
return test_result, test_status
|
||||
|
||||
|
||||
async def run_helloworld_test() -> Tuple[str, int]:
|
||||
res, status = await run_command(
|
||||
"./test/code_generator/hello_world.sh", test_name="helloworld_test"
|
||||
)
|
||||
|
||||
return res, status
|
||||
|
||||
|
||||
def run_all_test() -> None:
|
||||
task_list = []
|
||||
|
||||
task_list.append(run_demo_test())
|
||||
task_list.append(run_helloworld_test())
|
||||
task_list.append(run_mariadb_test())
|
||||
task_list.append(run_code_generator_multiple_test())
|
||||
task_list.append(run_code_generator_inherit_test())
|
||||
task_list.append(run_code_generator_auto_backup_test())
|
||||
task_list.append(run_code_generator_template_demo_portal_test())
|
||||
task_list.append(run_code_generator_template_demo_internal_inherit_test())
|
||||
task_list.append(run_code_generator_template_demo_sysadmin_cron_test())
|
||||
|
||||
print_summary_task(task_list)
|
||||
|
||||
if asyncio.get_event_loop().is_closed():
|
||||
asyncio.set_event_loop(asyncio.new_event_loop())
|
||||
loop = asyncio.get_event_loop()
|
||||
commands = asyncio.gather(*task_list)
|
||||
tpl_result = loop.run_until_complete(commands)
|
||||
loop.close()
|
||||
print_log(task_list, tpl_result)
|
||||
check_result(task_list, tpl_result)
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
start_time = time.time()
|
||||
if not config.ignore_init_check_git:
|
||||
success = check_git_change()
|
||||
else:
|
||||
success = True
|
||||
if success:
|
||||
run_all_test()
|
||||
end_time = time.time()
|
||||
diff_sec = end_time - start_time
|
||||
# print(f"Time execution {diff_sec:.3f}s")
|
||||
print(f"Time execution {datetime.timedelta(seconds=diff_sec)}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
20
script/version/change_python_version.sh
Executable file
20
script/version/change_python_version.sh
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# $1 new version version, like 3.7.12
|
||||
|
||||
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" ./docker/Dockerfile.base
|
||||
sed -i -e "s/$line/$1/g" ./docker/python-versions.txt
|
||||
sed -i -e "s/$line/$1/g" ./script/install_locally.sh
|
||||
sed -i -e "s/$line/$1/g" ./script/install_OSX_dependency.sh
|
||||
sed -i -e "s/$line/$1/g" ./pyproject.toml
|
||||
done < "$input"
|
||||
|
||||
while IFS= read -r line
|
||||
do
|
||||
echo -e "New version $line"
|
||||
done < "$input"
|
||||
|
|
@ -129,3 +129,5 @@ https://github.com/OCA/maintainer-tools.git,script,master,
|
|||
https://github.com/TechnoLibre/odoo-code-generator.git,addons,,
|
||||
https://github.com/TechnoLibre/odoo-code-generator-template.git,addons,,
|
||||
https://github.com/ERPLibre/ERPLibre_image_db.git,,,
|
||||
https://github.com/odoo/design-themes.git,addons,,
|
||||
https://github.com/novacode-nl/odoo-formio.git,addons,,
|
||||
|
|
|
|||
|
18
test/code_generator/hello_world.sh
Executable file
18
test/code_generator/hello_world.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
Color_Off='\033[0m' # Text Reset
|
||||
Red='\033[0;31m' # Red
|
||||
Green='\033[0;32m' # Green
|
||||
|
||||
tmp_dir=$(mktemp -d -t "erplibre_code_generator_helloworld-$(date +%Y-%m-%d-%H-%M-%S)-XXXXXXXXXX")
|
||||
|
||||
./script/code_generator/new_project.py -m test -d "${tmp_dir}"
|
||||
|
||||
MODULE_PATH="${tmp_dir}/test"
|
||||
if [[ -d "${MODULE_PATH}" ]]; then
|
||||
echo -e "${Green}SUCCESS${Color_Off} ${MODULE_PATH} exists."
|
||||
else
|
||||
echo -e "${Red}ERROR${Color_Off} ${MODULE_PATH} is missing."
|
||||
fi
|
||||
|
||||
rm -rf "${tmp_dir}"
|
||||
Loading…
Reference in a new issue