Merge pull request #33 from ERPLibre/makefile_test_and_code_generator
Makefile test and code generator
This commit is contained in:
commit
247c4e6bb9
64 changed files with 5511 additions and 1346 deletions
13
.flake8
Normal file
13
.flake8
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[flake8]
|
||||
max-line-length = 80
|
||||
max-complexity = 16
|
||||
# B = bugbear
|
||||
# B9 = bugbear opinionated (incl line length)
|
||||
select = C,E,F,W,B,B9
|
||||
# E203: whitespace before ':' (black behaviour)
|
||||
# E501: flake8 line length (covered by bugbear B950)
|
||||
# W503: line break before binary operator (black behaviour)
|
||||
ignore = E203,E501,W503
|
||||
exclude =
|
||||
./.git
|
||||
.eggs/
|
||||
35
CHANGELOG.md
35
CHANGELOG.md
|
|
@ -9,13 +9,42 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
|
||||
### Added
|
||||
|
||||
- Code generator for Odoo module
|
||||
- Adapt script to give an execution status
|
||||
- Multilingual markdown
|
||||
- Guide to use Cloudflare with DDNS
|
||||
- Script to check git diff and ignore date
|
||||
- Repo with ERPLibre image
|
||||
- Improve git repo usage, filter repo by use case
|
||||
|
||||
#### Makefile
|
||||
- Format code
|
||||
- Code generator test
|
||||
- Addons installation
|
||||
- OS installation
|
||||
- Restore database
|
||||
- Docker execution
|
||||
|
||||
#### Code generator
|
||||
- Code generator for Odoo module, depending of ERPLibre
|
||||
- Support map geoengine
|
||||
- Support i18n
|
||||
- Script to transform Python and XML to Python code writer script to regenerate themselves
|
||||
|
||||
### Changed
|
||||
|
||||
- Downgrade postgresql to 11 to support postgis
|
||||
- Travis CI
|
||||
- Update Python dependency with Poetry
|
||||
- Format all Python code with black
|
||||
|
||||
#### Docker
|
||||
|
||||
- Use buster python 3.7.7 image to remove pyenv
|
||||
- Update Postgresql to support Postgis
|
||||
- Support volume addons /ERPLibre/addons/addons
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ubuntu installation
|
||||
- Poetry installation
|
||||
|
||||
## [1.1.1] - 2020-12-11
|
||||
|
||||
|
|
|
|||
232
Makefile
232
Makefile
|
|
@ -46,11 +46,15 @@ run_test:
|
|||
.PHONY: run_code_generator
|
||||
run_code_generator:
|
||||
echo http://localhost:8069
|
||||
# -$(BROWSER) http://localhost:8069
|
||||
./run.sh --database code_generator
|
||||
|
||||
#############
|
||||
# INSTALL #
|
||||
#############
|
||||
.PHONY: install
|
||||
install:install_os install_dev
|
||||
|
||||
.PHONY: install_dev
|
||||
install_dev:
|
||||
./script/install_locally_dev.sh
|
||||
|
|
@ -87,86 +91,193 @@ db_version:
|
|||
db_drop_db_test:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database test
|
||||
|
||||
.PHONY: db_drop_db_test2
|
||||
db_drop_db_test2:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database test2
|
||||
|
||||
.PHONY: db_drop_db_test3
|
||||
db_drop_db_test3:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database test3
|
||||
|
||||
.PHONY: db_drop_db_code_generator
|
||||
db_drop_db_code_generator:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database code_generator
|
||||
|
||||
.PHONY: db_drop_db_template
|
||||
db_drop_db_template:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --drop --database template
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_test
|
||||
db_restore_erplibre_base_db_test:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --restore --restore_image erplibre_base --database 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
|
||||
./script/addons/install_addons.sh test test
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_test2
|
||||
db_restore_erplibre_base_db_test2:
|
||||
./script/db_restore.py --database test2
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_test3
|
||||
db_restore_erplibre_base_db_test3:
|
||||
./script/db_restore.py --database test3
|
||||
|
||||
.PHONY: db_restore_erplibre_website_db_test
|
||||
db_restore_erplibre_website_db_test:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --restore --restore_image erplibre_website --database test
|
||||
./script/db_restore.py --database test --image erplibre_website
|
||||
|
||||
.PHONY: db_restore_erplibre_website_chat_crm_db_test
|
||||
db_restore_erplibre_website_chat_crm_db_test:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --restore --restore_image erplibre_website_chat_crm --database test
|
||||
./script/db_restore.py --database test --image erplibre_website_chat_crm
|
||||
|
||||
.PHONY: db_restore_erplibre_ecommerce_base_db_test
|
||||
db_restore_erplibre_ecommerce_base_db_test:
|
||||
./script/db_restore.py --database test --image erplibre_ecommerce_base
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_code_generator
|
||||
db_restore_erplibre_base_db_code_generator:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin db --restore --restore_image erplibre_base --database code_generator
|
||||
./script/db_restore.py --database code_generator
|
||||
|
||||
.PHONY: db_restore_erplibre_base_db_template
|
||||
db_restore_erplibre_base_db_template:
|
||||
./script/db_restore.py --database template
|
||||
|
||||
#########################
|
||||
# Addons installation #
|
||||
#########################
|
||||
.PHONY: addons_install_code_generator_basic
|
||||
addons_install_code_generator_basic: 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
|
||||
./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
|
||||
./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
|
||||
addons_install_code_generator_demo:
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo -u code_generator_demo
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo
|
||||
|
||||
.PHONY: addons_uninstall_code_generator_demo
|
||||
addons_uninstall_code_generator_demo:
|
||||
./run.sh --no-http --stop-after-init -d code_generator --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
|
||||
|
||||
.PHONY: addons_install_code_generator_demo_portal
|
||||
addons_install_code_generator_demo_portal:
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_portal -u code_generator_demo_portal
|
||||
|
||||
.PHONY: addons_uninstall_code_generator_demo_portal
|
||||
addons_uninstall_code_generator_demo_portal:
|
||||
./run.sh --no-http --stop-after-init -d code_generator --uninstall code_generator_demo_portal
|
||||
./run.sh --no-http --stop-after-init -d code_generator --uninstall code_generator_demo
|
||||
|
||||
.PHONY: addons_reinstall_code_generator_demo_portal
|
||||
addons_reinstall_code_generator_demo_portal: addons_uninstall_code_generator_demo_portal addons_install_code_generator_demo_portal
|
||||
|
||||
.PHONY: addons_install_demo_portal_on_code_generator
|
||||
addons_install_demo_portal_on_code_generator:
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i demo_portal -u demo_portal
|
||||
|
||||
.PHONY: addons_uninstall_demo_portal_on_code_generator
|
||||
addons_uninstall_demo_portal_on_code_generator:
|
||||
./run.sh --no-http --stop-after-init -d code_generator --uninstall demo_portal
|
||||
|
||||
.PHONY: addons_reinstall_demo_portal_on_code_generator
|
||||
addons_reinstall_demo_portal_on_code_generator: addons_uninstall_demo_portal_on_code_generator addons_install_demo_portal_on_code_generator
|
||||
|
||||
.PHONY: addons_install_demo_portal_on_test
|
||||
addons_install_demo_portal_on_test:
|
||||
./run.sh --no-http --stop-after-init -d test -i demo_portal -u demo_portal
|
||||
|
||||
.PHONY: addons_uninstall_demo_portal_on_test
|
||||
addons_uninstall_demo_portal_on_test:
|
||||
./run.sh --no-http --stop-after-init -d test --uninstall demo_portal
|
||||
|
||||
.PHONY: addons_reinstall_demo_portal_on_test
|
||||
addons_reinstall_demo_portal_on_test: addons_uninstall_demo_portal_on_test addons_install_demo_portal_on_test
|
||||
|
||||
.PHONY: addons_install_all_code_generator_demo
|
||||
addons_install_all_code_generator_demo:
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo -u code_generator_demo
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_export_helpdesk -u code_generator_demo_export_helpdesk
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_internal -u code_generator_demo_internal
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_portal -u code_generator_demo_portal
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_theme_website -u code_generator_demo_theme_website
|
||||
./run.sh --no-http --stop-after-init -d code_generator -i code_generator_demo_website_leaflet -u code_generator_demo_website_leaflet
|
||||
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
|
||||
# ./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_portal
|
||||
# ./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_uninstall_all_code_generator_demo
|
||||
addons_uninstall_all_code_generator_demo:
|
||||
./run.sh --no-http --stop-after-init -d code_generator --uninstall 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
|
||||
.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
|
||||
|
||||
.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
|
||||
# TODO support installation theme with cli
|
||||
#./script/addons/install_addons_dev.sh template theme_website_demo_code_generator
|
||||
|
||||
.PHONY: addons_install_all_code_generator
|
||||
addons_install_all_code_generator:
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_auto_backup
|
||||
|
||||
##########
|
||||
# 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
|
||||
|
||||
.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_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
|
||||
|
||||
.PHONY: test_code_generator_code_i18n
|
||||
test_code_generator_code_i18n:
|
||||
./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
|
||||
|
||||
.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
|
||||
./script/code_generator/check_git_change_code_generator.sh ./addons/OCA_server-tools/auto_backup
|
||||
|
||||
##############
|
||||
# terminal #
|
||||
##############
|
||||
.PHONY: open_terminal
|
||||
open_terminal:
|
||||
./script/open_terminal_code_generator.sh
|
||||
|
||||
############
|
||||
# format #
|
||||
############
|
||||
.PHONY: format
|
||||
format: format_code_generator format_code_generator_template format_script
|
||||
|
||||
.PHONY: format_code_generator
|
||||
format_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:
|
||||
./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:
|
||||
./script/maintenance/black.sh ./script/
|
||||
|
||||
###########
|
||||
# clean #
|
||||
###########
|
||||
.PHONY: clean_code_generator_template
|
||||
clean_code_generator_template:
|
||||
./script/repo_revert_git_diff_date_from_code_generator.py
|
||||
|
||||
.PHONY: clean_test
|
||||
clean_test:
|
||||
cd addons/OCA_server-tools; git stash; git clean -fd
|
||||
|
||||
############
|
||||
# docker #
|
||||
|
|
@ -219,6 +330,11 @@ docker_clean_all:
|
|||
repo_clear_all:
|
||||
./script/clean_repo_manifest.sh
|
||||
|
||||
# configure all repo
|
||||
.PHONY: repo_configure_all
|
||||
repo_configure_all:
|
||||
./script/update_manifest_local_dev.sh
|
||||
|
||||
# configure only group code_generator
|
||||
.PHONY: repo_configure_group_code_generator
|
||||
repo_configure_group_code_generator:
|
||||
|
|
@ -251,9 +367,18 @@ config_gen_all:
|
|||
# generate config repo code_generator
|
||||
.PHONY: config_gen_code_generator
|
||||
config_gen_code_generator:
|
||||
./script/git_repo_update_group.py --group base,code_generator
|
||||
./script/git_repo_update_group.py --group base,code_generator
|
||||
./script/install_locally.sh
|
||||
|
||||
##########
|
||||
# I18n #
|
||||
##########
|
||||
|
||||
# i18n generation demo_portal
|
||||
.PHONY: i18n_generate_demo_portal
|
||||
i18n_generate_demo_portal:
|
||||
./.venv/bin/python3 ./odoo/odoo-bin i18n --database code_generator --module demo_portal --addons_path addons/TechnoLibre_odoo-code-generator
|
||||
|
||||
###################
|
||||
# Documentation #
|
||||
###################
|
||||
|
|
@ -304,3 +429,8 @@ doc_user:
|
|||
.PHONY: doc_clean_user
|
||||
doc_clean_user:
|
||||
make -C doc/odoo_documentation-user clean
|
||||
|
||||
# documentation markdown
|
||||
.PHONY: doc_markdown
|
||||
doc_markdown:
|
||||
./.venv/multilang_md.py $(shell pwd)/doc/CODE_GENERATOR.base.md
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -7,19 +7,18 @@ Clone the project
|
|||
git clone https://github.com/ERPLibre/ERPLibre.git
|
||||
cd ERPLibre
|
||||
```
|
||||
Support Ubuntu 18.04 and OSX
|
||||
Support Ubuntu 18.04, 20.04 and OSX. The installation duration is more than 30 minutes.
|
||||
```bash
|
||||
./script/install_dev.sh
|
||||
./script/install_locally_prod.sh
|
||||
make install
|
||||
```
|
||||
Update your configuration if you need to run somehere than 127.0.0.1, file `config.conf`
|
||||
Update your configuration if you need to run from another interface than 127.0.0.1, file `config.conf`
|
||||
```
|
||||
#xmlrpc_interface = 127.0.0.1
|
||||
#netrpc_interface = 127.0.0.1
|
||||
```
|
||||
Run
|
||||
Ready to execute
|
||||
```bash
|
||||
./run.sh
|
||||
make run
|
||||
```
|
||||
|
||||
## Discover guide
|
||||
|
|
@ -36,3 +35,9 @@ Run
|
|||
|
||||
# git-repo
|
||||
To change repository like addons, see [GIT_REPO.md](doc/GIT_REPO.md)
|
||||
|
||||
# Test
|
||||
Execute ERPLibre test with his code generator.
|
||||
```bash
|
||||
time make test
|
||||
```
|
||||
|
|
|
|||
932
doc/CODE_GENERATOR.base.md
Normal file
932
doc/CODE_GENERATOR.base.md
Normal file
|
|
@ -0,0 +1,932 @@
|
|||
<!---------------------------->
|
||||
<!-- multilingual suffix: en, fr -->
|
||||
<!-- no suffix: en -->
|
||||
<!---------------------------->
|
||||
|
||||
<!-- [en] -->
|
||||
# How to generate code
|
||||
|
||||
<!-- [fr] -->
|
||||
# Comment générer du code
|
||||
|
||||
<!-- [en] -->
|
||||
Never run this on production environment, this create circular dependencies and will cause frustration to clean damage.
|
||||
<!-- [fr] -->
|
||||
Ne jamais exécuter le générateur de code dans un environnement de production, il y a création de dépendance circulaire pouvant causer de la frustration à nettoyer tous les dommages. D'ailleurs, il est nécessaire d'exécuter en mode développement, avec l'argument `--dev all`.
|
||||
|
||||
L'objectif du générateur de code est de :
|
||||
- utilisation du générateur via l'interface web;
|
||||
- créer un nouveau module;
|
||||
- modifier un module existant;
|
||||
- exécuter les tests.
|
||||
|
||||
Ce générateur de code, pour ERPLibre, a tout avantage d'être sous licence AGPLv3 et nécessite d'être dans une communauté active de logiciels libres puisqu'il sera plus efficace d'accéder à du code pour l'auto-apprentissage. Le libre permet :
|
||||
- (Utiliser) L'utilisation de module sans restriction;
|
||||
- (Copier) Copier des modules pour faciliter leur maintenance et leur pérennité;
|
||||
- (Étudier) De comprendre le comportement des fonctionnalités;
|
||||
- (Modifier) Modifier un module existant pour l'améliorer et pouvoir le redistribuer à la communauté;
|
||||
<!-- [common] -->
|
||||
|
||||
```
|
||||
Modules
|
||||
############ ################## ##########
|
||||
# Template # -> # Code_Generator # -> # Module #
|
||||
############ ################## ##########
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
1. [A Template generates a Template or a Code_Generator.](#create-your-first-code_generator)
|
||||
2. A Code_Generator generates a Module.
|
||||
3. A Template reads a Module to generate a Code_Generator.
|
||||
|
||||
<!-- [fr] -->
|
||||
Il y a 3 types de module dans le contexte du générateur de code :
|
||||
1. [A Template generates a Template or a Code_Generator.](#crer-votre-premier-code_generator), le chef d'orchestre qui permet de gérer plusieurs générateur de code.
|
||||
2. Un Code_Generator génère un module, c'est un moule à module généré.
|
||||
3. Un Template lit un module pour générer un Code_Generator.
|
||||
|
||||
<!-- [en] -->
|
||||
Warning, be careful to your code, always commit after a manipulation, because the mode enable_sync_code erase data, only the git will save you!
|
||||
|
||||
<!-- [fr] -->
|
||||
Attention pour ne pas écraser votre code, toujours commiter après une manipulation, l'utilisation du mode enable_sync_code peut effacer des données. Seul git vous sauvera!
|
||||
|
||||
<!-- [en] -->
|
||||
## Manual generator with web interface
|
||||
|
||||
<!-- [fr] -->
|
||||
## Générateur de module avec l'interface web
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [ignore] -->
|
||||
At root path of ERPLibre git project, run:
|
||||
|
||||
<!-- [fr] -->
|
||||
Niveau intermédiaire.
|
||||
|
||||
Pour utiliser le générateur de code, il faut ouvrir l'interface web qui permet la configuration du logiciel à générer. Un des choix suivants :
|
||||
|
||||
Générateur de code de base :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [fr] -->
|
||||
Générateur de code avec fonctionnalités avancées :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_featured
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [fr] -->
|
||||
Générateur de code avec fonctionnalités complètes :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_full
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Ouvrir le navigateur sur [http://localhost:8069](http://localhost:8069). Utilisateur `test` et mot de passe `test`. Une fois connecté, ouvrir sur [http://localhost:8069/web?debug=](http://localhost:8069/web?debug=) pour activer le déverminage.
|
||||
|
||||
Ouvrir l'application `Code Generator` et créer un `Module`. Remplir les champs requis et générer avec `Action/Generate code`.
|
||||
|
||||
<!-- [en] -->
|
||||
### Create model-view module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module modèle avec vue
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_portal
|
||||
- code_generator_demo_portal
|
||||
- code_generator_demo_internal
|
||||
- demo_portal
|
||||
- demo_internal
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Application».
|
||||
- Sur l'onglet «Elements»/«Models», ajouter un modèle et sauvegarder.
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
### Create portal module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module avec la vue portail
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_portal
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_portal
|
||||
- code_generator_demo_portal
|
||||
- code_generator_demo_internal
|
||||
- demo_portal
|
||||
- demo_internal
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Application».
|
||||
- Sur l'onglet «Elements»/«Models», ajouter un modèle et sauvegarder.
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Désactiver «Enable all feature»
|
||||
- Dans l'onglet «Portal»
|
||||
- Activer «Enable portal feature»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Ajouter des données dans votre nouveau module «test».
|
||||
|
||||
Aller sur le portail pour visualiser les données, à l'adresse `/my`.
|
||||
|
||||
<!-- [en] -->
|
||||
### Create hook module for installation
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module crochet pour l'installation
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Le crochet nommé «hook» permet d'exécuter du code en
|
||||
- Pré-initialisation du module
|
||||
- Post-initialisation du module
|
||||
- Désinstallation du module
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_hook
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Hook»
|
||||
- Activer «Show post_init_hook»
|
||||
- Ajouter le code suivant dans la fenêtre qui est apparu :
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
print("Hello World")
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester et chercher dans la console "Hello World" :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
### Create cron module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module d'exécution de code sur une plage horaire
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Permettre d'exécuter du code basé sur des séquences de temps ou des moments spécifiques à répétition.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_sysadmin_cron
|
||||
- code_generator_auto_backup
|
||||
- auto_backup
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_cron
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Cron»
|
||||
- Ajouter un cron
|
||||
- Choisir le «Modèle» : «Contact»
|
||||
- Choisir unité de temps en «Minutes» dans «Exécuter tous les»
|
||||
- Modifier «Nombre d'appel» à -1 pour exécution sans arrêt.
|
||||
- Activer «Force nextcall» pour permettre que l'interval soit basé sur le moment d'installation du module
|
||||
- Ajouter le code :
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
log("Coucou")
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Avec les outils développeur, aller regarder les logs dans l'application «Configuration»/Technique/«Structure de base de donnée»/Historisation. Des informations dans le temps apparaîtront avec le mot «Coucou».
|
||||
|
||||
<!-- [en] -->
|
||||
### Create website snippet module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module de snippet pour le site web
|
||||
|
||||
<!-- [en] -->
|
||||
In progress
|
||||
|
||||
<!-- [fr] -->
|
||||
En progression, non terminé
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_snippet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_website_snippet
|
||||
- code_generator_demo_website_snippet
|
||||
- demo_website_snippet
|
||||
|
||||
Puis dans le repo addons/ERPLibre_erplibre_theme_addons, branche code_generator_erplibre_website_snippets
|
||||
- code_generator_erplibre_website_snippets
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
|
||||
TODO Incomplet
|
||||
|
||||
<!-- [en] -->
|
||||
### Create geoengine with Leaflet module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module de gestion de coordonnée géospatial avec Leaflet
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_leaflet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_website_leaflet
|
||||
- demo_website_leaflet
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data»
|
||||
- Activer «Application»
|
||||
- Ajouter la dépendance du geo_engine «Geospatial support for System»
|
||||
- Sur l'onglet «Elements»/«Models»
|
||||
- Ajouter un modèle «test»
|
||||
- Ajouter un champs de type «geo_». Le «geo_point» fonctionne bien. Si vous ajoutez plusieurs géométrie, tel que «geo_point», «geo_line» et «geo_polygon», il faut ajouter le champs «type» avec les valeurs du nom des champs choisis en option de sélection, exemple `[('geo_point', 'Geo Point'),('geo_polygon', 'Geo Polygon')]`
|
||||
- Ajouter le champs optionnel «html_text» de type «html» pour pouvoir afficher du texte dessus.
|
||||
- Appuyer sur le bouton «Controllers»
|
||||
- Ajouter le modèle du module actuel, «test»
|
||||
- Appuyer «Generate»
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Désactiver «Enable all feature»
|
||||
- Dans l'onglet «Website»
|
||||
- Activer «Enable website leaflet feature»
|
||||
- Activer «Enable geoengine feature»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Ajouter les permissions d'utilisation, dans l'application «Configuration», «Gérer les droits d'accès». Sur votre utilisateur, ajouter «Geoengine Admin».
|
||||
|
||||
Aller sur l'application «test», créer un «geo_point».
|
||||
|
||||
Aller sur la page du site web, ajouter le snippet «Leaflet». Chercher le point qui a été ajouté sur la carte du monde.
|
||||
|
||||
<!-- [en] -->
|
||||
### Create theme module for website
|
||||
|
||||
<!-- [fr] -->
|
||||
### Créer un module thème pour site web
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_theme_website
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_theme_website
|
||||
make run_code_generator
|
||||
```
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Website theme».
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Aller à l'onglet «theme_website»
|
||||
- Mettre les couleurs désirés
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Ce module doit être installé manuellement pour l'instant.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons.sh test website
|
||||
make run_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans l'interface web, Application «Configuration», «Paramètres Généraux»/«Site Web»/«Choisissez un thème». Installer le thème «TEST». Puis aller la page du site web, les couleurs sont dans «Personnaliser»/«Personnaliser le thème».
|
||||
|
||||
<!-- [en] -->
|
||||
### Extract data to module
|
||||
|
||||
<!-- [fr] -->
|
||||
### Extraire les données vers un module
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
L'exemple est avec le helpdesk. Installer le module helpdesk_mgmt :
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_export_helpdesk
|
||||
- code_generator_demo_export_website
|
||||
- demo_website_data
|
||||
- demo_helpdesk_data
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator helpdesk_mgmt
|
||||
make run_code_generator
|
||||
```
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Créer un ticket dans l'application «Helpdesk» dans l'interface web.
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Only export data».
|
||||
- Appuyer sur le bouton «Models»
|
||||
- Choisissez dans «Models» :
|
||||
- «helpdesk.ticket»
|
||||
- Activer «Clear field blacklisted»
|
||||
- Enlever les éléments suivant de «Fields» :
|
||||
- name
|
||||
- description
|
||||
- number
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
### Migrate external database into module of migration
|
||||
|
||||
<!-- [fr] -->
|
||||
### Migrer une base de donnée externe en module de migration
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
En progression.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- ??
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_db_servers
|
||||
make run_code_generator
|
||||
```
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller dans le module «Code generator», menu «Databases»/«Databases» et créer un connecteur vers une base de donnée.
|
||||
|
||||
À compléter...
|
||||
|
||||
<!-- [en] -->
|
||||
### Migrate from website to model with PDF data
|
||||
|
||||
<!-- [fr] -->
|
||||
### Migrer d'un site web vers un modèle de donnée avec des données format PDF
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
En progression, ce n'est pas encore supporté via l'interface web.
|
||||
|
||||
Cette technique permet d'aller lire du Javascript sur un site web pour lire ensuite le HTML, c'est à dire la vue, et en comprendre l'information pour créer un modèle.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_converter_js
|
||||
- business_plan_import_pdf
|
||||
|
||||
Attention, il faut mettre à jour les variables, dans les fichiers hook.py qui permettront d'extraire des données sur le site web à copier. Aucun exemple public n'est accessible pour le moment.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_converter_js
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test business_plan_import_pdf
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
## Prepare a DB
|
||||
|
||||
<!-- [fr] -->
|
||||
## Préparer une BD
|
||||
|
||||
<!-- [en] -->
|
||||
This will destroy and create database named `code_generator`.
|
||||
|
||||
<!-- [fr] -->
|
||||
Ceci va détruire et créer une base de donnée nommé `code_generator`.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour de meilleur performance d'exécution, réduire la quantité de «repo addons» permet d'accélérer l'installation, exécuter :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make config_gen_code_generator
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour revenir à la configuration normal, en production, exécuter :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make config_gen_all
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
## Create your first `Code_Generator`
|
||||
|
||||
<!-- [fr] -->
|
||||
## Créer votre premier `Code_Generator`
|
||||
|
||||
<!-- [en] -->
|
||||
Edit [Code Generator Demo](./../addons/TechnoLibre_odoo-code-generator/code_generator_demo/hooks.py) and update `# TODO HUMAN:`
|
||||
|
||||
<!-- [fr] -->
|
||||
Modifier [Code Generator Demo](./../addons/TechnoLibre_odoo-code-generator/code_generator_demo/hooks.py) et mettre à jour `# TODO HUMAN:`
|
||||
|
||||
<!-- [en] -->
|
||||
### Generate a `Template`
|
||||
|
||||
<!-- [fr] -->
|
||||
### Générer un `Template`
|
||||
|
||||
<!-- [en] -->
|
||||
By default, `code_generator_demo` generate itself, `code_generator_demo`.
|
||||
|
||||
Name your module begin with `MODULE_NAME = "code_generator_template_"`
|
||||
|
||||
The value "enable_template_code_generator_demo" at `False` to create a new template module, else this will recreate `code_generator_demo`.
|
||||
|
||||
<!-- [fr] -->
|
||||
Par défaut, installer le module code_generator_demo va générer le module `code_generator_demo`.
|
||||
|
||||
Nommer votre module en commençant par `MODULE_NAME = "code_generator_template_"`
|
||||
|
||||
<!-- [en] -->
|
||||
Example, to generate the module `code_generator_template_demo_website_snippet`, change value:
|
||||
|
||||
<!-- [fr] -->
|
||||
Un exemple, générer le module `code_generator_template_demo_website_snippet`, changer la variable `value`:
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
MODULE_NAME = "code_generator_template_demo_website_snippet"
|
||||
[...]
|
||||
value["enable_template_website_snippet_view"] = True
|
||||
[...]
|
||||
lst_depend = [
|
||||
"code_generator",
|
||||
"code_generator_website_snippet",
|
||||
]
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Generate new module, this will overwrite `code_generator_template_demo_website_snippet`:
|
||||
|
||||
<!-- [fr] -->
|
||||
Générer un nouveau module, ceci va écraser `code_generator_template_demo_website_snippet` :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
make addons_install_code_generator_demo
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
### Generate a Code_Generator (continue template)
|
||||
|
||||
<!-- [fr] -->
|
||||
### Générer un Code_Generator (suite de template)
|
||||
|
||||
<!-- [en] -->
|
||||
Name your module begin with `MODULE_NAME = "code_generator_"`
|
||||
|
||||
<!-- [fr] -->
|
||||
Au besoin, renommé votre module qui débute par `MODULE_NAME = "code_generator_"`
|
||||
|
||||
<!-- [en] -->
|
||||
Continue the example, you generated the template `code_generator_template_demo_website_snippet`, this will overwrite `code_generator_demo_website_snippet`:
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour continuer avec l'exemple, généré le template `code_generator_template_demo_website_snippet`, ceci va écraser `code_generator_demo_website_snippet`:
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Go to section [Create your first module](#create-your-first-module)
|
||||
|
||||
<!-- [fr] -->
|
||||
Aller à la section [Créer votre premier module](#crer-votre-premier-module)
|
||||
|
||||
<!-- [en] -->
|
||||
### Generate a Code_Generator_Demo
|
||||
|
||||
<!-- [fr] -->
|
||||
### Générer un Code_Generator_Demo
|
||||
|
||||
<!-- [ignore] -->
|
||||
TODO validate this
|
||||
|
||||
<!-- [en] -->
|
||||
Name your module begin with `MODULE_NAME = "code_generator_demo_"`
|
||||
|
||||
Disable `enable_template_code_generator_demo`
|
||||
|
||||
<!-- [fr] -->
|
||||
Nommé votre module qui débute par `MODULE_NAME = "code_generator_demo_"`
|
||||
|
||||
Désactiver la variable `enable_template_code_generator_demo`
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
value["enable_template_code_generator_demo"] = False
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Continue the example, you generated the template `code_generator_template_demo_website_snippet`, this will overwrite `code_generator_demo_website_snippet`:
|
||||
|
||||
<!-- [fr] -->
|
||||
Pour continuer avec l'exemple, généré le template `code_generator_template_demo_website_snippet`, ceci va écraser `code_generator_demo_website_snippet`:
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
## Create your first Module
|
||||
|
||||
<!-- [fr] -->
|
||||
## Créer votre premier module
|
||||
|
||||
<!-- [en] -->
|
||||
Continue example of code_generator_demo_website_snippet to generate your first module. Update next value:
|
||||
|
||||
<!-- [fr] -->
|
||||
Continuer avec l'exemple du `code_generator_demo_website_snippet` pour générer votre premier module. Mettre à jour les valeurs suivantes :
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
"application": True,
|
||||
"category_id": env.ref("base.module_category_website").id,
|
||||
[...]
|
||||
# Add dependencies
|
||||
lst_depend = [
|
||||
"website",
|
||||
]
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Generate your module:
|
||||
|
||||
<!-- [fr] -->
|
||||
Générer votre module :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Now, you can test it! Note, you cannot install a generated module with is code_generator associated, because duplicated
|
||||
models!
|
||||
|
||||
<!-- [fr] -->
|
||||
Maintenant, vous pouvez le tester! Pour info, on ne peut pas installer un module généré avec son générateur de code associé, puisqu'il y a une duplication des modèles!
|
||||
|
||||
<!-- [en] -->
|
||||
|
||||
<!-- [fr] -->
|
||||
Il est maintenant possible de modifier les paramètres via l'interface manuelle pour ce module, puis le regénérer en effaçant la BD. Ajouter un modèle et une vue.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
|
||||
<!-- [fr] -->
|
||||
Faire la boucle d'amélioration, commiter le code pour avoir une traçabilité des changements.
|
||||
|
||||
Ensuite, modifier la valeur `enable_sync_template` à `True`, `enable_template_wizard_view` à `True`, `template_model_name` avec un modèle existant, dans le fichier template, de l'exemple `code_generator_template_demo_website_snippet`.
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
value["enable_sync_template"] = True
|
||||
value["enable_template_wizard_view"] = True
|
||||
value["template_model_name"] = "test;test2"
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Exécuter l'installation du template pour qu'il se synchronise sur le module généré.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template demo_website_snippet
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
Ready to test, generate your module:
|
||||
|
||||
<!-- [fr] -->
|
||||
Prêt à tester, générer le module :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
# Optional, reset test database
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test demo_website_snippet
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
# How to generate i18n translation
|
||||
|
||||
<!-- [fr] -->
|
||||
# Comment générer les traductions i18n
|
||||
|
||||
<!-- [en] -->
|
||||
You need a template and a module. Be sure you have this line in template:
|
||||
|
||||
<!-- [fr] -->
|
||||
Vous avez besoin d'un template et d'un module. Soyez certain que vous avez cette ligne dans le template :
|
||||
|
||||
<!-- [common] -->
|
||||
```python
|
||||
new_module_path = os.path.join(path_module_generate, new_module_name)
|
||||
code_generator_writer.set_module_translator(new_module_name, new_module_path)
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
First, install the module, example `demo_portal`, and after the template, example `code_generator_template_demo_portal`.
|
||||
|
||||
<!-- [fr] -->
|
||||
Premièrement, installer le module, par exemple `demo_portal`, et ensuite le template, par exemple `code_generator_template_demo_portal`.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
# Sync Code_Generator fields from Module
|
||||
|
||||
<!-- [fr] -->
|
||||
# Synchroniser les champs du `Code_Generator` du module
|
||||
|
||||
<!-- [en] -->
|
||||
This reduce time of programming a `Code_Generator` with sync module field with `Template`.
|
||||
|
||||
You need a `Template`, a `Code_Generator` with his `Module`. Install the `Module` first in clean database and install `Template`,
|
||||
this will generate the `Code_Generator`, use `enable_sync_template` at True.
|
||||
|
||||
Example:
|
||||
|
||||
<!-- [fr] -->
|
||||
Ceci va permettre de réduire le temps de programmation d'un `Code_Generator` avec la synchronisation des champs de module avec `Template`.
|
||||
|
||||
On a besoin d'un `Template`, un `Code_Generator` accompagné de son module. Installer le module en premier dans une base de donnée nettoyé et installer le `Template`, ceci va générer le `Code_Generator`, utiliser `enable_sync_template` à la valeur `True`.
|
||||
|
||||
Exemple :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
# Test the code generator
|
||||
|
||||
<!-- [fr] -->
|
||||
# Tester le générateur de code
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Une bonne manière de tester un générateur de code est de valider qu'il génère le même code, il ne devient pas nécessaire de tester les fonctionnalités, puisque le comportement est la génération.
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Tester les générations simples :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make test_code_generator_generation
|
||||
```
|
||||
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Tester les générations extra :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make test_code_generator_generation_extra
|
||||
```
|
||||
<!-- [en] -->
|
||||
TODO
|
||||
|
||||
<!-- [fr] -->
|
||||
Tester les générations des templates :
|
||||
|
||||
<!-- [common] -->
|
||||
```bash
|
||||
make test_code_generator_template
|
||||
```
|
||||
556
doc/CODE_GENERATOR.fr.md
Normal file
556
doc/CODE_GENERATOR.fr.md
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
# Comment générer du code
|
||||
|
||||
Ne jamais exécuter le générateur de code dans un environnement de production, il y a création de dépendance circulaire pouvant causer de la frustration à nettoyer tous les dommages. D'ailleurs, il est nécessaire d'exécuter en mode développement, avec l'argument `--dev all`.
|
||||
|
||||
L'objectif du générateur de code est de :
|
||||
- utilisation du générateur via l'interface web;
|
||||
- créer un nouveau module;
|
||||
- modifier un module existant;
|
||||
- exécuter les tests.
|
||||
|
||||
Ce générateur de code, pour ERPLibre, a tout avantage d'être sous licence AGPLv3 et nécessite d'être dans une communauté active de logiciels libres puisqu'il sera plus efficace d'accéder à du code pour l'auto-apprentissage. Le libre permet :
|
||||
- (Utiliser) L'utilisation de module sans restriction;
|
||||
- (Copier) Copier des modules pour faciliter leur maintenance et leur pérennité;
|
||||
- (Étudier) De comprendre le comportement des fonctionnalités;
|
||||
- (Modifier) Modifier un module existant pour l'améliorer et pouvoir le redistribuer à la communauté;
|
||||
|
||||
```
|
||||
Modules
|
||||
############ ################## ##########
|
||||
# Template # -> # Code_Generator # -> # Module #
|
||||
############ ################## ##########
|
||||
```
|
||||
|
||||
Il y a 3 types de module dans le contexte du générateur de code :
|
||||
1. [A Template generates a Template or a Code_Generator.](#crer-votre-premier-code_generator), le chef d'orchestre qui permet de gérer plusieurs générateur de code.
|
||||
2. Un Code_Generator génère un module, c'est un moule à module généré.
|
||||
3. Un Template lit un module pour générer un Code_Generator.
|
||||
|
||||
Attention pour ne pas écraser votre code, toujours commiter après une manipulation, l'utilisation du mode enable_sync_code peut effacer des données. Seul git vous sauvera!
|
||||
|
||||
## Générateur de module avec l'interface web
|
||||
|
||||
Niveau intermédiaire.
|
||||
|
||||
Pour utiliser le générateur de code, il faut ouvrir l'interface web qui permet la configuration du logiciel à générer. Un des choix suivants :
|
||||
|
||||
Générateur de code de base :
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Générateur de code avec fonctionnalités avancées :
|
||||
```bash
|
||||
make addons_install_code_generator_featured
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Générateur de code avec fonctionnalités complètes :
|
||||
```bash
|
||||
make addons_install_code_generator_full
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Ouvrir le navigateur sur [http://localhost:8069](http://localhost:8069). Utilisateur `test` et mot de passe `test`. Une fois connecté, ouvrir sur [http://localhost:8069/web?debug=](http://localhost:8069/web?debug=) pour activer le déverminage.
|
||||
|
||||
Ouvrir l'application `Code Generator` et créer un `Module`. Remplir les champs requis et générer avec `Action/Generate code`.
|
||||
|
||||
### Créer un module modèle avec vue
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_portal
|
||||
- code_generator_demo_portal
|
||||
- code_generator_demo_internal
|
||||
- demo_portal
|
||||
- demo_internal
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Application».
|
||||
- Sur l'onglet «Elements»/«Models», ajouter un modèle et sauvegarder.
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
### Créer un module avec la vue portail
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_portal
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_portal
|
||||
- code_generator_demo_portal
|
||||
- code_generator_demo_internal
|
||||
- demo_portal
|
||||
- demo_internal
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Application».
|
||||
- Sur l'onglet «Elements»/«Models», ajouter un modèle et sauvegarder.
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Désactiver «Enable all feature»
|
||||
- Dans l'onglet «Portal»
|
||||
- Activer «Enable portal feature»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
Ajouter des données dans votre nouveau module «test».
|
||||
|
||||
Aller sur le portail pour visualiser les données, à l'adresse `/my`.
|
||||
|
||||
### Créer un module crochet pour l'installation
|
||||
|
||||
Le crochet nommé «hook» permet d'exécuter du code en
|
||||
- Pré-initialisation du module
|
||||
- Post-initialisation du module
|
||||
- Désinstallation du module
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_hook
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Hook»
|
||||
- Activer «Show post_init_hook»
|
||||
- Ajouter le code suivant dans la fenêtre qui est apparu :
|
||||
|
||||
```python
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
print("Hello World")
|
||||
```
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester et chercher dans la console "Hello World" :
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
### Créer un module d'exécution de code sur une plage horaire
|
||||
|
||||
Permettre d'exécuter du code basé sur des séquences de temps ou des moments spécifiques à répétition.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_sysadmin_cron
|
||||
- code_generator_auto_backup
|
||||
- auto_backup
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_cron
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Cron»
|
||||
- Ajouter un cron
|
||||
- Choisir le «Modèle» : «Contact»
|
||||
- Choisir unité de temps en «Minutes» dans «Exécuter tous les»
|
||||
- Modifier «Nombre d'appel» à -1 pour exécution sans arrêt.
|
||||
- Activer «Force nextcall» pour permettre que l'interval soit basé sur le moment d'installation du module
|
||||
- Ajouter le code :
|
||||
|
||||
```python
|
||||
log("Coucou")
|
||||
```
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester :
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
Avec les outils développeur, aller regarder les logs dans l'application «Configuration»/Technique/«Structure de base de donnée»/Historisation. Des informations dans le temps apparaîtront avec le mot «Coucou».
|
||||
|
||||
### Créer un module de snippet pour le site web
|
||||
|
||||
En progression, non terminé
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_snippet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_template_demo_website_snippet
|
||||
- code_generator_demo_website_snippet
|
||||
- demo_website_snippet
|
||||
|
||||
Puis dans le repo addons/ERPLibre_erplibre_theme_addons, branche code_generator_erplibre_website_snippets
|
||||
- code_generator_erplibre_website_snippets
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
|
||||
TODO Incomplet
|
||||
|
||||
### Créer un module de gestion de coordonnée géospatial avec Leaflet
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_leaflet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_website_leaflet
|
||||
- demo_website_leaflet
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data»
|
||||
- Activer «Application»
|
||||
- Ajouter la dépendance du geo_engine «Geospatial support for System»
|
||||
- Sur l'onglet «Elements»/«Models»
|
||||
- Ajouter un modèle «test»
|
||||
- Ajouter un champs de type «geo_». Le «geo_point» fonctionne bien. Si vous ajoutez plusieurs géométrie, tel que «geo_point», «geo_line» et «geo_polygon», il faut ajouter le champs «type» avec les valeurs du nom des champs choisis en option de sélection, exemple `[('geo_point', 'Geo Point'),('geo_polygon', 'Geo Polygon')]`
|
||||
- Ajouter le champs optionnel «html_text» de type «html» pour pouvoir afficher du texte dessus.
|
||||
- Appuyer sur le bouton «Controllers»
|
||||
- Ajouter le modèle du module actuel, «test»
|
||||
- Appuyer «Generate»
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Désactiver «Enable all feature»
|
||||
- Dans l'onglet «Website»
|
||||
- Activer «Enable website leaflet feature»
|
||||
- Activer «Enable geoengine feature»
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Tester sur :
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
Ajouter les permissions d'utilisation, dans l'application «Configuration», «Gérer les droits d'accès». Sur votre utilisateur, ajouter «Geoengine Admin».
|
||||
|
||||
Aller sur l'application «test», créer un «geo_point».
|
||||
|
||||
Aller sur la page du site web, ajouter le snippet «Leaflet». Chercher le point qui a été ajouté sur la carte du monde.
|
||||
|
||||
### Créer un module thème pour site web
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_theme_website
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_theme_website
|
||||
make run_code_generator
|
||||
```
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Website theme».
|
||||
- Appuyer sur le bouton «Views»
|
||||
- Aller à l'onglet «theme_website»
|
||||
- Mettre les couleurs désirés
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
|
||||
Ce module doit être installé manuellement pour l'instant.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons.sh test website
|
||||
make run_test
|
||||
```
|
||||
|
||||
Aller dans l'interface web, Application «Configuration», «Paramètres Généraux»/«Site Web»/«Choisissez un thème». Installer le thème «TEST». Puis aller la page du site web, les couleurs sont dans «Personnaliser»/«Personnaliser le thème».
|
||||
|
||||
### Extraire les données vers un module
|
||||
|
||||
L'exemple est avec le helpdesk. Installer le module helpdesk_mgmt :
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_export_helpdesk
|
||||
- code_generator_demo_export_website
|
||||
- demo_website_data
|
||||
- demo_helpdesk_data
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator helpdesk_mgmt
|
||||
make run_code_generator
|
||||
```
|
||||
Créer un ticket dans l'application «Helpdesk» dans l'interface web.
|
||||
|
||||
Aller dans le module «Code generator» et créer un module «test».
|
||||
- Sur l'onglet «Information», activer «Enable Sync Code»
|
||||
- Sur l'onglet «Technical Data», activer «Only export data».
|
||||
- Appuyer sur le bouton «Models»
|
||||
- Choisissez dans «Models» :
|
||||
- «helpdesk.ticket»
|
||||
- Activer «Clear field blacklisted»
|
||||
- Enlever les éléments suivant de «Fields» :
|
||||
- name
|
||||
- description
|
||||
- number
|
||||
- Appuyer «Generate»
|
||||
|
||||
Générer le module avec «Action/Générer code».
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
### Migrer une base de donnée externe en module de migration
|
||||
|
||||
En progression.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- ??
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_db_servers
|
||||
make run_code_generator
|
||||
```
|
||||
Aller dans le module «Code generator», menu «Databases»/«Databases» et créer un connecteur vers une base de donnée.
|
||||
|
||||
À compléter...
|
||||
|
||||
### Migrer d'un site web vers un modèle de donnée avec des données format PDF
|
||||
|
||||
En progression, ce n'est pas encore supporté via l'interface web.
|
||||
|
||||
Cette technique permet d'aller lire du Javascript sur un site web pour lire ensuite le HTML, c'est à dire la vue, et en comprendre l'information pour créer un modèle.
|
||||
|
||||
Pour des références techniques, voir module :
|
||||
- code_generator_demo_converter_js
|
||||
- business_plan_import_pdf
|
||||
|
||||
Attention, il faut mettre à jour les variables, dans les fichiers hook.py qui permettront d'extraire des données sur le site web à copier. Aucun exemple public n'est accessible pour le moment.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_converter_js
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test business_plan_import_pdf
|
||||
```
|
||||
|
||||
## Préparer une BD
|
||||
|
||||
Ceci va détruire et créer une base de donnée nommé `code_generator`.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
```
|
||||
|
||||
Pour de meilleur performance d'exécution, réduire la quantité de «repo addons» permet d'accélérer l'installation, exécuter :
|
||||
|
||||
```bash
|
||||
make config_gen_code_generator
|
||||
```
|
||||
|
||||
Pour revenir à la configuration normal, en production, exécuter :
|
||||
|
||||
```bash
|
||||
make config_gen_all
|
||||
```
|
||||
|
||||
## Créer votre premier `Code_Generator`
|
||||
|
||||
Modifier [Code Generator Demo](./../addons/TechnoLibre_odoo-code-generator/code_generator_demo/hooks.py) et mettre à jour `# TODO HUMAN:`
|
||||
|
||||
### Générer un `Template`
|
||||
|
||||
Par défaut, installer le module code_generator_demo va générer le module `code_generator_demo`.
|
||||
|
||||
Nommer votre module en commençant par `MODULE_NAME = "code_generator_template_"`
|
||||
|
||||
Un exemple, générer le module `code_generator_template_demo_website_snippet`, changer la variable `value`:
|
||||
|
||||
```python
|
||||
MODULE_NAME = "code_generator_template_demo_website_snippet"
|
||||
[...]
|
||||
value["enable_template_website_snippet_view"] = True
|
||||
[...]
|
||||
lst_depend = [
|
||||
"code_generator",
|
||||
"code_generator_website_snippet",
|
||||
]
|
||||
```
|
||||
|
||||
Générer un nouveau module, ceci va écraser `code_generator_template_demo_website_snippet` :
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
make addons_install_code_generator_demo
|
||||
```
|
||||
|
||||
### Générer un Code_Generator (suite de template)
|
||||
|
||||
Au besoin, renommé votre module qui débute par `MODULE_NAME = "code_generator_"`
|
||||
|
||||
Pour continuer avec l'exemple, généré le template `code_generator_template_demo_website_snippet`, ceci va écraser `code_generator_demo_website_snippet`:
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
Aller à la section [Créer votre premier module](#crer-votre-premier-module)
|
||||
|
||||
### Générer un Code_Generator_Demo
|
||||
|
||||
Nommé votre module qui débute par `MODULE_NAME = "code_generator_demo_"`
|
||||
|
||||
Désactiver la variable `enable_template_code_generator_demo`
|
||||
|
||||
```python
|
||||
value["enable_template_code_generator_demo"] = False
|
||||
```
|
||||
|
||||
Pour continuer avec l'exemple, généré le template `code_generator_template_demo_website_snippet`, ceci va écraser `code_generator_demo_website_snippet`:
|
||||
|
||||
```bash
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
## Créer votre premier module
|
||||
|
||||
Continuer avec l'exemple du `code_generator_demo_website_snippet` pour générer votre premier module. Mettre à jour les valeurs suivantes :
|
||||
|
||||
```python
|
||||
"application": True,
|
||||
"category_id": env.ref("base.module_category_website").id,
|
||||
[...]
|
||||
# Add dependencies
|
||||
lst_depend = [
|
||||
"website",
|
||||
]
|
||||
```
|
||||
|
||||
Générer votre module :
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
Maintenant, vous pouvez le tester! Pour info, on ne peut pas installer un module généré avec son générateur de code associé, puisqu'il y a une duplication des modèles!
|
||||
|
||||
Il est maintenant possible de modifier les paramètres via l'interface manuelle pour ce module, puis le regénérer en effaçant la BD. Ajouter un modèle et une vue.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
Faire la boucle d'amélioration, commiter le code pour avoir une traçabilité des changements.
|
||||
|
||||
Ensuite, modifier la valeur `enable_sync_template` à `True`, `enable_template_wizard_view` à `True`, `template_model_name` avec un modèle existant, dans le fichier template, de l'exemple `code_generator_template_demo_website_snippet`.
|
||||
|
||||
```python
|
||||
value["enable_sync_template"] = True
|
||||
value["enable_template_wizard_view"] = True
|
||||
value["template_model_name"] = "test;test2"
|
||||
```
|
||||
|
||||
Exécuter l'installation du template pour qu'il se synchronise sur le module généré.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template demo_website_snippet
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
Prêt à tester, générer le module :
|
||||
|
||||
```bash
|
||||
# Optional, reset test database
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test demo_website_snippet
|
||||
```
|
||||
|
||||
# Comment générer les traductions i18n
|
||||
|
||||
Vous avez besoin d'un template et d'un module. Soyez certain que vous avez cette ligne dans le template :
|
||||
|
||||
```python
|
||||
new_module_path = os.path.join(path_module_generate, new_module_name)
|
||||
code_generator_writer.set_module_translator(new_module_name, new_module_path)
|
||||
```
|
||||
|
||||
Premièrement, installer le module, par exemple `demo_portal`, et ensuite le template, par exemple `code_generator_template_demo_portal`.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
# Synchroniser les champs du `Code_Generator` du module
|
||||
|
||||
Ceci va permettre de réduire le temps de programmation d'un `Code_Generator` avec la synchronisation des champs de module avec `Template`.
|
||||
|
||||
On a besoin d'un `Template`, un `Code_Generator` accompagné de son module. Installer le module en premier dans une base de donnée nettoyé et installer le `Template`, ceci va générer le `Code_Generator`, utiliser `enable_sync_template` à la valeur `True`.
|
||||
|
||||
Exemple :
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
# Tester le générateur de code
|
||||
|
||||
Une bonne manière de tester un générateur de code est de valider qu'il génère le même code, il ne devient pas nécessaire de tester les fonctionnalités, puisque le comportement est la génération.
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Tester les générations simples :
|
||||
|
||||
```bash
|
||||
make test_code_generator_generation
|
||||
```
|
||||
|
||||
Tester les générations extra :
|
||||
|
||||
```bash
|
||||
make test_code_generator_generation_extra
|
||||
```
|
||||
Tester les générations des templates :
|
||||
|
||||
```bash
|
||||
make test_code_generator_template
|
||||
```
|
||||
403
doc/CODE_GENERATOR.md
Normal file
403
doc/CODE_GENERATOR.md
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
# How to generate code
|
||||
|
||||
Never run this on production environment, this create circular dependencies and will cause frustration to clean damage.
|
||||
|
||||
```
|
||||
Modules
|
||||
############ ################## ##########
|
||||
# Template # -> # Code_Generator # -> # Module #
|
||||
############ ################## ##########
|
||||
```
|
||||
|
||||
1. [A Template generates a Template or a Code_Generator.](#create-your-first-code_generator)
|
||||
2. A Code_Generator generates a Module.
|
||||
3. A Template reads a Module to generate a Code_Generator.
|
||||
|
||||
Warning, be careful to your code, always commit after a manipulation, because the mode enable_sync_code erase data, only the git will save you!
|
||||
|
||||
## Manual generator with web interface
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_featured
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_full
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
Ouvrir le navigateur sur [http://localhost:8069](http://localhost:8069). Utilisateur `test` et mot de passe `test`. Une fois connecté, ouvrir sur [http://localhost:8069/web?debug=](http://localhost:8069/web?debug=) pour activer le déverminage.
|
||||
|
||||
Ouvrir l'application `Code Generator` et créer un `Module`. Remplir les champs requis et générer avec `Action/Generate code`.
|
||||
|
||||
### Create model-view module
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
### Create portal module
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_portal
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
### Create hook module for installation
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_hook
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```python
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
print("Hello World")
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
### Create cron module
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_cron
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```python
|
||||
log("Coucou")
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
### Create website snippet module
|
||||
|
||||
In progress
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_snippet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
TODO
|
||||
|
||||
### Create geoengine with Leaflet module
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_website_leaflet
|
||||
make run_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
make run_test
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
### Create theme module for website
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_theme_website
|
||||
make run_code_generator
|
||||
```
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons.sh test website
|
||||
make run_test
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
### Extract data to module
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator helpdesk_mgmt
|
||||
make run_code_generator
|
||||
```
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_test_module_test
|
||||
```
|
||||
|
||||
### Migrate external database into module of migration
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make addons_install_code_generator_basic
|
||||
./script/addons/install_addons.sh code_generator code_generator_db_servers
|
||||
make run_code_generator
|
||||
```
|
||||
TODO
|
||||
|
||||
### Migrate from website to model with PDF data
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_converter_js
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test business_plan_import_pdf
|
||||
```
|
||||
|
||||
## Prepare a DB
|
||||
|
||||
This will destroy and create database named `code_generator`.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make config_gen_code_generator
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make config_gen_all
|
||||
```
|
||||
|
||||
## Create your first `Code_Generator`
|
||||
|
||||
Edit [Code Generator Demo](./../addons/TechnoLibre_odoo-code-generator/code_generator_demo/hooks.py) and update `# TODO HUMAN:`
|
||||
|
||||
### Generate a `Template`
|
||||
|
||||
By default, `code_generator_demo` generate itself, `code_generator_demo`.
|
||||
|
||||
Name your module begin with `MODULE_NAME = "code_generator_template_"`
|
||||
|
||||
The value "enable_template_code_generator_demo" at `False` to create a new template module, else this will recreate `code_generator_demo`.
|
||||
|
||||
Example, to generate the module `code_generator_template_demo_website_snippet`, change value:
|
||||
|
||||
```python
|
||||
MODULE_NAME = "code_generator_template_demo_website_snippet"
|
||||
[...]
|
||||
value["enable_template_website_snippet_view"] = True
|
||||
[...]
|
||||
lst_depend = [
|
||||
"code_generator",
|
||||
"code_generator_website_snippet",
|
||||
]
|
||||
```
|
||||
|
||||
Generate new module, this will overwrite `code_generator_template_demo_website_snippet`:
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
make addons_install_code_generator_demo
|
||||
```
|
||||
|
||||
### Generate a Code_Generator (continue template)
|
||||
|
||||
Name your module begin with `MODULE_NAME = "code_generator_"`
|
||||
|
||||
Continue the example, you generated the template `code_generator_template_demo_website_snippet`, this will overwrite `code_generator_demo_website_snippet`:
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
Go to section [Create your first module](#create-your-first-module)
|
||||
|
||||
### Generate a Code_Generator_Demo
|
||||
|
||||
Name your module begin with `MODULE_NAME = "code_generator_demo_"`
|
||||
|
||||
Disable `enable_template_code_generator_demo`
|
||||
|
||||
```python
|
||||
value["enable_template_code_generator_demo"] = False
|
||||
```
|
||||
|
||||
Continue the example, you generated the template `code_generator_template_demo_website_snippet`, this will overwrite `code_generator_demo_website_snippet`:
|
||||
|
||||
```bash
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
## Create your first Module
|
||||
|
||||
Continue example of code_generator_demo_website_snippet to generate your first module. Update next value:
|
||||
|
||||
```python
|
||||
"application": True,
|
||||
"category_id": env.ref("base.module_category_website").id,
|
||||
[...]
|
||||
# Add dependencies
|
||||
lst_depend = [
|
||||
"website",
|
||||
]
|
||||
```
|
||||
|
||||
Generate your module:
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
Now, you can test it! Note, you cannot install a generated module with is code_generator associated, because duplicated
|
||||
models!
|
||||
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh code_generator code_generator_demo_website_snippet
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
value["enable_sync_template"] = True
|
||||
value["enable_template_wizard_view"] = True
|
||||
value["template_model_name"] = "test;test2"
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_template
|
||||
./script/addons/install_addons_dev.sh template demo_website_snippet
|
||||
./script/addons/install_addons_dev.sh template code_generator_template_demo_website_snippet
|
||||
```
|
||||
|
||||
Ready to test, generate your module:
|
||||
|
||||
```bash
|
||||
# Optional, reset test database
|
||||
make db_restore_erplibre_base_db_test
|
||||
./script/addons/install_addons_dev.sh test demo_website_snippet
|
||||
```
|
||||
|
||||
# How to generate i18n translation
|
||||
|
||||
You need a template and a module. Be sure you have this line in template:
|
||||
|
||||
```python
|
||||
new_module_path = os.path.join(path_module_generate, new_module_name)
|
||||
code_generator_writer.set_module_translator(new_module_name, new_module_path)
|
||||
```
|
||||
|
||||
First, install the module, example `demo_portal`, and after the template, example `code_generator_template_demo_portal`.
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
# Sync Code_Generator fields from Module
|
||||
|
||||
This reduce time of programming a `Code_Generator` with sync module field with `Template`.
|
||||
|
||||
You need a `Template`, a `Code_Generator` with his `Module`. Install the `Module` first in clean database and install `Template`,
|
||||
this will generate the `Code_Generator`, use `enable_sync_template` at True.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
make db_restore_erplibre_base_db_code_generator
|
||||
./script/addons/install_addons_dev.sh test demo_portal
|
||||
./script/addons/install_addons_dev.sh test code_generator_template_demo_portal
|
||||
```
|
||||
|
||||
# Test the code generator
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make test_code_generator_generation
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make test_code_generator_generation_extra
|
||||
```
|
||||
TODO
|
||||
|
||||
```bash
|
||||
make test_code_generator_template
|
||||
```
|
||||
|
|
@ -139,3 +139,27 @@ Use this commit format:
|
|||
```bash
|
||||
git commit -am "[#ticket] subject: short sentence"
|
||||
```
|
||||
|
||||
# Format code
|
||||
## Python
|
||||
Use [black](https://github.com/psf/black)
|
||||
```bash
|
||||
./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator
|
||||
```
|
||||
|
||||
Or if you prefer [oca-autopep8](https://github.com/psf/black)
|
||||
```bash
|
||||
./script/maintenance/autopep8.sh ./addons/TechnoLibre_odoo-code-generator
|
||||
```
|
||||
|
||||
## HTML and css
|
||||
Use [prettier](https://github.com/prettier/prettier)
|
||||
```bash
|
||||
./script/maintenance/prettier.sh ./addons/TechnoLibre_odoo-code-generator
|
||||
```
|
||||
|
||||
## Javascript
|
||||
Use [prettier](https://github.com/prettier/prettier)
|
||||
```bash
|
||||
./script/maintenance/prettier.sh --tab-width 4 ./addons/TechnoLibre_odoo-code-generator
|
||||
```
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ Add your dependencies in file [requirements.txt](../requirements.txt) and run sc
|
|||
```
|
||||
This will search all `requirements.txt` files and update `pyproject.toml` and it will update poetry
|
||||
|
||||
Priority dependencies in ./requirements.txt, after it's ./odoo/requirements.txt, after it's highest version values.
|
||||
|
||||
TODO add option to only add missing dependencies and ignore update.
|
||||
|
||||
## Add manually dependencies
|
||||
|
|
|
|||
|
|
@ -62,9 +62,10 @@ cd /[EL_USER]/erplibre
|
|||
|
||||
## Move prod database to dev
|
||||
When moving prod database to your dev environment, you want to remove email servers and install user test to test the database.
|
||||
Warning, this is not safe for production, you expose all data.
|
||||
Run:
|
||||
```bash
|
||||
./run.sh --stop-after-init -i user_test,disable_mail_server --dev all -d DATABASE
|
||||
./script/migrate_prod_to_test.sh DATABASE
|
||||
```
|
||||
|
||||
## Update production
|
||||
|
|
@ -85,3 +86,28 @@ Caution, this delete user's home, it's irrevocable.
|
|||
```bash
|
||||
./script/delete_production.sh
|
||||
```
|
||||
|
||||
# Update ip when public ip change with CloudFlare and crontab
|
||||
|
||||
```bash
|
||||
mkdir ~/.cloudflare
|
||||
```
|
||||
|
||||
Edit ~/.cloudflare/cloudflare.cfg
|
||||
```
|
||||
[PROFILE_NAME]
|
||||
email=EMAIL
|
||||
token=TOKEN
|
||||
```
|
||||
|
||||
Add your cron
|
||||
```bash
|
||||
vim /etc/crontab
|
||||
# Add
|
||||
*/5 * * * * USER cd PATH && ./script/deployment/update_dns_cloudflare.py --profile PROFILE_NAME --zone_name CLOUDFLARE_ZONE_NAME --dns_name DNS_NAME --auto_sync
|
||||
```
|
||||
|
||||
Check log with
|
||||
```bash
|
||||
sudo journalctl -feu cron
|
||||
```
|
||||
|
|
@ -80,7 +80,7 @@ When building your docker with script
|
|||
> ./script/docker_build.sh --release
|
||||
|
||||
List your docker version
|
||||
> docker image
|
||||
> docker images
|
||||
|
||||
You need to push your docker image and update your tag, like 1.0.1:
|
||||
> docker push technolibre/erplibre:VERSION
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ RUN apt-get update \
|
|||
fonts-noto-cjk \
|
||||
gnupg \
|
||||
libssl-dev \
|
||||
node-less \
|
||||
node-less \
|
||||
npm \
|
||||
python3-num2words \
|
||||
python3-pip \
|
||||
|
|
@ -38,6 +38,8 @@ RUN apt-get update \
|
|||
&& apt-get install -y --no-install-recommends ./wkhtmltox.deb \
|
||||
&& rm -rf /var/lib/apt/lists/* wkhtmltox.deb
|
||||
|
||||
RUN npm i prettier
|
||||
|
||||
# install latest postgresql-client
|
||||
RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' > /etc/apt/sources.list.d/pgdg.list \
|
||||
&& GNUPGHOME="$(mktemp -d)" \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM debian:buster-slim
|
||||
FROM python:3.7.7-slim-buster
|
||||
MAINTAINER TechnoLibre <docker@technolibre.ca>
|
||||
|
||||
SHELL ["/bin/bash", "-xo", "pipefail", "-c"]
|
||||
|
|
@ -25,29 +25,19 @@ RUN apt-get update \
|
|||
gnupg \
|
||||
libssl-dev \
|
||||
npm \
|
||||
python3-num2words \
|
||||
python3-pip \
|
||||
python3-phonenumbers \
|
||||
python3-pyldap \
|
||||
python3-qrcode \
|
||||
python3-renderpm \
|
||||
python3-setuptools \
|
||||
python3-slugify \
|
||||
python3-vobject \
|
||||
python3-watchdog \
|
||||
python3-xlrd \
|
||||
python3-xlwt \
|
||||
python3-babel \
|
||||
python3-psycopg2 \
|
||||
xz-utils \
|
||||
git \
|
||||
wget \
|
||||
make \
|
||||
libssl-dev \
|
||||
zlib1g-dev \
|
||||
llvm \
|
||||
tk-dev \
|
||||
libxslt-dev \
|
||||
libzip-dev \
|
||||
libldap2-dev \
|
||||
libsasl2-dev \
|
||||
gdebi-core \
|
||||
libffi-dev \
|
||||
iproute2 \
|
||||
libmariadbd-dev \
|
||||
inetutils-ping \
|
||||
|
|
@ -85,21 +75,21 @@ RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' > /etc/
|
|||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install npm dependencies
|
||||
RUN npm install -g rtlcss less \
|
||||
RUN npm install -g rtlcss less prettier @prettier/plugin-xml \
|
||||
&& ln -fs /usr/local/bin/lessc /usr/bin/lessc
|
||||
|
||||
# Install python with pyenv
|
||||
# Reference https://github.com/bopen/docker-ubuntu-pyenv
|
||||
COPY pyenv-version.txt python-versions.txt /
|
||||
#COPY pyenv-version.txt python-versions.txt /
|
||||
|
||||
RUN git clone -b `cat /pyenv-version.txt` --single-branch --depth 1 https://github.com/pyenv/pyenv.git $PYENV_ROOT \
|
||||
&& for version in `cat /python-versions.txt`; do pyenv install $version; done \
|
||||
&& pyenv global `cat /python-versions.txt` \
|
||||
&& find $PYENV_ROOT/versions -type d '(' -name '__pycache__' -o -name 'test' -o -name 'tests' ')' -exec rm -rf '{}' + \
|
||||
&& find $PYENV_ROOT/versions -type f '(' -name '*.pyo' -o -name '*.exe' ')' -exec rm -f '{}' + \
|
||||
&& rm -rf /tmp/* \
|
||||
&& python --version \
|
||||
&& python3 --version
|
||||
#RUN git clone -b `cat /pyenv-version.txt` --single-branch --depth 1 https://github.com/pyenv/pyenv.git $PYENV_ROOT \
|
||||
# && for version in `cat /python-versions.txt`; do pyenv install $version; done \
|
||||
# && pyenv global `cat /python-versions.txt` \
|
||||
# && find $PYENV_ROOT/versions -type d '(' -name '__pycache__' -o -name 'test' -o -name 'tests' ')' -exec rm -rf '{}' + \
|
||||
# && find $PYENV_ROOT/versions -type f '(' -name '*.pyo' -o -name '*.exe' ')' -exec rm -f '{}' + \
|
||||
# && rm -rf /tmp/* \
|
||||
# && python --version \
|
||||
# && python3 --version
|
||||
|
||||
# Install git-repo
|
||||
RUN cd ; mkdir -p .bin/ && \
|
||||
|
|
@ -112,11 +102,6 @@ RUN cd ; mkdir -p .bin/ && \
|
|||
RUN groupadd --gid 101 --force odoo && \
|
||||
useradd --non-unique --create-home --uid 101 --gid 101 odoo
|
||||
|
||||
# TODO delete poetry installation
|
||||
# Install Poetry
|
||||
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - -y --preview --version 1.0.10
|
||||
#curl -fsS -o get-poetry.py https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py
|
||||
|
||||
# Copy entrypoint script and Odoo configuration file
|
||||
COPY ./entrypoint.sh /
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
|
|
|||
|
|
@ -34,9 +34,22 @@ RUN cd $ODOO_PREFIX && \
|
|||
RUN cd $ODOO_PREFIX && \
|
||||
./script/update_manifest_dev.sh
|
||||
|
||||
# TODO delete poetry installation
|
||||
# Install Poetry
|
||||
RUN cd $ODOO_PREFIX && \
|
||||
source /root/.poetry/env && \
|
||||
poetry install
|
||||
curl -sSL -o get-poetry.py https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py && \
|
||||
./.venv/bin/python get-poetry.py -y --preview --version 1.0.10
|
||||
|
||||
RUN cd $ODOO_PREFIX && \
|
||||
./.venv/bin/pip install --upgrade pip && \
|
||||
./.venv/bin/python ~/.poetry/bin/poetry install && \
|
||||
rm -rf artifacts
|
||||
|
||||
RUN cd $ODOO_PREFIX/.venv && \
|
||||
curl https://raw.githubusercontent.com/ERPLibre/multilingual-markdown/master/multilang_md.py > ./multilang_md.py && \
|
||||
chmod +x ./multilang_md.py && \
|
||||
sed -i 1d ./multilang_md.py && \
|
||||
sed -i "1 i #!./.venv/bin/python" ./multilang_md.py
|
||||
|
||||
RUN cd $ODOO_PREFIX && \
|
||||
head /etc/odoo/odoo.conf && \
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ addonsDirs = [abspath(join(addonsBaseDir, f)) for f in listdir(addonsBaseDir) if
|
|||
|
||||
# addonsDirs.insert(0, "/usr/lib/python3/dist-packages/odoo/addons/")
|
||||
# TODO path addons/addons is not exist in docker, so force to add it
|
||||
addonsDirs.insert(0, "/ERPLibre/addons/addons")
|
||||
# addonsDirs.insert(0, "/ERPLibre/addons/addons")
|
||||
addonsDirs.insert(0, "/ERPLibre/odoo/addons/")
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
|
|
|
|||
|
|
@ -13,3 +13,4 @@ xlsxwriter
|
|||
ldap
|
||||
pythonjsonlogger
|
||||
python-alipay-sdk
|
||||
pyrfc
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
<project name="connector-jira.git" path="addons/OCA_connector-jira" remote="OCA" groups="addons"/>
|
||||
<project name="connector-telephony.git" path="addons/OCA_connector-telephony" remote="OCA" groups="addons"/>
|
||||
<project name="connector.git" path="addons/OCA_connector" remote="OCA" groups="addons"/>
|
||||
<project name="contract.git" path="addons/OCA_contract" remote="OCA" groups="addons"/>
|
||||
<project name="contract.git" path="addons/OCA_contract" remote="OCA" revision="12.0_dev" groups="addons,code_generator"/>
|
||||
<project name="credit-control.git" path="addons/OCA_credit-control" remote="OCA" groups="addons"/>
|
||||
<project name="crm.git" path="addons/OCA_crm" remote="OCA" groups="addons"/>
|
||||
<project name="currency.git" path="addons/OCA_currency" remote="OCA" groups="addons"/>
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
<project name="e-commerce.git" path="addons/OCA_e-commerce" remote="OCA" groups="addons"/>
|
||||
<project name="edi.git" path="addons/OCA_edi" remote="OCA" groups="addons"/>
|
||||
<project name="erplibre_addons.git" path="addons/ERPLibre_erplibre_addons" remote="ERPLibre" groups="addons,base"/>
|
||||
<project name="erplibre_theme_addons.git" path="addons/ERPLibre_erplibre_theme_addons" remote="ERPLibre" groups="addons"/>
|
||||
<project name="erplibre_theme_addons.git" path="addons/ERPLibre_erplibre_theme_addons" remote="ERPLibre" groups="addons,code_generator"/>
|
||||
<project name="event.git" path="addons/OCA_event" remote="OCA" groups="addons"/>
|
||||
<project name="field-service.git" path="addons/OCA_field-service" remote="OCA" groups="addons"/>
|
||||
<project name="fleet.git" path="addons/OCA_fleet" remote="OCA" groups="addons"/>
|
||||
|
|
@ -75,6 +75,7 @@
|
|||
<project name="interface-github.git" path="addons/OCA_interface-github" remote="OCA" groups="addons"/>
|
||||
<project name="knowledge.git" path="addons/OCA_knowledge" remote="OCA" groups="addons"/>
|
||||
<project name="l10n-canada.git" path="addons/OCA_l10n-canada" remote="OCA" groups="addons"/>
|
||||
<project name="maintainer-tools.git" path="script/OCA_maintainer-tools" remote="OCA" revision="master" groups="odoo,code_generator"/>
|
||||
<project name="maintenance.git" path="addons/OCA_maintenance" remote="OCA" groups="addons"/>
|
||||
<project name="management-system.git" path="addons/OCA_management-system" remote="OCA" groups="addons"/>
|
||||
<project name="manufacture.git" path="addons/OCA_manufacture" remote="OCA" groups="addons"/>
|
||||
|
|
@ -86,14 +87,15 @@
|
|||
<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_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_fix_web_conflict_menu" groups="addons,base"/>
|
||||
<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"/>
|
||||
<project name="multi-company.git" path="addons/OCA_multi-company" remote="OCA" groups="addons"/>
|
||||
<project name="odoo-base-addons.git" path="addons/Numigi_odoo-base-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-business-spending-management-quebec-canada.git" path="addons/MathBenTech_odoo-business-spending-management-quebec-canada" remote="MathBenTech" revision="12.0_sale_order_line_timesheet_attribution" groups="addons,base"/>
|
||||
<project name="odoo-cloud-platform.git" path="addons/camptocamp_odoo-cloud-platform" remote="camptocamp" groups="addons,base"/>
|
||||
<project name="odoo-cloud-platform.git" path="addons/camptocamp_odoo-cloud-platform" remote="camptocamp" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-code-generator-template.git" path="addons/TechnoLibre_odoo-code-generator-template" revision="12.0" remote="TechnoLibre" groups="addons,code_generator"/>
|
||||
<project name="odoo-code-generator.git" path="addons/TechnoLibre_odoo-code-generator" remote="TechnoLibre" revision="12.0" groups="addons,code_generator"/>
|
||||
<project name="odoo-development.git" path="doc/itpp-labs_odoo-development" remote="itpp-labs" revision="master" groups="odoo"/>
|
||||
<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-hr-addons.git" path="addons/Numigi_odoo-hr-addons" remote="Numigi" groups="addons"/>
|
||||
|
|
@ -104,7 +106,6 @@
|
|||
<project name="odoo-product-configurator.git" path="addons/pledra_odoo-product-configurator" remote="pledra" groups="addons"/>
|
||||
<project name="odoo-project-addons.git" path="addons/Numigi_odoo-project-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-purchase-addons.git" path="addons/Numigi_odoo-purchase-addons" remote="Numigi" groups="addons"/>
|
||||
<project name="odoo-saas-tools.git" path="addons/it-projects-llc_odoo-saas-tools" remote="it-projects-llc" groups="addons"/>
|
||||
<project name="odoo-stock-addons.git" path="addons/Numigi_odoo-stock-addons" remote="Numigi" revision="12.0_dev" groups="addons"/>
|
||||
<project name="odoo-survey-addons.git" path="addons/Numigi_odoo-survey-addons" remote="Numigi" groups="addons"/>
|
||||
<project name="odoo-test-docs.git" path="doc/itpp-labs_odoo-test-docs" remote="itpp-labs" revision="master" groups="odoo"/>
|
||||
|
|
@ -129,6 +130,7 @@
|
|||
<project name="queue.git" path="addons/OCA_queue" remote="OCA" groups="addons"/>
|
||||
<project name="reporting-engine.git" path="addons/OCA_reporting-engine" remote="OCA" groups="addons"/>
|
||||
<project name="rma.git" path="addons/OCA_rma" remote="OCA" groups="addons"/>
|
||||
<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"/>
|
||||
|
|
|
|||
1338
poetry.lock
generated
1338
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,7 +13,8 @@ authors = [ "Mathieu Benoit <mathben@technolibre.ca>",]
|
|||
python = "^3.7.7"
|
||||
Asterisk = "^0.0.8"
|
||||
Babel = "2.3.4"
|
||||
GitPython = "^3.1.12"
|
||||
BeautifulSoup4 = "^4.9.3"
|
||||
GitPython = "3.1.12"
|
||||
Jinja2 = "2.10.1"
|
||||
Mako = "1.0.4"
|
||||
MarkupSafe = "0.23"
|
||||
|
|
@ -28,37 +29,42 @@ Werkzeug = "0.11.15"
|
|||
XlsxWriter = "0.9.3"
|
||||
agithub = "^2.2.2"
|
||||
altair = "^4.1.0"
|
||||
argcomplete = "^1.12.2"
|
||||
argcomplete = "^1.12.3"
|
||||
bokeh = "1.1.0"
|
||||
boto = "^2.49.0"
|
||||
boto3 = "1.9.102"
|
||||
cachetools = ">=2.0.1"
|
||||
cerberus = "^1.3.2"
|
||||
cerberus = "^1.3.4"
|
||||
chardet = "3.0.4"
|
||||
click = "^8.0.1"
|
||||
cloudflare = "^2.8.15"
|
||||
code_writer = "^1.1.1"
|
||||
colorama = "^0.4.4"
|
||||
cryptography = "2.6.1"
|
||||
cython = "^0.29.21"
|
||||
css-html-prettify = "^2.5.5"
|
||||
cython = "^0.29.23"
|
||||
ddt = "1.2.0"
|
||||
decorator = "4.0.10"
|
||||
docutils = "0.12"
|
||||
docutils = "0.16"
|
||||
ebaysdk = "2.1.5"
|
||||
email_validator = "^1.1.2"
|
||||
escpos = "^1.8"
|
||||
extract-msg = "^0.28.0"
|
||||
extract_msg = "^0.28.0"
|
||||
factur-x = "^1.12"
|
||||
email_validator = "^1.1.3"
|
||||
emoji = "^1.2.0"
|
||||
escpos = "^1.9"
|
||||
extract-msg = "^0.28.7"
|
||||
extract_msg = "^0.28.7"
|
||||
factur-x = "^2.3"
|
||||
feedparser = "5.2.1"
|
||||
flake8 = "^3.9.2"
|
||||
freezegun = "0.3.11"
|
||||
geojson = "2.4.1"
|
||||
gevent = "1.3.4"
|
||||
gitpython = "^3.1.12"
|
||||
giturlparse = "^0.10.0"
|
||||
greenlet = "0.4.13"
|
||||
html2text = "2016.9.19"
|
||||
invoice2data = "^0.3.5"
|
||||
html5print = "^0.1.2"
|
||||
invoice2data = "^0.3.6"
|
||||
iscompatible = "^0.1.1"
|
||||
jira = "2.0.0"
|
||||
js2py = "^0.71"
|
||||
keystoneauth1 = "3.14.0"
|
||||
lasso = "^0.0.5"
|
||||
libsass = "0.12.3"
|
||||
|
|
@ -68,20 +74,21 @@ mock = "2.0.0"
|
|||
mpld3 = "0.3"
|
||||
mysqlclient = "^2.0.3"
|
||||
num2words = "0.5.6"
|
||||
numpy = "^1.19.5"
|
||||
numpy = "^1.21.0"
|
||||
oauthlib = "2.1.0"
|
||||
"oca.decorators" = "^0.0.1"
|
||||
ofxparse = "0.16"
|
||||
openpyxl = "^3.0.5"
|
||||
openpyxl = "^3.0.7"
|
||||
openupgradelib = "^2.0.0"
|
||||
pandas = "1.2.0"
|
||||
paramiko = "^2.7.2"
|
||||
passlib = "1.6.5"
|
||||
pdf2image = "^1.14.0"
|
||||
pdf2image = "^1.16.0"
|
||||
pdfminer = "^20191125"
|
||||
pexpect = "^4.8.0"
|
||||
phonenumbers = "^8.12.15"
|
||||
phonenumbers = "^8.12.26"
|
||||
plotly = "4.1.0"
|
||||
premailer = "^3.7.0"
|
||||
premailer = "^3.9.0"
|
||||
psutil = "4.3.1"
|
||||
psycopg2 = "2.7.3.1"
|
||||
py-Asterisk = "^0.5.18"
|
||||
|
|
@ -91,12 +98,11 @@ pycountry = "^20.7.3"
|
|||
pydot = "1.2.3"
|
||||
pygount = "<1.2.0"
|
||||
pyldap = "2.4.28"
|
||||
pymssql = "^2.1.5"
|
||||
pymssql = "^2.2.1"
|
||||
pymysql = "^1.0.2"
|
||||
pyotp = "^2.4.1"
|
||||
pyotp = "^2.6.0"
|
||||
pyparsing = "2.1.10"
|
||||
pyproj = "^3.0.0"
|
||||
pyrfc = "^0.1.2"
|
||||
pyproj = "^3.1.0"
|
||||
pyserial = "3.1.1"
|
||||
pysftp = "^0.2.9"
|
||||
python-chess = "<0.24"
|
||||
|
|
@ -106,7 +112,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.15"
|
||||
python-stdnum = "^1.16"
|
||||
python-swiftclient = "3.9.0"
|
||||
python-u2flib-server = "^5.0.1"
|
||||
python-u2flib_server = "^5.0.1"
|
||||
|
|
@ -118,11 +124,10 @@ raven = "^6.10.0"
|
|||
redis = "2.10.5"
|
||||
reportlab = "3.3.0"
|
||||
requests = "2.20.0"
|
||||
requests-mock = "^1.8.0"
|
||||
requests-mock = "^1.9.3"
|
||||
requests-oauthlib = "1.1.0"
|
||||
requests-toolbelt = "0.9.1"
|
||||
retrying = "^1.3.3"
|
||||
rotate_backups_s3 = "^0.3"
|
||||
serial = "^0.0.97"
|
||||
shapely = "1.6.4.post2"
|
||||
simplejson = "^3.17.2"
|
||||
|
|
@ -130,27 +135,37 @@ slugify = "^0.0.1"
|
|||
sphinx = ">=1.6.7"
|
||||
sphinx-intl = "^2.0.1"
|
||||
sphinx-patchqueue = ">=1.0"
|
||||
sphinx_rtd_theme = "^0.5.1"
|
||||
sqlalchemy = "^1.3.22"
|
||||
sphinx_rtd_theme = "^0.5.2"
|
||||
sqlalchemy = "^1.4.19"
|
||||
statsd = "3.2.1"
|
||||
suds-jurko = "0.6"
|
||||
toml = "^0.10.2"
|
||||
twython = "^3.8.2"
|
||||
unidecode = "1.0.22"
|
||||
unidiff = "^0.6.0"
|
||||
vatnumber = "1.2"
|
||||
vcrpy = ">=2.1.1"
|
||||
vcrpy-unittest = "^0.1.7"
|
||||
vobject = "0.9.3"
|
||||
voicent-python = "^1.0"
|
||||
webcolors = "1.10"
|
||||
websocket-client = "^0.57.0"
|
||||
wechatpy = "^1.8.14"
|
||||
websocket-client = "^1.1.0"
|
||||
wechatpy = "^1.8.15"
|
||||
wget = "^3.2"
|
||||
wheel = "^0.36.2"
|
||||
xlrd = "1.0.0"
|
||||
xlwt = "1.3"
|
||||
xmlformatter = "^0.2.2"
|
||||
xmltodict = "^0.12.0"
|
||||
zeep = "^4.0.0"
|
||||
zxcvbn = "^4.4.28"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
websocket_client = "^0.57.0"
|
||||
websocket_client = "^1.1.0"
|
||||
|
||||
[tool.poetry.dependencies.black]
|
||||
git = "https://github.com/psf/black.git"
|
||||
rev = "21.6b0"
|
||||
|
||||
[tool.poetry.dependencies.pylint-odoo]
|
||||
git = "https://github.com/oca/pylint-odoo.git"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
# For script
|
||||
giturlparse
|
||||
agithub
|
||||
gitpython
|
||||
GitPython==3.1.12
|
||||
PyYAML
|
||||
retrying
|
||||
xmltodict
|
||||
openupgradelib
|
||||
unidiff
|
||||
|
||||
# For OSX
|
||||
cython
|
||||
|
|
@ -13,6 +14,7 @@ cython
|
|||
# For Odoo
|
||||
wheel
|
||||
phonenumbers
|
||||
pytz==2017.3
|
||||
|
||||
# For OCA
|
||||
factur-x
|
||||
|
|
@ -29,7 +31,26 @@ voicent-python
|
|||
python-swiftclient
|
||||
python-keystoneclient
|
||||
|
||||
# For logical test
|
||||
docutils==0.16
|
||||
flake8
|
||||
git+https://github.com/oca/pylint-odoo.git
|
||||
# oca-maintainers-tools
|
||||
# git+https://github.com/OCA/maintainer-tools.git#egg=oca-maintainers-tools
|
||||
xmlformatter
|
||||
html5print
|
||||
css-html-prettify
|
||||
BeautifulSoup4
|
||||
git+https://github.com/psf/black.git@21.6b0
|
||||
|
||||
# For updating poetry
|
||||
toml
|
||||
iscompatible
|
||||
pandas==1.2.0
|
||||
|
||||
# For deployment
|
||||
cloudflare
|
||||
|
||||
# For multilang_md.py
|
||||
click
|
||||
emoji
|
||||
|
|
|
|||
5
run.sh
5
run.sh
|
|
@ -1,3 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
source ./.venv/bin/activate
|
||||
python3 ./odoo/odoo-bin -c ./config.conf --limit-time-real 99999 --limit-time-cpu 99999 $@
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error run.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
7
script/addons/install_addons.sh
Executable file
7
script/addons/install_addons.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
./run.sh --no-http --stop-after-init -d $1 -i $2 -u $2
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error install_addons.sh"
|
||||
exit 1
|
||||
fi
|
||||
7
script/addons/install_addons_dev.sh
Executable file
7
script/addons/install_addons_dev.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
./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"
|
||||
exit 1
|
||||
fi
|
||||
8
script/addons/reinstall_addons.sh
Executable file
8
script/addons/reinstall_addons.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
./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"
|
||||
exit 1
|
||||
fi
|
||||
2
script/addons/uninstall_addons.sh
Executable file
2
script/addons/uninstall_addons.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
./run.sh --no-http --stop-after-init -d $1 --uninstall $2
|
||||
100
script/code_generator/check_git_change_code_generator.sh
Executable file
100
script/code_generator/check_git_change_code_generator.sh
Executable file
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env bash
|
||||
# REF: https://stackoverflow.com/a/28938235
|
||||
# Reset
|
||||
Color_Off='\033[0m' # Text Reset
|
||||
|
||||
# Regular Colors
|
||||
Black='\033[0;30m' # Black
|
||||
Red='\033[0;31m' # Red
|
||||
Green='\033[0;32m' # Green
|
||||
Yellow='\033[0;33m' # Yellow
|
||||
Blue='\033[0;34m' # Blue
|
||||
Purple='\033[0;35m' # Purple
|
||||
Cyan='\033[0;36m' # Cyan
|
||||
White='\033[0;37m' # White
|
||||
|
||||
# Bold
|
||||
BBlack='\033[1;30m' # Black
|
||||
BRed='\033[1;31m' # Red
|
||||
BGreen='\033[1;32m' # Green
|
||||
BYellow='\033[1;33m' # Yellow
|
||||
BBlue='\033[1;34m' # Blue
|
||||
BPurple='\033[1;35m' # Purple
|
||||
BCyan='\033[1;36m' # Cyan
|
||||
BWhite='\033[1;37m' # White
|
||||
|
||||
# Underline
|
||||
UBlack='\033[4;30m' # Black
|
||||
URed='\033[4;31m' # Red
|
||||
UGreen='\033[4;32m' # Green
|
||||
UYellow='\033[4;33m' # Yellow
|
||||
UBlue='\033[4;34m' # Blue
|
||||
UPurple='\033[4;35m' # Purple
|
||||
UCyan='\033[4;36m' # Cyan
|
||||
UWhite='\033[4;37m' # White
|
||||
|
||||
# Background
|
||||
On_Black='\033[40m' # Black
|
||||
On_Red='\033[41m' # Red
|
||||
On_Green='\033[42m' # Green
|
||||
On_Yellow='\033[43m' # Yellow
|
||||
On_Blue='\033[44m' # Blue
|
||||
On_Purple='\033[45m' # Purple
|
||||
On_Cyan='\033[46m' # Cyan
|
||||
On_White='\033[47m' # White
|
||||
|
||||
# High Intensity
|
||||
IBlack='\033[0;90m' # Black
|
||||
IRed='\033[0;91m' # Red
|
||||
IGreen='\033[0;92m' # Green
|
||||
IYellow='\033[0;93m' # Yellow
|
||||
IBlue='\033[0;94m' # Blue
|
||||
IPurple='\033[0;95m' # Purple
|
||||
ICyan='\033[0;96m' # Cyan
|
||||
IWhite='\033[0;97m' # White
|
||||
|
||||
# Bold High Intensity
|
||||
BIBlack='\033[1;90m' # Black
|
||||
BIRed='\033[1;91m' # Red
|
||||
BIGreen='\033[1;92m' # Green
|
||||
BIYellow='\033[1;93m' # Yellow
|
||||
BIBlue='\033[1;94m' # Blue
|
||||
BIPurple='\033[1;95m' # Purple
|
||||
BICyan='\033[1;96m' # Cyan
|
||||
BIWhite='\033[1;97m' # White
|
||||
|
||||
# High Intensity backgrounds
|
||||
On_IBlack='\033[0;100m' # Black
|
||||
On_IRed='\033[0;101m' # Red
|
||||
On_IGreen='\033[0;102m' # Green
|
||||
On_IYellow='\033[0;103m' # Yellow
|
||||
On_IBlue='\033[0;104m' # Blue
|
||||
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}
|
||||
|
||||
output=$(git status --porcelain)
|
||||
if [ -z "$output" ]; then
|
||||
echo "PASS - ${REP}"
|
||||
else
|
||||
echo -e "${Red}FAIL - ${REP}${Color_Off}"
|
||||
echo -e "${BRed}${output}${Color_Off}"
|
||||
cd - >/dev/null
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd - >/dev/null
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
check_git "$1"
|
||||
else
|
||||
# check_git "./addons/TechnoLibre_odoo-code-generator"
|
||||
check_git "./addons/TechnoLibre_odoo-code-generator-template"
|
||||
fi
|
||||
25
script/code_generator/install_and_test_code_generator.sh
Executable file
25
script/code_generator/install_and_test_code_generator.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
# $1 is database name
|
||||
# $2 is module name
|
||||
# $3 is directory path to check
|
||||
|
||||
./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
|
||||
./script/repo_revert_git_diff_date_from_code_generator.py
|
||||
# Remove pot and po diff
|
||||
cd $3
|
||||
BRANCH=$(git branch --show-current)
|
||||
git restore --source="${BRANCH}" "*.po*"
|
||||
cd -
|
||||
./script/maintenance/black.sh $3
|
||||
echo "TEST ${2}"
|
||||
./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"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -5,6 +5,7 @@ import argparse
|
|||
import logging
|
||||
import subprocess
|
||||
from code_writer import CodeWriter
|
||||
|
||||
# import tokenize
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -21,16 +22,22 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Transform a python file in code writer format python file.
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--file",
|
||||
dest="file",
|
||||
required=True,
|
||||
help="Path of file to transform to code_writer.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o", "--output", dest="output", help="The output file."
|
||||
)
|
||||
parser.add_argument('-f', '--file', dest="file", required=True,
|
||||
help="Path of file to transform to code_writer.")
|
||||
parser.add_argument('-o', '--output', dest="output",
|
||||
help="The output file.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -68,7 +75,11 @@ def main():
|
|||
no_tab = 0
|
||||
|
||||
# Validate file format
|
||||
out = subprocess.check_output(f"python -m tabnanny {config.file}", stderr=subprocess.STDOUT, shell=True)
|
||||
out = subprocess.check_output(
|
||||
f"python -m tabnanny {config.file}",
|
||||
stderr=subprocess.STDOUT,
|
||||
shell=True,
|
||||
)
|
||||
if out:
|
||||
print(out)
|
||||
sys.exit(1)
|
||||
|
|
@ -82,14 +93,16 @@ def main():
|
|||
cw.emit("cw = CodeWriter()")
|
||||
|
||||
no_line = 1
|
||||
with open(config.file, 'r') as file:
|
||||
with open(config.file, "r") as file:
|
||||
for line in file.readlines():
|
||||
nb_tab, nb_space = count_space_tab(line)
|
||||
diff_tab = nb_tab - last_nb_tab
|
||||
new_line = line.strip()
|
||||
new_line = new_line.replace("\"", "\\\"")
|
||||
new_line = new_line.replace('"', '\\"')
|
||||
|
||||
status_no_tab = add_line(cw, new_line, no_line, nb_tab, no_tab, no_tab, nb_space)
|
||||
status_no_tab = add_line(
|
||||
cw, new_line, no_line, nb_tab, no_tab, no_tab, nb_space
|
||||
)
|
||||
if status_no_tab >= 0:
|
||||
no_tab = status_no_tab
|
||||
|
||||
|
|
@ -99,13 +112,15 @@ def main():
|
|||
|
||||
output = cw.render()
|
||||
if config.output:
|
||||
with open(config.output, 'w') as file:
|
||||
with open(config.output, "w") as file:
|
||||
file.write(output)
|
||||
else:
|
||||
print(output)
|
||||
|
||||
|
||||
def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
||||
def add_line(
|
||||
cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space
|
||||
):
|
||||
"""
|
||||
Recursive check indent and write line
|
||||
:param cw: code_writer module
|
||||
|
|
@ -123,25 +138,27 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
sys.exit(-1)
|
||||
|
||||
if nb_indent == -1:
|
||||
cw.emit("cw.emit(\"\")")
|
||||
cw.emit('cw.emit("")')
|
||||
return 0
|
||||
elif nb_indent == no_indent:
|
||||
if nb_indent == 0:
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
return 0
|
||||
elif nb_indent == 1:
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 2:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 3:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -150,9 +167,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 4:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -164,9 +184,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 5:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -181,9 +204,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 6:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -201,9 +227,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 7:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -224,9 +253,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 8:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -250,9 +282,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 9:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -279,9 +314,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 10:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -311,9 +349,14 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 11:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -342,13 +385,26 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 12:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -377,16 +433,35 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 13:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -415,19 +490,44 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 14:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -458,22 +558,53 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 15:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -504,25 +635,63 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 16:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -551,28 +720,72 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 17:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -601,31 +814,81 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 18:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -656,34 +919,90 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
elif nb_indent == 19:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
|
@ -716,48 +1035,126 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent - 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with"
|
||||
f" cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
if (
|
||||
nb_indent
|
||||
- 1
|
||||
> init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent():"
|
||||
)
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
if (
|
||||
no_indent
|
||||
!= init_no_intend
|
||||
):
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(
|
||||
f'cw.emit("{line}")'
|
||||
)
|
||||
return nb_indent
|
||||
else:
|
||||
if no_indent > nb_indent:
|
||||
# deindent
|
||||
return add_line(cw, line, no_line, nb_indent, no_indent - 1, init_no_intend, nb_space)
|
||||
return add_line(
|
||||
cw,
|
||||
line,
|
||||
no_line,
|
||||
nb_indent,
|
||||
no_indent - 1,
|
||||
init_no_intend,
|
||||
nb_space,
|
||||
)
|
||||
else:
|
||||
# indent
|
||||
return add_line(cw, line, no_line, nb_indent, no_indent + 1, init_no_intend, nb_space)
|
||||
return add_line(
|
||||
cw,
|
||||
line,
|
||||
no_line,
|
||||
nb_indent,
|
||||
no_indent + 1,
|
||||
init_no_intend,
|
||||
nb_space,
|
||||
)
|
||||
print("BUG")
|
||||
return -1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -20,16 +20,22 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Transform a xml file in code writer format xml file.
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--file",
|
||||
dest="file",
|
||||
required=True,
|
||||
help="Path of file to transform to code_writer.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o", "--output", dest="output", help="The output file."
|
||||
)
|
||||
parser.add_argument('-f', '--file', dest="file", required=True,
|
||||
help="Path of file to transform to code_writer.")
|
||||
parser.add_argument('-o', '--output', dest="output",
|
||||
help="The output file.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -55,7 +61,10 @@ def code_writer_deep_xml(nodes):
|
|||
if lst_comment:
|
||||
comment = f"# {lst_comment[0]}"
|
||||
|
||||
code_line = (f"E.{node.tagName}({str(dict(node.attributes.items()))})", value)
|
||||
code_line = (
|
||||
f"E.{node.tagName}({str(dict(node.attributes.items()))})",
|
||||
value,
|
||||
)
|
||||
lst_result.append((comment, code_line))
|
||||
elif node.nodeType == Node.TEXT_NODE:
|
||||
if size_nodes == 1:
|
||||
|
|
@ -102,31 +111,36 @@ def main():
|
|||
print(f"Error, cannot parse {config.file}")
|
||||
sys.exit(1)
|
||||
|
||||
cw.emit('from lxml.builder import E')
|
||||
cw.emit('from lxml import etree as ET')
|
||||
cw.emit('from code_writer import CodeWriter')
|
||||
cw.emit('')
|
||||
cw.emit("from lxml.builder import E")
|
||||
cw.emit("from lxml import etree as ET")
|
||||
cw.emit("from code_writer import CodeWriter")
|
||||
cw.emit("")
|
||||
cw.emit('print(\'<?xml version="1.0" encoding="utf-8"?>\')')
|
||||
cw.emit('print("<odoo>")')
|
||||
|
||||
lst_function = []
|
||||
comment_for_next_group = None
|
||||
|
||||
for odoo in mydoc.getElementsByTagName('odoo'):
|
||||
for odoo in mydoc.getElementsByTagName("odoo"):
|
||||
for ir_view_item in odoo.childNodes:
|
||||
if ir_view_item.nodeType == Node.ELEMENT_NODE:
|
||||
# Show part of xml
|
||||
fct_name = "ma_fonction"
|
||||
lst_function.append(fct_name)
|
||||
cw.emit(f'def {fct_name}():')
|
||||
cw.emit(f"def {fct_name}():")
|
||||
with cw.indent():
|
||||
cw.emit('"""')
|
||||
for line in transform_string_to_list(ir_view_item.toprettyxml()):
|
||||
for line in transform_string_to_list(
|
||||
ir_view_item.toprettyxml()
|
||||
):
|
||||
cw.emit(line)
|
||||
cw.emit('"""')
|
||||
# Show comment
|
||||
if comment_for_next_group:
|
||||
cw.emit(f'print(\'<!-- {comment_for_next_group.strip()} -->\')')
|
||||
cw.emit(
|
||||
"print('<!--"
|
||||
f" {comment_for_next_group.strip()} -->')"
|
||||
)
|
||||
comment_for_next_group = None
|
||||
attributes_root = dict(ir_view_item.attributes.items())
|
||||
|
||||
|
|
@ -136,15 +150,21 @@ def main():
|
|||
generate_code.generate_code(lst_out)
|
||||
child_root = generate_code.result
|
||||
|
||||
code = f'root = E.{ir_view_item.tagName}({str(attributes_root)}, {child_root})'
|
||||
code = (
|
||||
"root ="
|
||||
f" E.{ir_view_item.tagName}({str(attributes_root)},"
|
||||
f" {child_root})"
|
||||
)
|
||||
|
||||
for line in code.split("\n"):
|
||||
cw.emit(line)
|
||||
|
||||
cw.emit('content = ET.tostring(root, pretty_print=True)')
|
||||
cw.emit("content = ET.tostring(root, pretty_print=True)")
|
||||
cw.emit()
|
||||
cw.emit("cw = CodeWriter()")
|
||||
cw.emit('for line in content.decode("utf-8").split("\\n"):')
|
||||
cw.emit(
|
||||
'for line in content.decode("utf-8").split("\\n"):'
|
||||
)
|
||||
with cw.indent():
|
||||
cw.emit("with cw.indent():")
|
||||
with cw.indent():
|
||||
|
|
@ -161,13 +181,15 @@ def main():
|
|||
|
||||
output = cw.render()
|
||||
if config.output:
|
||||
with open(config.output, 'w') as file:
|
||||
with open(config.output, "w") as file:
|
||||
file.write(output)
|
||||
else:
|
||||
print(output)
|
||||
|
||||
|
||||
def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
||||
def add_line(
|
||||
cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space
|
||||
):
|
||||
"""
|
||||
Recursive check indent and write line
|
||||
:param cw: code_writer module
|
||||
|
|
@ -185,21 +207,21 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
|
|||
sys.exit(-1)
|
||||
|
||||
if nb_indent == -1:
|
||||
cw.emit("cw.emit(\"\")")
|
||||
cw.emit('cw.emit("")')
|
||||
return 0
|
||||
elif nb_indent == no_indent:
|
||||
if nb_indent == 0:
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
return 0
|
||||
elif nb_indent == 1:
|
||||
if no_indent != init_no_intend:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
with cw.indent():
|
||||
cw.emit(f"cw.emit(\"{line}\")")
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 2:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
107
script/db_restore.py
Executable file
107
script/db_restore.py
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
from subprocess import check_output
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
||||
|
||||
_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="""\
|
||||
Restore database, use cache to clone to improve speed.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
# parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
# help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument("--database", help="Database to manipulate.")
|
||||
parser.add_argument(
|
||||
"--image",
|
||||
default="erplibre_base",
|
||||
help=(
|
||||
"Image name to restore, from directory image_db, filename without"
|
||||
" '.zip'. Example, use erplibre_base to use image"
|
||||
" erplibre_base.zip."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--clean_cache",
|
||||
action="store_true",
|
||||
help="Delete all database cache to clone, begin by _cache_.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
|
||||
# Get list of database
|
||||
arg = "./.venv/bin/python3 ./odoo/odoo-bin db --list"
|
||||
out = check_output(arg.split(" ")).decode()
|
||||
lst_db = out.strip().split("\n")
|
||||
lst_db_cache = [a for a in lst_db if a.startswith("_cache_")]
|
||||
|
||||
if config.clean_cache:
|
||||
for db in lst_db_cache:
|
||||
_logger.info(f"## Delete {db} ##")
|
||||
arg = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {db}"
|
||||
)
|
||||
out = check_output(arg.split(" ")).decode()
|
||||
print(out)
|
||||
|
||||
if config.database:
|
||||
cache_database = f"_cache_{config.image}"
|
||||
# Drop db
|
||||
if config.database in lst_db:
|
||||
_logger.info(f"## Drop {config.database} ##")
|
||||
arg = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
|
||||
f" {config.database}"
|
||||
)
|
||||
out = check_output(arg.split(" ")).decode()
|
||||
print(out)
|
||||
# Check cache exist
|
||||
if cache_database not in lst_db_cache:
|
||||
_logger.info(
|
||||
f"## Create cache {cache_database} from image"
|
||||
f" {config.image} ##"
|
||||
)
|
||||
arg = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --restore"
|
||||
f" --restore_image {config.image} --database {cache_database}"
|
||||
)
|
||||
out = check_output(arg.split(" ")).decode()
|
||||
print(out)
|
||||
# Clone database
|
||||
_logger.info(
|
||||
f"## Clone cache {cache_database} to database {config.database} ##"
|
||||
)
|
||||
arg = (
|
||||
"./.venv/bin/python3 ./odoo/odoo-bin db --clone --from_database"
|
||||
f" {cache_database} --database {config.database}"
|
||||
)
|
||||
out = check_output(arg.split(" ")).decode()
|
||||
print(out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
6
script/deployment/get_public_ip.py
Executable file
6
script/deployment/get_public_ip.py
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#!./.venv/bin/python
|
||||
import requests
|
||||
|
||||
r = requests.get(r"https://api.ipify.org")
|
||||
ip = r.text
|
||||
print(ip)
|
||||
145
script/deployment/update_dns_cloudflare.py
Executable file
145
script/deployment/update_dns_cloudflare.py
Executable file
|
|
@ -0,0 +1,145 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import CloudFlare
|
||||
import requests
|
||||
|
||||
logging.basicConfig()
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
_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="""\
|
||||
Can update all old_ip to new_ip.
|
||||
When auto_sync is enable:
|
||||
Check zone and name on cloudflare and compare with public ip, update all old ip with new ip if different.
|
||||
You need your profile in file ~/.cloudflare/cloudflare.cfg
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--profile",
|
||||
required=True,
|
||||
help="The profile of CloudFlare, check ~/.cloudflare/cloudflare.cfg.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--old_ip", required=False, help="Ip to search to update."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--new_ip", required=False, help="Ip to replace the old ip."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dns_name",
|
||||
required=False,
|
||||
help="DNS name to output his ip and sync.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--zone_name",
|
||||
required=False,
|
||||
help="The CloudFlare zone name to check.",
|
||||
)
|
||||
parser.add_argument("--delete", action="store_true")
|
||||
parser.add_argument("--debug", action="store_true")
|
||||
parser.add_argument("--raw", action="store_true")
|
||||
parser.add_argument(
|
||||
"--auto_sync",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Need this to use DNS name and zone name to sync public ip to"
|
||||
" CloudFlare."
|
||||
),
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
class ManageCloudFlare:
|
||||
def __init__(self, profile, debug=False, raw=False):
|
||||
self.cf = CloudFlare.CloudFlare(profile=profile, debug=debug, raw=raw)
|
||||
self.raw = raw
|
||||
|
||||
@staticmethod
|
||||
def get_public_ip():
|
||||
r = requests.get(r"https://api.ipify.org")
|
||||
ip = r.text
|
||||
return ip
|
||||
|
||||
def get_ip_cloudflare(self, zone_name, name):
|
||||
"""Return ip from a zone and domain"""
|
||||
zone = self.cf.zones.get(params={"name": zone_name})
|
||||
lst_zone = [a.get("id") for a in zone]
|
||||
for zone_id in lst_zone:
|
||||
lst_result_dns = self.cf.zones.dns_records.get(zone_id)
|
||||
for result_dns in lst_result_dns:
|
||||
if (
|
||||
result_dns.get("type") == "A"
|
||||
and result_dns.get("name") == name
|
||||
):
|
||||
return result_dns.get("content")
|
||||
|
||||
def edit_cloudflare(self, old_ip, delete=False, new_ip=""):
|
||||
"""Change ip of zone and name"""
|
||||
|
||||
# TODO support smaller range
|
||||
params = {"per_page": 500}
|
||||
zones = self.cf.zones.get(params=params)
|
||||
result = zones.get("result") if self.raw else zones
|
||||
lst_zone = [a.get("id") for a in result]
|
||||
for zone_id in lst_zone:
|
||||
# dns_records = cf.zones.dns_records.export.get(zone_id)
|
||||
result_dns = self.cf.zones.dns_records.get(zone_id)
|
||||
dns_records = result_dns.get("result") if self.raw else result_dns
|
||||
for dns in dns_records:
|
||||
if dns.get("content") == old_ip:
|
||||
if delete:
|
||||
_logger.info(f"Delete {dns.get('name')}")
|
||||
r = self.cf.zones.dns_records.delete(
|
||||
zone_id, dns.get("id")
|
||||
)
|
||||
elif new_ip:
|
||||
_logger.info(
|
||||
f"Update {dns.get('name')} with ip {new_ip}, old"
|
||||
f" ip was {old_ip}"
|
||||
)
|
||||
dns_record = {
|
||||
"name": dns.get("name"),
|
||||
"type": dns.get("type"),
|
||||
"content": new_ip,
|
||||
}
|
||||
r = self.cf.zones.dns_records.post(
|
||||
zone_id, data=dns_record
|
||||
)
|
||||
r = self.cf.zones.dns_records.delete(
|
||||
zone_id, dns.get("id")
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
cl = ManageCloudFlare(config.profile, debug=config.debug)
|
||||
if config.auto_sync:
|
||||
configured_ip = cl.get_ip_cloudflare(config.zone_name, config.dns_name)
|
||||
actual_ip = cl.get_public_ip()
|
||||
if configured_ip != actual_ip:
|
||||
cl.edit_cloudflare(configured_ip, new_ip=actual_ip)
|
||||
else:
|
||||
_logger.info(f"Nothing to do, same ip {actual_ip}")
|
||||
else:
|
||||
cl.edit_cloudflare(
|
||||
config.old_ip, delete=config.delete, new_ip=config.new_ip
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -5,7 +5,7 @@ import argparse
|
|||
import logging
|
||||
import yaml
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -24,17 +24,27 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Update version of docker ready to commit.
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version", required=True, help="Version of ERPLibre."
|
||||
)
|
||||
parser.add_argument("--base", required=True, help="Docker base name.")
|
||||
parser.add_argument("--prod", required=True, help="Docker prod name.")
|
||||
parser.add_argument(
|
||||
"--docker_compose_file",
|
||||
default="./docker-compose.yml",
|
||||
help="Docker compose file to update.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--docker_prod",
|
||||
default="./docker/Dockerfile.prod.pkg",
|
||||
help="Docker prod file to update.",
|
||||
)
|
||||
parser.add_argument('--version', required=True, help="Version of ERPLibre.")
|
||||
parser.add_argument('--base', required=True, help="Docker base name.")
|
||||
parser.add_argument('--prod', required=True, help="Docker prod name.")
|
||||
parser.add_argument('--docker_compose_file', default="./docker-compose.yml", help="Docker compose file to update.")
|
||||
parser.add_argument('--docker_prod', default="./docker/Dockerfile.prod.pkg", help="Docker prod file to update.")
|
||||
args = parser.parse_args()
|
||||
args.base_version = f"{args.base}:{args.version}"
|
||||
args.prod_version = f"{args.prod}:{args.version}"
|
||||
|
|
@ -57,7 +67,7 @@ def get_config():
|
|||
|
||||
|
||||
def edit_text(config):
|
||||
with open(config.docker_compose_file, 'r') as f:
|
||||
with open(config.docker_compose_file, "r") as f:
|
||||
lst_docker_info = f.readlines()
|
||||
|
||||
if not lst_docker_info:
|
||||
|
|
@ -70,18 +80,20 @@ def edit_text(config):
|
|||
if is_find:
|
||||
key = "image:"
|
||||
value = lst_docker_info[i]
|
||||
lst_docker_info[i] = f"{value[:value.find(key) + len(key)]} {config.prod_version}\n"
|
||||
lst_docker_info[
|
||||
i
|
||||
] = f"{value[:value.find(key) + len(key)]} {config.prod_version}\n"
|
||||
break
|
||||
if "ERPLibre" in docker_info:
|
||||
is_find = True
|
||||
i += 1
|
||||
|
||||
with open(config.docker_compose_file, 'w') as f:
|
||||
with open(config.docker_compose_file, "w") as f:
|
||||
f.writelines(lst_docker_info)
|
||||
|
||||
|
||||
def edit_docker_prod(config):
|
||||
with open(config.docker_prod, 'r') as f:
|
||||
with open(config.docker_prod, "r") as f:
|
||||
lst_docker_info = f.readlines()
|
||||
|
||||
if not lst_docker_info:
|
||||
|
|
@ -94,7 +106,7 @@ def edit_docker_prod(config):
|
|||
lst_docker_info[i] = f"FROM {config.base_version}\n"
|
||||
i += 1
|
||||
|
||||
with open(config.docker_prod, 'w') as f:
|
||||
with open(config.docker_prod, "w") as f:
|
||||
f.writelines(lst_docker_info)
|
||||
|
||||
|
||||
|
|
@ -104,5 +116,5 @@ def main():
|
|||
edit_docker_prod(config)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ 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'
|
||||
DEFAULT_CONFIG_FILENAME = "~/.github/fork_github_repo.yaml"
|
||||
|
||||
|
||||
def github_url_argument(url):
|
||||
|
|
@ -20,11 +20,11 @@ def github_url_argument(url):
|
|||
"""
|
||||
parsed_url = parse(url)
|
||||
if not parsed_url.valid:
|
||||
raise argparse.ArgumentTypeError('%s is not a valid git URL'
|
||||
% url)
|
||||
raise argparse.ArgumentTypeError("%s is not a valid git URL" % url)
|
||||
if not parsed_url.github:
|
||||
raise argparse.ArgumentTypeError('%s is not a GitHub repo'
|
||||
% parsed_url.url)
|
||||
raise argparse.ArgumentTypeError(
|
||||
"%s is not a GitHub repo" % parsed_url.url
|
||||
)
|
||||
return url
|
||||
|
||||
|
||||
|
|
@ -41,10 +41,10 @@ def get_config():
|
|||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Fork a GitHub repo, clone that repo to a local directory, add the upstream
|
||||
remote, create an optional feature branch and checkout that branch''',
|
||||
epilog='''\
|
||||
remote, create an optional feature branch and checkout that branch""",
|
||||
epilog="""\
|
||||
The config file with a default location of
|
||||
~/.github/fork_github_repo.yaml contains the following settings:
|
||||
|
||||
|
|
@ -59,27 +59,40 @@ The file is YAML formatted and the contents look like this :
|
|||
github_token: 0123456789abcdef0123456789abcdef01234567
|
||||
repo_dir: ~/Documents/github.com/example/
|
||||
organization:
|
||||
'''
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-c', '--config',
|
||||
help='Filename of the yaml config file (default : %s)'
|
||||
% DEFAULT_CONFIG_FILENAME,
|
||||
"-c",
|
||||
"--config",
|
||||
help="Filename of the yaml config file (default : %s)"
|
||||
% DEFAULT_CONFIG_FILENAME,
|
||||
default=filename_argument(DEFAULT_CONFIG_FILENAME),
|
||||
type=filename_argument)
|
||||
parser.add_argument('url', help="GitHub URL of the upstream repo to fork",
|
||||
type=github_url_argument)
|
||||
parser.add_argument('branch', nargs='?', default=None,
|
||||
help="Name of the feature branch to create")
|
||||
type=filename_argument,
|
||||
)
|
||||
parser.add_argument(
|
||||
"url",
|
||||
help="GitHub URL of the upstream repo to fork",
|
||||
type=github_url_argument,
|
||||
)
|
||||
parser.add_argument(
|
||||
"branch",
|
||||
nargs="?",
|
||||
default=None,
|
||||
help="Name of the feature branch to create",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if (args.config == filename_argument(DEFAULT_CONFIG_FILENAME)) and (
|
||||
not os.path.isfile(args.config)):
|
||||
parser.error('Please create a config file at %s or point to one with '
|
||||
'the --config option.' % DEFAULT_CONFIG_FILENAME)
|
||||
not os.path.isfile(args.config)
|
||||
):
|
||||
parser.error(
|
||||
"Please create a config file at %s or point to one with "
|
||||
"the --config option." % DEFAULT_CONFIG_FILENAME
|
||||
)
|
||||
if not os.path.isfile(args.config):
|
||||
raise argparse.ArgumentTypeError(
|
||||
'Could not find config file %s.' % args.config)
|
||||
with open(args.config, 'r') as f:
|
||||
"Could not find config file %s." % args.config
|
||||
)
|
||||
with open(args.config, "r") as f:
|
||||
try:
|
||||
config = yaml.safe_load(f)
|
||||
if isinstance(config, dict):
|
||||
|
|
@ -88,10 +101,12 @@ organization:
|
|||
else:
|
||||
raise argparse.ArgumentTypeError(
|
||||
'Config contains %s of "%s" but it should be a dict'
|
||||
% (type(config), config))
|
||||
% (type(config), config)
|
||||
)
|
||||
except yaml.YAMLError:
|
||||
raise argparse.ArgumentTypeError(
|
||||
'Could not parse YAML in %s' % args.config)
|
||||
"Could not parse YAML in %s" % args.config
|
||||
)
|
||||
|
||||
|
||||
def get_list_fork_repo(upstream_url, github_token):
|
||||
|
|
@ -105,9 +120,15 @@ def get_list_fork_repo(upstream_url, github_token):
|
|||
|
||||
|
||||
def fork_and_clone_repo(
|
||||
upstream_url, github_token, repo_dir_root, branch_name=None,
|
||||
upstream_name='upstream', organization_name=None, fork_only=False,
|
||||
repo_root=None):
|
||||
upstream_url,
|
||||
github_token,
|
||||
repo_dir_root,
|
||||
branch_name=None,
|
||||
upstream_name="upstream",
|
||||
organization_name=None,
|
||||
fork_only=False,
|
||||
repo_root=None,
|
||||
):
|
||||
"""Fork a GitHub repo, clone that repo to a local directory,
|
||||
add the upstream remote, create an optional feature branch and checkout
|
||||
that branch
|
||||
|
|
@ -130,26 +151,28 @@ def fork_and_clone_repo(
|
|||
|
||||
# Fork the repo
|
||||
status, user = gh.user.get()
|
||||
user_name = user['login'] if not organization_name else organization_name
|
||||
user_name = user["login"] if not organization_name else organization_name
|
||||
status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
|
||||
if status == 404:
|
||||
status, upstream_repo = (
|
||||
gh.repos[parsed_url.owner][parsed_url.repo].get())
|
||||
status, upstream_repo = gh.repos[parsed_url.owner][
|
||||
parsed_url.repo
|
||||
].get()
|
||||
if status == 404:
|
||||
print("Unable to find repo %s" % upstream_url)
|
||||
exit(1)
|
||||
args = {}
|
||||
if organization_name:
|
||||
args["organization"] = organization_name
|
||||
status, forked_repo = (
|
||||
gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args))
|
||||
status, forked_repo = gh.repos[parsed_url.owner][
|
||||
parsed_url.repo
|
||||
].forks.post(**args)
|
||||
if status == 404:
|
||||
print("Error when forking repo %s" % forked_repo)
|
||||
exit(1)
|
||||
else:
|
||||
print("Forked %s to %s" % (upstream_url, forked_repo['html_url']))
|
||||
print("Forked %s to %s" % (upstream_url, forked_repo["html_url"]))
|
||||
elif status == 202:
|
||||
print("Forked repo %s already exists" % forked_repo['full_name'])
|
||||
print("Forked repo %s already exists" % forked_repo["full_name"])
|
||||
elif status != 200:
|
||||
print("Status not supported: %s - %s" % (status, forked_repo))
|
||||
exit(1)
|
||||
|
|
@ -166,24 +189,30 @@ def fork_and_clone_repo(
|
|||
try:
|
||||
if branch_name:
|
||||
submodule_repo = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
|
||||
url=http_url,
|
||||
branch=branch_name)
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(repo_root.create_submodule)(
|
||||
repo_dir_root,
|
||||
repo_dir_root,
|
||||
url=http_url,
|
||||
branch=branch_name,
|
||||
)
|
||||
else:
|
||||
submodule_repo = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
|
||||
url=http_url)
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(repo_root.create_submodule)(
|
||||
repo_dir_root, repo_dir_root, url=http_url
|
||||
)
|
||||
except KeyError as e:
|
||||
if os.path.isdir(repo_dir_root):
|
||||
print(f"Warning, submodule {repo_dir_root} already exist, "
|
||||
f"you need to add it in stage.")
|
||||
print(
|
||||
f"Warning, submodule {repo_dir_root} already exist, "
|
||||
"you need to add it in stage."
|
||||
)
|
||||
else:
|
||||
print(f"\nERROR Cannot create submodule {repo_dir_root}."
|
||||
f"Maybe you need to delete .git/modules/{repo_dir_root}\n")
|
||||
print(
|
||||
f"\nERROR Cannot create submodule {repo_dir_root}."
|
||||
f"Maybe you need to delete .git/modules/{repo_dir_root}\n"
|
||||
)
|
||||
return
|
||||
# # Delete appropriate submodule and recreate_submodule
|
||||
# shutil.rmtree(f".git/modules/{repo_dir_root}", ignore_errors=True)
|
||||
|
|
@ -219,14 +248,15 @@ def fork_and_clone_repo(
|
|||
# url=bare_repo.git_dir, branch='master')
|
||||
else:
|
||||
if os.path.isdir(repo_dir):
|
||||
print("Directory %s already exists, assuming it's a clone" % repo_dir)
|
||||
print(
|
||||
"Directory %s already exists, assuming it's a clone" % repo_dir
|
||||
)
|
||||
cloned_repo = Repo(repo_dir)
|
||||
else:
|
||||
cloned_repo = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(Repo.clone_from)(forked_repo['ssh_url'], repo_dir)
|
||||
print("Cloned %s to %s" % (forked_repo['ssh_url'], repo_dir))
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(Repo.clone_from)(forked_repo["ssh_url"], repo_dir)
|
||||
print("Cloned %s to %s" % (forked_repo["ssh_url"], repo_dir))
|
||||
|
||||
# Create the remote upstream
|
||||
try:
|
||||
|
|
@ -234,14 +264,14 @@ def fork_and_clone_repo(
|
|||
print('Remote "%s" already exists in %s' % (upstream_name, repo_dir))
|
||||
except ValueError:
|
||||
upstream_remote = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(cloned_repo.create_remote)(upstream_name, upstream_url)
|
||||
print('Remote "%s" created for %s' % (upstream_name, upstream_url))
|
||||
|
||||
# Fetch the remote upstream
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
upstream_remote.fetch)()
|
||||
upstream_remote.fetch
|
||||
)()
|
||||
print('Remote "%s" fetched' % upstream_name)
|
||||
|
||||
# Create and checkout the branch
|
||||
|
|
@ -255,19 +285,25 @@ def fork_and_clone_repo(
|
|||
branch = cloned_repo.heads[branch_name]
|
||||
print('Branch "%s" already exists' % branch_name)
|
||||
if branch_name not in cloned_repo.remotes.origin.refs:
|
||||
cloned_repo.remotes.origin.push(refspec='{}:{}'.format(
|
||||
branch.path, branch.path))
|
||||
cloned_repo.remotes.origin.push(
|
||||
refspec="{}:{}".format(branch.path, branch.path)
|
||||
)
|
||||
print('Branch "%s" pushed to origin' % branch_name)
|
||||
else:
|
||||
print('Branch "%s" already exists in remote origin' % branch_name)
|
||||
if branch.tracking_branch() is None:
|
||||
branch.set_tracking_branch(
|
||||
cloned_repo.remotes.origin.refs[branch_name])
|
||||
print('Tracking branch "%s" setup for branch "%s"' % (
|
||||
cloned_repo.remotes.origin.refs[branch_name], branch_name))
|
||||
cloned_repo.remotes.origin.refs[branch_name]
|
||||
)
|
||||
print(
|
||||
'Tracking branch "%s" setup for branch "%s"'
|
||||
% (cloned_repo.remotes.origin.refs[branch_name], branch_name)
|
||||
)
|
||||
else:
|
||||
print('Branch "%s" already setup to track "%s"' % (
|
||||
branch_name, cloned_repo.remotes.origin.refs[branch_name]))
|
||||
print(
|
||||
'Branch "%s" already setup to track "%s"'
|
||||
% (branch_name, cloned_repo.remotes.origin.refs[branch_name])
|
||||
)
|
||||
branch.checkout()
|
||||
print('Branch "%s" checked out' % branch_name)
|
||||
return branch
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from git import Repo
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script import fork_github_repo
|
||||
|
|
@ -27,18 +27,30 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--organization",
|
||||
dest="organization",
|
||||
default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github_token",
|
||||
dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('--organization', dest="organization", default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.")
|
||||
parser.add_argument('--github_token', dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -76,21 +88,28 @@ def main():
|
|||
# for remote in working_repo.remotes:
|
||||
if remote_origin:
|
||||
repo_origin_info = GitTool.get_transformed_repo_info_from_url(
|
||||
remote_origin.url, repo_path=repo.get("relative_path"))
|
||||
remote_origin.url, repo_path=repo.get("relative_path")
|
||||
)
|
||||
|
||||
if repo_origin_info.organization not in dct_remote_name.keys():
|
||||
# Add remote
|
||||
upstream_remote = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(working_repo.create_remote)(repo_origin_info.organization,
|
||||
repo_origin_info.url_https)
|
||||
print('Remote "%s" created for %s' % (
|
||||
repo_origin_info.organization, repo_origin_info.url_https))
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(working_repo.create_remote)(
|
||||
repo_origin_info.organization, repo_origin_info.url_https
|
||||
)
|
||||
print(
|
||||
'Remote "%s" created for %s'
|
||||
% (
|
||||
repo_origin_info.organization,
|
||||
repo_origin_info.url_https,
|
||||
)
|
||||
)
|
||||
|
||||
# Fetch the remote
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
upstream_remote.fetch)()
|
||||
upstream_remote.fetch
|
||||
)()
|
||||
print('Remote "%s" fetched' % repo_origin_info.organization)
|
||||
# working_repo.git.remote.remove("origin")
|
||||
upstream_name = organization_name
|
||||
|
|
@ -99,7 +118,9 @@ def main():
|
|||
# [<git.Remote "origin">, <git.Remote "upstream">, <git.Remote "MathBenTech">]
|
||||
|
||||
_logger.info(
|
||||
f"Fork {url} on dir {repo_dir_root} for organization {organization_name}")
|
||||
f"Fork {url} on dir {repo_dir_root} for organization"
|
||||
f" {organization_name}"
|
||||
)
|
||||
|
||||
fork_github_repo.fork_and_clone_repo(
|
||||
url,
|
||||
|
|
@ -117,5 +138,5 @@ def main():
|
|||
GitTool().generate_install_locally()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from git import Repo
|
||||
import git
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -26,24 +26,41 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--organization",
|
||||
dest="organization",
|
||||
default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip_fork",
|
||||
action="store_true",
|
||||
help="Ignore fork to generate only manifest.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f", "--force", action="store_true", help="Force rewrite remote."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--fast", action="store_true", help="Ignore if repo already exist."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github_token",
|
||||
dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('--organization', dest="organization", default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.")
|
||||
parser.add_argument("--skip_fork", action="store_true",
|
||||
help="Ignore fork to generate only manifest.")
|
||||
parser.add_argument('-f', "--force", action="store_true",
|
||||
help="Force rewrite remote.")
|
||||
parser.add_argument("--fast", action="store_true",
|
||||
help="Ignore if repo already exist.")
|
||||
parser.add_argument('--github_token', dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -58,12 +75,21 @@ def main():
|
|||
raise ValueError("Missing github_token")
|
||||
|
||||
organization_name = config.organization
|
||||
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True)
|
||||
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"), repo_path=config.dir, organization_force=organization_name,
|
||||
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"), clone_depth=a.get("clone_depth"))
|
||||
for a in lst_repo]
|
||||
lst_repo = git_tool.get_source_repo_addons(
|
||||
repo_path=config.dir, add_repo_root=True
|
||||
)
|
||||
lst_repo_organization = [
|
||||
git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"),
|
||||
repo_path=config.dir,
|
||||
organization_force=organization_name,
|
||||
is_submodule=a.get("is_submodule"),
|
||||
sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"),
|
||||
clone_depth=a.get("clone_depth"),
|
||||
)
|
||||
for a in lst_repo
|
||||
]
|
||||
|
||||
if not config.skip_fork:
|
||||
i = 0
|
||||
|
|
@ -71,7 +97,11 @@ def main():
|
|||
for repo in lst_repo:
|
||||
i += 1
|
||||
print(f"Nb element {i}/{total} - {repo.get('project_name')}")
|
||||
if config.fast and repo.get("is_submodule") and os.path.isdir(repo.get("path")):
|
||||
if (
|
||||
config.fast
|
||||
and repo.get("is_submodule")
|
||||
and os.path.isdir(repo.get("path"))
|
||||
):
|
||||
continue
|
||||
url = repo.get("url")
|
||||
|
||||
|
|
@ -83,16 +113,22 @@ def main():
|
|||
# url, organization_force="ERPLibre",
|
||||
# is_submodule=repo.get("is_submodule"),
|
||||
# sub_path=repo.get("sub_path"))
|
||||
git_tool.fork_repo(upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name="ERPLibre")
|
||||
git_tool.fork_repo(
|
||||
upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name="ERPLibre",
|
||||
)
|
||||
repo_info = git_tool.get_transformed_repo_info_from_url(
|
||||
url, organization_force=organization_name,
|
||||
url,
|
||||
organization_force=organization_name,
|
||||
is_submodule=repo.get("is_submodule"),
|
||||
sub_path=repo.get("sub_path"))
|
||||
git_tool.fork_repo(upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name=organization_name)
|
||||
sub_path=repo.get("sub_path"),
|
||||
)
|
||||
git_tool.fork_repo(
|
||||
upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name=organization_name,
|
||||
)
|
||||
|
||||
# git_tool.add_and_fetch_remote(repo_info, root_repo=root_repo)
|
||||
continue
|
||||
|
|
@ -104,18 +140,25 @@ def main():
|
|||
|
||||
if not remote_erplibre:
|
||||
repo_info = git_tool.get_transformed_repo_info_from_url(
|
||||
url, organization_force="ERPLibre",
|
||||
url,
|
||||
organization_force="ERPLibre",
|
||||
is_submodule=repo.get("is_submodule"),
|
||||
sub_path=repo.get("sub_path"))
|
||||
sub_path=repo.get("sub_path"),
|
||||
)
|
||||
# git_tool.add_and_fetch_remote(repo_info)
|
||||
|
||||
git_tool.fork_repo(url, github_token,
|
||||
organization_name=organization_name,
|
||||
)
|
||||
git_tool.fork_repo(
|
||||
url,
|
||||
github_token,
|
||||
organization_name=organization_name,
|
||||
)
|
||||
|
||||
repo_info = git_tool.get_transformed_repo_info_from_url(
|
||||
url, organization_force=organization_name,
|
||||
is_submodule=repo.get("is_submodule"), sub_path=repo.get("sub_path"))
|
||||
url,
|
||||
organization_force=organization_name,
|
||||
is_submodule=repo.get("is_submodule"),
|
||||
sub_path=repo.get("sub_path"),
|
||||
)
|
||||
if remote_origin:
|
||||
working_repo.git.remote("remove", "origin")
|
||||
repo_info.organization = "origin"
|
||||
|
|
@ -131,10 +174,11 @@ def main():
|
|||
|
||||
# Update origin to new repo
|
||||
# git_tool.generate_git_modules(lst_repo_organization, repo_path=config.dir)
|
||||
git_tool.generate_repo_manifest(lst_repo_organization,
|
||||
output=f"{config.dir}manifest/default.dev.xml")
|
||||
git_tool.generate_repo_manifest(
|
||||
lst_repo_organization, output=f"{config.dir}manifest/default.dev.xml"
|
||||
)
|
||||
git_tool.generate_install_locally()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from git import Repo
|
|||
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script import git_tool
|
||||
|
|
@ -27,28 +27,51 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github_token",
|
||||
dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--open_web_browser",
|
||||
action="store_true",
|
||||
help="Open web browser for each repo.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--generate_only_install_locally",
|
||||
action="store_true",
|
||||
help="Only generate script install_locally.sh.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--sync_to",
|
||||
dest="sync_to",
|
||||
help="Only synchronize matching repo, use path compare to repo.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry_sync",
|
||||
dest="dry_sync",
|
||||
action="store_true",
|
||||
help="Don't apply modification when sync_to.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--sync_with_submodule",
|
||||
dest="sync_with_submodule",
|
||||
action="store_true",
|
||||
help="Remote directory use submodule to sync.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('--github_token', dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user")
|
||||
parser.add_argument("--open_web_browser", action="store_true",
|
||||
help="Open web browser for each repo.")
|
||||
parser.add_argument("--generate_only_install_locally", action="store_true",
|
||||
help="Only generate script install_locally.sh.")
|
||||
parser.add_argument("--sync_to", dest="sync_to",
|
||||
help="Only synchronize matching repo, use path compare to "
|
||||
"repo.")
|
||||
parser.add_argument("--dry_sync", dest="dry_sync", action="store_true",
|
||||
help="Don't apply modification when sync_to.")
|
||||
parser.add_argument("--sync_with_submodule", dest="sync_with_submodule",
|
||||
action="store_true",
|
||||
help="Remote directory use submodule to sync.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -68,9 +91,11 @@ def main():
|
|||
if config.sync_to[-1] != "/":
|
||||
config.sync_to += "/"
|
||||
gt = git_tool.GitTool()
|
||||
result = gt.get_matching_repo(repo_compare_to=config.sync_to,
|
||||
force_normalize_compare=True,
|
||||
sync_with_submodule=config.sync_with_submodule)
|
||||
result = gt.get_matching_repo(
|
||||
repo_compare_to=config.sync_to,
|
||||
force_normalize_compare=True,
|
||||
sync_with_submodule=config.sync_with_submodule,
|
||||
)
|
||||
gt.sync_to(result, checkout_when_diff=not config.dry_sync)
|
||||
return
|
||||
|
||||
|
|
@ -109,28 +134,34 @@ def main():
|
|||
# # print(f"ERROR, missing branch 12.0 for {repo_dir_root}")
|
||||
|
||||
_logger.info(
|
||||
f"Fork {url} on dir {repo_dir_root} for organization {organization_name}")
|
||||
f"Fork {url} on dir {repo_dir_root} for organization"
|
||||
f" {organization_name}"
|
||||
)
|
||||
|
||||
try:
|
||||
upstream_remote = cloned_repo.remote(upstream_name)
|
||||
print('Remote "%s" already exists in %s' %
|
||||
(upstream_name, repo_dir_root))
|
||||
print(
|
||||
'Remote "%s" already exists in %s'
|
||||
% (upstream_name, repo_dir_root)
|
||||
)
|
||||
except ValueError:
|
||||
upstream_remote = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(cloned_repo.create_remote)(upstream_name, upstream_url)
|
||||
print('Remote "%s" created for %s' % (upstream_name, upstream_url))
|
||||
|
||||
try:
|
||||
# Fetch the remote upstream
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
upstream_remote.fetch)()
|
||||
upstream_remote.fetch
|
||||
)()
|
||||
print('Remote "%s" fetched' % upstream_name)
|
||||
except Exception:
|
||||
print(f"ERROR git {repo_dir_root} remote {upstream_name} not exist.")
|
||||
print(
|
||||
f"ERROR git {repo_dir_root} remote {upstream_name} not exist."
|
||||
)
|
||||
upstream_remote.remove(cloned_repo, upstream_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import sys
|
|||
|
||||
from git import Repo
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -27,18 +27,32 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--upstream",
|
||||
dest="upstream",
|
||||
help=(
|
||||
"Upstream name to change address https to git. "
|
||||
"When empty, all upstream is updated."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--git_to_https",
|
||||
action="store_true",
|
||||
help="Replace all repo git to https.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('-f', '--upstream', dest="upstream",
|
||||
help="Upstream name to change address https to git. "
|
||||
"When empty, all upstream is updated.")
|
||||
parser.add_argument("--git_to_https", action="store_true",
|
||||
help="Replace all repo git to https.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -54,10 +68,16 @@ def main():
|
|||
for repo in lst_repo:
|
||||
i += 1
|
||||
print(f"Nb element {i}/{total}")
|
||||
repo_sm = Repo(repo.get("name"))
|
||||
repo_name = repo.get("name")
|
||||
relative_path = os.path.join(new_path, repo_name)
|
||||
if not os.path.isdir(relative_path):
|
||||
print(f"Ignore repo {relative_path}")
|
||||
continue
|
||||
repo_sm = Repo(repo_name)
|
||||
if upstream_name:
|
||||
remote_upstream_name = [a for a in repo_sm.remotes
|
||||
if upstream_name == a.name]
|
||||
remote_upstream_name = [
|
||||
a for a in repo_sm.remotes if upstream_name == a.name
|
||||
]
|
||||
else:
|
||||
remote_upstream_name = [a for a in repo_sm.remotes]
|
||||
|
||||
|
|
@ -68,5 +88,5 @@ def main():
|
|||
print(f'Remote "{remote.name}" update for {new_url}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import argparse
|
|||
import logging
|
||||
from git import Repo
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -24,13 +24,19 @@ def get_config():
|
|||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Get git diff between manifest repo revision,
|
||||
diff revision input1 to input2 """,
|
||||
epilog='''\
|
||||
'''
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input1",
|
||||
required=True,
|
||||
help="Compare input1 to input2. Input1 is older config.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input2",
|
||||
required=True,
|
||||
help="Compare input1 to input2. Input2 is newer config.",
|
||||
)
|
||||
parser.add_argument('--input1', required=True,
|
||||
help="Compare input1 to input2. Input1 is older config.")
|
||||
parser.add_argument('--input2', required=True,
|
||||
help="Compare input1 to input2. Input2 is newer config.")
|
||||
# parser.add_argument('--clear', action="store_true",
|
||||
# help="Create a new manifest and clear old configuration.")
|
||||
args = parser.parse_args()
|
||||
|
|
@ -41,10 +47,16 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
dct_remote_1, dct_project_1, default_remote_1 = git_tool.get_manifest_xml_info(
|
||||
filename=config.input1, add_root=True)
|
||||
dct_remote_2, dct_project_2, default_remote_2 = git_tool.get_manifest_xml_info(
|
||||
filename=config.input2, add_root=True)
|
||||
(
|
||||
dct_remote_1,
|
||||
dct_project_1,
|
||||
default_remote_1,
|
||||
) = git_tool.get_manifest_xml_info(filename=config.input1, add_root=True)
|
||||
(
|
||||
dct_remote_2,
|
||||
dct_project_2,
|
||||
default_remote_2,
|
||||
) = git_tool.get_manifest_xml_info(filename=config.input2, add_root=True)
|
||||
|
||||
set_project_1 = set(dct_project_1.keys())
|
||||
set_project_2 = set(dct_project_2.keys())
|
||||
|
|
@ -75,14 +87,18 @@ def main():
|
|||
path1 = value1.get("@path")
|
||||
path2 = value2.get("@path")
|
||||
if path1 != path2:
|
||||
print(f"WARNING id {i}, path of git are different. "
|
||||
f"Input1 {path1}, input2 {path2}")
|
||||
print(
|
||||
f"WARNING id {i}, path of git are different. "
|
||||
f"Input1 {path1}, input2 {path2}"
|
||||
)
|
||||
continue
|
||||
|
||||
i += 1
|
||||
result = "same" if old_revision == new_revision else "diff"
|
||||
print(f"{i}/{total} - {result} - "
|
||||
f"{path1} {key} old {old_revision} new {new_revision}")
|
||||
print(
|
||||
f"{i}/{total} - {result} - "
|
||||
f"{path1} {key} old {old_revision} new {new_revision}"
|
||||
)
|
||||
default_arg = [f"{old_revision}..{new_revision}"]
|
||||
if old_revision != new_revision:
|
||||
# get git diff
|
||||
|
|
@ -91,5 +107,5 @@ def main():
|
|||
print(status)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import argparse
|
|||
import logging
|
||||
import copy
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -23,15 +23,18 @@ def get_config():
|
|||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Replace revision field in input2 from input1 if existing, create an output of new manifest.""",
|
||||
epilog='''\
|
||||
'''
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input1", required=True, help="First manifest to merge into input2."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input2", required=True, help="Second manifest, overwrite by input1."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output", required=True, help="Output of new manifest"
|
||||
)
|
||||
parser.add_argument('--input1', required=True,
|
||||
help="First manifest to merge into input2.")
|
||||
parser.add_argument('--input2', required=True,
|
||||
help="Second manifest, overwrite by input1.")
|
||||
parser.add_argument('--output', required=True,
|
||||
help="Output of new manifest")
|
||||
# parser.add_argument('--clear', action="store_true",
|
||||
# help="Create a new manifest and clear old configuration.")
|
||||
args = parser.parse_args()
|
||||
|
|
@ -42,10 +45,16 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
dct_remote_1, dct_project_1, default_remote_1 = git_tool.get_manifest_xml_info(
|
||||
filename=config.input1, add_root=True)
|
||||
dct_remote_2, dct_project_2, default_remote_2 = git_tool.get_manifest_xml_info(
|
||||
filename=config.input2, add_root=True)
|
||||
(
|
||||
dct_remote_1,
|
||||
dct_project_1,
|
||||
default_remote_1,
|
||||
) = git_tool.get_manifest_xml_info(filename=config.input1, add_root=True)
|
||||
(
|
||||
dct_remote_2,
|
||||
dct_project_2,
|
||||
default_remote_2,
|
||||
) = git_tool.get_manifest_xml_info(filename=config.input2, add_root=True)
|
||||
|
||||
dct_remote_3 = copy.deepcopy(dct_remote_2)
|
||||
dct_project_3 = copy.deepcopy(dct_project_2)
|
||||
|
|
@ -59,10 +68,13 @@ def main():
|
|||
dct_project_3[key]["@dest-branch"] = "12.0"
|
||||
|
||||
# Update origin to new repo
|
||||
git_tool.generate_repo_manifest(dct_remote=dct_remote_3, dct_project=dct_project_3,
|
||||
output=config.output,
|
||||
default_remote=default_remote_2)
|
||||
git_tool.generate_repo_manifest(
|
||||
dct_remote=dct_remote_3,
|
||||
dct_project=dct_project_3,
|
||||
output=config.output,
|
||||
default_remote=default_remote_2,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import argparse
|
||||
import logging
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -21,17 +21,29 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--clear",
|
||||
action="store_true",
|
||||
help="Create a new manifest and clear old configuration.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--manifest",
|
||||
default="manifest/default.dev.xml",
|
||||
help="The manifest file path to generate.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('--clear', action="store_true",
|
||||
help="Create a new manifest and clear old configuration.")
|
||||
parser.add_argument('-m', '--manifest', default="manifest/default.dev.xml",
|
||||
help="The manifest file path to generate.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -40,26 +52,39 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True)
|
||||
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"), repo_path=config.dir, get_obj=True,
|
||||
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"), clone_depth=a.get("clone_depth"))
|
||||
for a in lst_repo]
|
||||
lst_repo = git_tool.get_source_repo_addons(
|
||||
repo_path=config.dir, add_repo_root=True
|
||||
)
|
||||
lst_repo_organization = [
|
||||
git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"),
|
||||
repo_path=config.dir,
|
||||
get_obj=True,
|
||||
is_submodule=a.get("is_submodule"),
|
||||
sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"),
|
||||
clone_depth=a.get("clone_depth"),
|
||||
)
|
||||
for a in lst_repo
|
||||
]
|
||||
|
||||
# Update origin to new repo
|
||||
if not config.clear:
|
||||
dct_remote, dct_project, _ = git_tool.get_manifest_xml_info(
|
||||
repo_path=config.dir, add_root=True)
|
||||
repo_path=config.dir, add_root=True
|
||||
)
|
||||
else:
|
||||
dct_remote = {}
|
||||
dct_project = {}
|
||||
git_tool.generate_repo_manifest(lst_repo_organization,
|
||||
output=f"{config.dir}{config.manifest}",
|
||||
dct_remote=dct_remote, dct_project=dct_project,
|
||||
keep_original=True)
|
||||
git_tool.generate_repo_manifest(
|
||||
lst_repo_organization,
|
||||
output=f"{config.dir}{config.manifest}",
|
||||
dct_remote=dct_remote,
|
||||
dct_project=dct_project,
|
||||
keep_original=True,
|
||||
)
|
||||
git_tool.generate_install_locally()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from git import Repo
|
||||
import git
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -25,14 +25,17 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Update config.conf file with group specified in manifest file.
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--group",
|
||||
default="",
|
||||
help="Prod by default, use 'dev' for manifest/default.dev.xml",
|
||||
)
|
||||
parser.add_argument('--group', default="",
|
||||
help="Prod by default, use 'dev' for manifest/default.dev.xml")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -46,5 +49,5 @@ def main():
|
|||
git_tool.generate_install_locally(filter_group=filter_group)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from git import Repo
|
||||
from git.exc import GitCommandError
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -24,11 +24,15 @@ def get_config():
|
|||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Compare actual code with a manifest.""",
|
||||
epilog='''\
|
||||
'''
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--manifest",
|
||||
required=True,
|
||||
help="The manifest to compare with actual code.",
|
||||
)
|
||||
parser.add_argument('-m', '--manifest', required=True,
|
||||
help="The manifest to compare with actual code.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -37,8 +41,12 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
dct_remote, dct_project, default_remote = git_tool.get_manifest_xml_info(filename=config.manifest, add_root=True)
|
||||
default_branch_name = default_remote.get("@revision", git_tool.default_branch)
|
||||
dct_remote, dct_project, default_remote = git_tool.get_manifest_xml_info(
|
||||
filename=config.manifest, add_root=True
|
||||
)
|
||||
default_branch_name = default_remote.get(
|
||||
"@revision", git_tool.default_branch
|
||||
)
|
||||
i = 0
|
||||
total = len(dct_project)
|
||||
for name, project in dct_project.items():
|
||||
|
|
@ -57,7 +65,9 @@ def main():
|
|||
# TODO maybe need to check divergence with local branch and not remote branch
|
||||
commit_head = git_repo.git.rev_parse("HEAD")
|
||||
try:
|
||||
commit_branch = git_repo.git.rev_parse(f"{organization}/{branch_name}")
|
||||
commit_branch = git_repo.git.rev_parse(
|
||||
f"{organization}/{branch_name}"
|
||||
)
|
||||
except GitCommandError:
|
||||
print("ERROR Something wrong with this repo.")
|
||||
continue
|
||||
|
|
@ -66,10 +76,13 @@ def main():
|
|||
else:
|
||||
print("PASS Not on specified branch, no divergence.")
|
||||
elif branch_name != value:
|
||||
print(f"ERROR, manifest revision is {branch_name} and actual revision is {value}.")
|
||||
print(
|
||||
f"ERROR, manifest revision is {branch_name} and actual"
|
||||
f" revision is {value}."
|
||||
)
|
||||
else:
|
||||
print("PASS")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -59,13 +59,17 @@ class GitTool:
|
|||
|
||||
return url, url_https, url_git
|
||||
|
||||
def get_transformed_repo_info_from_url(self, url: str, repo_path: str = "./",
|
||||
get_obj: bool = True,
|
||||
is_submodule: bool = True,
|
||||
organization_force: str = None,
|
||||
sub_path: str = "addons",
|
||||
revision: str = "",
|
||||
clone_depth: str = "") -> object:
|
||||
def get_transformed_repo_info_from_url(
|
||||
self,
|
||||
url: str,
|
||||
repo_path: str = "./",
|
||||
get_obj: bool = True,
|
||||
is_submodule: bool = True,
|
||||
organization_force: str = None,
|
||||
sub_path: str = "addons",
|
||||
revision: str = "",
|
||||
clone_depth: str = "",
|
||||
) -> object:
|
||||
"""
|
||||
|
||||
:param url:
|
||||
|
|
@ -99,8 +103,8 @@ class GitTool:
|
|||
relative_path = os.path.normpath(relative_path)
|
||||
|
||||
original_organization = organization
|
||||
url_https_original_organization = url_https[:url_https.rfind("/")]
|
||||
project_name = url_https[url_https.rfind("/") + 1:]
|
||||
url_https_original_organization = url_https[: url_https.rfind("/")]
|
||||
project_name = url_https[url_https.rfind("/") + 1 :]
|
||||
# begin_original = url_git[url_git.find(":") + 1:]
|
||||
# original_organization = begin_original[:begin_original.find("/")]
|
||||
if organization_force:
|
||||
|
|
@ -109,7 +113,7 @@ class GitTool:
|
|||
url_split[3] = organization
|
||||
url_https = "/".join(url_split)
|
||||
url, _, url_git = self.get_url(url_https)
|
||||
url_https_organization = url_https[:url_https.rfind("/")]
|
||||
url_https_organization = url_https[: url_https.rfind("/")]
|
||||
|
||||
d = {
|
||||
"url": url,
|
||||
|
|
@ -132,15 +136,26 @@ class GitTool:
|
|||
return Struct(**d)
|
||||
return d
|
||||
|
||||
def get_repo_info(self, repo_path: str = "./",
|
||||
add_root: bool = False, is_manifest: bool = True, filter_group=None):
|
||||
def get_repo_info(
|
||||
self,
|
||||
repo_path: str = "./",
|
||||
add_root: bool = False,
|
||||
is_manifest: bool = True,
|
||||
filter_group=None,
|
||||
):
|
||||
if is_manifest:
|
||||
return self.get_repo_info_manifest_xml(repo_path=repo_path,
|
||||
add_root=add_root, filter_group=filter_group)
|
||||
return self.get_repo_info_submodule(repo_path=repo_path, add_root=add_root)
|
||||
return self.get_repo_info_manifest_xml(
|
||||
repo_path=repo_path,
|
||||
add_root=add_root,
|
||||
filter_group=filter_group,
|
||||
)
|
||||
return self.get_repo_info_submodule(
|
||||
repo_path=repo_path, add_root=add_root
|
||||
)
|
||||
|
||||
def get_repo_info_submodule(self, repo_path: str = "./",
|
||||
add_root: bool = False) -> list:
|
||||
def get_repo_info_submodule(
|
||||
self, repo_path: str = "./", add_root: bool = False
|
||||
) -> list:
|
||||
"""
|
||||
Get information about submodule from repo_path
|
||||
:param repo_path: path of repo to get information about submodule
|
||||
|
|
@ -166,7 +181,7 @@ class GitTool:
|
|||
first_execution = True
|
||||
for line in txt:
|
||||
no_line += 1
|
||||
if line[:12] == "[submodule \"":
|
||||
if line[:12] == '[submodule "':
|
||||
if not first_execution:
|
||||
data = {
|
||||
"url": url,
|
||||
|
|
@ -220,8 +235,9 @@ class GitTool:
|
|||
lst_repo = sorted(lst_repo, key=lambda k: k.get("name"))
|
||||
return lst_repo
|
||||
|
||||
def get_repo_info_manifest_xml(self, repo_path: str = "./",
|
||||
add_root: bool = False, filter_group=None) -> list:
|
||||
def get_repo_info_manifest_xml(
|
||||
self, repo_path: str = "./", add_root: bool = False, filter_group=None
|
||||
) -> list:
|
||||
"""
|
||||
Get information about manifest of Repo from repo_path
|
||||
:param repo_path: path of repo to get information about submodule
|
||||
|
|
@ -255,7 +271,7 @@ class GitTool:
|
|||
dct_remote = {a.get("@name"): a.get("@fetch") for a in lst_remote}
|
||||
for project in lst_project:
|
||||
groups = project.get("@groups")
|
||||
lst_group = groups.split(',') if groups else []
|
||||
lst_group = groups.split(",") if groups else []
|
||||
# Continue if lst_filter exist and group in filter
|
||||
for group in lst_group:
|
||||
if lst_filter_group and group not in lst_filter_group:
|
||||
|
|
@ -290,9 +306,11 @@ class GitTool:
|
|||
try:
|
||||
url = repo_root.git.remote("get-url", "origin")
|
||||
except Exception as e:
|
||||
print(f"WARNING: Missing origin remote, use default url "
|
||||
f"{DEFAULT_REMOTE_URL}. Suggest to add a remote origin: \n"
|
||||
f"> git remote add origin {DEFAULT_REMOTE_URL}")
|
||||
print(
|
||||
"WARNING: Missing origin remote, use default url "
|
||||
f"{DEFAULT_REMOTE_URL}. Suggest to add a remote origin: \n"
|
||||
f"> git remote add origin {DEFAULT_REMOTE_URL}"
|
||||
)
|
||||
url = DEFAULT_REMOTE_URL
|
||||
url, url_https, url_git = self.get_url(url)
|
||||
|
||||
|
|
@ -308,8 +326,9 @@ class GitTool:
|
|||
lst_repo = sorted(lst_repo, key=lambda k: k.get("name"))
|
||||
return lst_repo
|
||||
|
||||
def get_manifest_xml_info(self, repo_path: str = "./", filename=None,
|
||||
add_root: bool = False) -> list:
|
||||
def get_manifest_xml_info(
|
||||
self, repo_path: str = "./", filename=None, add_root: bool = False
|
||||
) -> list:
|
||||
"""
|
||||
Get contain of manifest
|
||||
:param repo_path: path of repo to get information about submodule
|
||||
|
|
@ -366,15 +385,22 @@ class GitTool:
|
|||
|
||||
def generate_install_locally(self, repo_path="./", filter_group=None):
|
||||
filename_locally = f"{repo_path}script/install_locally.sh"
|
||||
lst_repo = self.get_repo_info(repo_path=repo_path, filter_group=filter_group)
|
||||
lst_repo = self.get_repo_info(
|
||||
repo_path=repo_path, filter_group=filter_group
|
||||
)
|
||||
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"):
|
||||
if (
|
||||
"addons/OCA_web" == repo.get("path")
|
||||
or "odoo" == repo.get("path")
|
||||
or "ERPLibre_image_db" == repo.get("path")
|
||||
):
|
||||
continue
|
||||
str_repo = f' printf "${{EL_HOME}}/{repo.get("path")}," >> ' \
|
||||
f'${{EL_CONFIG_FILE}}\n'
|
||||
str_repo = (
|
||||
f' printf "${{EL_HOME}}/{repo.get("path")}," >> '
|
||||
"${EL_CONFIG_FILE}\n"
|
||||
)
|
||||
lst_result.append(str_repo)
|
||||
with open(filename_locally) as file:
|
||||
all_lines = file.readlines()
|
||||
|
|
@ -383,8 +409,10 @@ class GitTool:
|
|||
find_index = False
|
||||
index_find = 0
|
||||
for line in all_lines:
|
||||
if not find_index and \
|
||||
"if [[ ${EL_MINIMAL_ADDONS} = \"False\" ]]; then\n" == line:
|
||||
if (
|
||||
not find_index
|
||||
and 'if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then\n' == line
|
||||
):
|
||||
index_find = index + 1
|
||||
for insert_line in lst_result:
|
||||
all_lines.insert(index_find, insert_line)
|
||||
|
|
@ -398,8 +426,10 @@ class GitTool:
|
|||
index += 1
|
||||
|
||||
if not find_index:
|
||||
print(f"ERROR cannot regenerate file {filename_locally}, "
|
||||
f"did you change the header?")
|
||||
print(
|
||||
f"ERROR cannot regenerate file {filename_locally}, "
|
||||
"did you change the header?"
|
||||
)
|
||||
|
||||
# create file
|
||||
with open(filename_locally, mode="w") as file:
|
||||
|
|
@ -409,9 +439,15 @@ class GitTool:
|
|||
def str_insert(source_str, insert_str, pos):
|
||||
return source_str[:pos] + insert_str + source_str[pos:]
|
||||
|
||||
def generate_repo_manifest(self, lst_repo: List[Struct] = [], output: str = "",
|
||||
dct_remote={}, dct_project={}, default_remote=None,
|
||||
keep_original=False):
|
||||
def generate_repo_manifest(
|
||||
self,
|
||||
lst_repo: List[Struct] = [],
|
||||
output: str = "",
|
||||
dct_remote={},
|
||||
dct_project={},
|
||||
default_remote=None,
|
||||
keep_original=False,
|
||||
):
|
||||
"""
|
||||
Generate repo manifest
|
||||
:param lst_repo: optional, update manifest with list_repo
|
||||
|
|
@ -424,7 +460,9 @@ class GitTool:
|
|||
:return:
|
||||
"""
|
||||
if not output:
|
||||
raise Exception("Cannot generate manifest with missing output filename.")
|
||||
raise Exception(
|
||||
"Cannot generate manifest with missing output filename."
|
||||
)
|
||||
lst_remote = []
|
||||
lst_remote_name = []
|
||||
lst_project = []
|
||||
|
|
@ -433,28 +471,40 @@ class GitTool:
|
|||
|
||||
# Fill with configuration
|
||||
for dct_value in dct_remote.values():
|
||||
lst_remote.append(OrderedDict(
|
||||
[('@name', dct_value.get("@name")),
|
||||
('@fetch', dct_value.get("@fetch"))]
|
||||
))
|
||||
lst_remote.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("@name", dct_value.get("@name")),
|
||||
("@fetch", dct_value.get("@fetch")),
|
||||
]
|
||||
)
|
||||
)
|
||||
lst_remote_name.append(dct_value.get("@name"))
|
||||
for dct_value in dct_project.values():
|
||||
lst_project_info = [
|
||||
('@name', dct_value.get("@name")),
|
||||
('@path', dct_value.get("@path")),
|
||||
("@name", dct_value.get("@name")),
|
||||
("@path", dct_value.get("@path")),
|
||||
]
|
||||
if "@remote" in dct_value.keys():
|
||||
lst_project_info.append(('@remote', dct_value.get("@remote")))
|
||||
lst_project_info.append(("@remote", dct_value.get("@remote")))
|
||||
if "@revision" in dct_value.keys():
|
||||
lst_project_info.append(('@revision', dct_value.get("@revision")))
|
||||
lst_project_info.append(
|
||||
("@revision", dct_value.get("@revision"))
|
||||
)
|
||||
if "@clone-depth" in dct_value.keys():
|
||||
lst_project_info.append(('@clone-depth', dct_value.get("@clone-depth")))
|
||||
lst_project_info.append(
|
||||
("@clone-depth", dct_value.get("@clone-depth"))
|
||||
)
|
||||
if "@groups" in dct_value.keys():
|
||||
lst_project_info.append(('@groups', dct_value.get("@groups")))
|
||||
lst_project_info.append(("@groups", dct_value.get("@groups")))
|
||||
if "@upstream" in dct_value.keys():
|
||||
lst_project_info.append(('@upstream', dct_value.get("@upstream")))
|
||||
lst_project_info.append(
|
||||
("@upstream", dct_value.get("@upstream"))
|
||||
)
|
||||
if "@dest-branch" in dct_value.keys():
|
||||
lst_project_info.append(('@dest-branch', dct_value.get("@dest-branch")))
|
||||
lst_project_info.append(
|
||||
("@dest-branch", dct_value.get("@dest-branch"))
|
||||
)
|
||||
|
||||
lst_project.append(OrderedDict(lst_project_info))
|
||||
lst_project_name.append(dct_value.get("@name"))
|
||||
|
|
@ -463,64 +513,97 @@ class GitTool:
|
|||
if not repo.is_submodule:
|
||||
# Default
|
||||
if lst_default:
|
||||
raise Exception("Cannot have many root repo. "
|
||||
"Validate why 2 or more is not submodule.")
|
||||
lst_default.append(OrderedDict([
|
||||
('@remote', repo.original_organization),
|
||||
('@revision', DEFAULT_BRANCH),
|
||||
('@sync-j', "4"),
|
||||
('@sync-c', "true"),
|
||||
]))
|
||||
raise Exception(
|
||||
"Cannot have many root repo. "
|
||||
"Validate why 2 or more is not submodule."
|
||||
)
|
||||
lst_default.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("@remote", repo.original_organization),
|
||||
("@revision", DEFAULT_BRANCH),
|
||||
("@sync-j", "4"),
|
||||
("@sync-c", "true"),
|
||||
]
|
||||
)
|
||||
)
|
||||
else:
|
||||
if keep_original and repo.project_name not in dct_project.keys():
|
||||
if (
|
||||
keep_original
|
||||
and repo.project_name not in dct_project.keys()
|
||||
):
|
||||
# Exception, create a new remote to keep tracking on original
|
||||
original_organization = f"{repo.original_organization}_origin"
|
||||
original_organization = (
|
||||
f"{repo.original_organization}_origin"
|
||||
)
|
||||
else:
|
||||
original_organization = repo.original_organization
|
||||
# Add remote, only unique remote
|
||||
if original_organization not in lst_remote_name:
|
||||
lst_remote.append(OrderedDict(
|
||||
[('@name', original_organization),
|
||||
('@fetch', repo.url_https_organization + "/")]
|
||||
))
|
||||
lst_remote.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("@name", original_organization),
|
||||
("@fetch", repo.url_https_organization + "/"),
|
||||
]
|
||||
)
|
||||
)
|
||||
lst_remote_name.append(repo.original_organization)
|
||||
# Add project, only unique project
|
||||
if repo.project_name not in lst_project_name:
|
||||
lst_project_name.append(repo.project_name)
|
||||
lst_project_info = [
|
||||
('@name', repo.project_name),
|
||||
('@path', repo.path),
|
||||
('@remote', original_organization),
|
||||
("@name", repo.project_name),
|
||||
("@path", repo.path),
|
||||
("@remote", original_organization),
|
||||
]
|
||||
if repo.revision:
|
||||
lst_project_info.append(('@revision', repo.revision))
|
||||
lst_project_info.append(("@revision", repo.revision))
|
||||
if repo.clone_depth:
|
||||
lst_project_info.append(('@clone-depth', repo.clone_depth))
|
||||
lst_project_info.append(
|
||||
("@clone-depth", repo.clone_depth)
|
||||
)
|
||||
if repo.sub_path == "addons":
|
||||
lst_project_info.append(('@groups', "addons"))
|
||||
lst_project_info.append(("@groups", "addons"))
|
||||
else:
|
||||
lst_project_info.append(('@groups', "odoo"))
|
||||
lst_project_info.append(("@groups", "odoo"))
|
||||
lst_project.append(OrderedDict(lst_project_info))
|
||||
|
||||
if default_remote and not lst_default:
|
||||
lst_default.append(OrderedDict([
|
||||
('@remote', default_remote.get("@remote")),
|
||||
('@revision', DEFAULT_BRANCH),
|
||||
('@sync-j', "4"),
|
||||
('@sync-c', "true"),
|
||||
]))
|
||||
lst_default.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("@remote", default_remote.get("@remote")),
|
||||
("@revision", DEFAULT_BRANCH),
|
||||
("@sync-j", "4"),
|
||||
("@sync-c", "true"),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
# Order in alphabetic
|
||||
lst_order_remote = sorted(lst_remote, key=lambda key: key.get("@name"))
|
||||
lst_order_default = sorted(lst_default, key=lambda key: key.get("@remote"))
|
||||
lst_order_project = sorted(lst_project, key=lambda key: key.get("@name"))
|
||||
lst_order_default = sorted(
|
||||
lst_default, key=lambda key: key.get("@remote")
|
||||
)
|
||||
lst_order_project = sorted(
|
||||
lst_project, key=lambda key: key.get("@name")
|
||||
)
|
||||
|
||||
dct_repo = OrderedDict(
|
||||
[('manifest', OrderedDict([
|
||||
('remote', lst_order_remote),
|
||||
('default', lst_order_default),
|
||||
('project', lst_order_project),
|
||||
]))])
|
||||
[
|
||||
(
|
||||
"manifest",
|
||||
OrderedDict(
|
||||
[
|
||||
("remote", lst_order_remote),
|
||||
("default", lst_order_default),
|
||||
("project", lst_order_project),
|
||||
]
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
str_xml_text = xmltodict.unparse(dct_repo, pretty=True)
|
||||
|
||||
pos_insert = str_xml_text.rfind("</remote>")
|
||||
|
|
@ -541,20 +624,26 @@ class GitTool:
|
|||
str_xml_text = str_xml_text.replace("></remote", "/")
|
||||
str_xml_text = str_xml_text.replace("></default", "/")
|
||||
str_xml_text = str_xml_text.replace("></project", "/")
|
||||
str_xml_text = str_xml_text.replace("encoding=\"utf-8\"", "encoding=\"UTF-8\"")
|
||||
str_xml_text = str_xml_text.replace(
|
||||
'encoding="utf-8"', 'encoding="UTF-8"'
|
||||
)
|
||||
str_xml_text = str_xml_text.replace("\t", " ")
|
||||
|
||||
# create file
|
||||
with open(output, mode="w") as file:
|
||||
file.writelines(str_xml_text + "\n")
|
||||
|
||||
def generate_git_modules(self, lst_repo: List[Struct], repo_path: str = "./"):
|
||||
def generate_git_modules(
|
||||
self, lst_repo: List[Struct], repo_path: str = "./"
|
||||
):
|
||||
lst_modules = []
|
||||
for repo in lst_repo:
|
||||
if repo.is_submodule:
|
||||
lst_modules.append(f"[submodule \"{repo.path}\"]\n"
|
||||
f"\turl = {repo.url_https}\n"
|
||||
f"\tpath = {repo.path}\n")
|
||||
lst_modules.append(
|
||||
f'[submodule "{repo.path}"]\n'
|
||||
f"\turl = {repo.url_https}\n"
|
||||
f"\tpath = {repo.path}\n"
|
||||
)
|
||||
|
||||
# create file
|
||||
with open(f"{repo_path}.gitmodules", mode="w") as file:
|
||||
|
|
@ -581,10 +670,9 @@ class GitTool:
|
|||
# TODO what to do if origin not exist?
|
||||
repo = Repo(repo_path)
|
||||
url = [a for a in repo.remotes][0].url
|
||||
repo_info = self.get_transformed_repo_info_from_url(url,
|
||||
repo_path=repo_path,
|
||||
get_obj=False,
|
||||
is_submodule=False)
|
||||
repo_info = self.get_transformed_repo_info_from_url(
|
||||
url, repo_path=repo_path, get_obj=False, is_submodule=False
|
||||
)
|
||||
lst_result.append(repo_info)
|
||||
with open(file_name) as file:
|
||||
all_lines = file.readlines()
|
||||
|
|
@ -592,8 +680,10 @@ class GitTool:
|
|||
# Validate first line is supported column
|
||||
expected_header = "url,path,revision,clone-depth\n"
|
||||
if all_lines[0] != expected_header:
|
||||
raise Exception(f"Not supported csv, please validate {file_name} "
|
||||
f"with first line {expected_header}")
|
||||
raise Exception(
|
||||
f"Not supported csv, please validate {file_name} "
|
||||
f"with first line {expected_header}"
|
||||
)
|
||||
# Ignore first line
|
||||
all_lines = all_lines[1:]
|
||||
|
||||
|
|
@ -606,7 +696,7 @@ class GitTool:
|
|||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
line_split = line.split(',')
|
||||
line_split = line.split(",")
|
||||
if len(line_split) != 4:
|
||||
print(f"Error with line {line}, suppose to have only 4 ','.")
|
||||
exit(1)
|
||||
|
|
@ -615,12 +705,14 @@ class GitTool:
|
|||
# If begin by http, need to finish by .git
|
||||
if len(url) > 5 and url[0:4] == "http" and url[-4:] != ".git":
|
||||
url = f"{url}.git"
|
||||
repo_info = self.get_transformed_repo_info_from_url(url,
|
||||
repo_path=repo_path,
|
||||
get_obj=False,
|
||||
sub_path=path,
|
||||
revision=revision,
|
||||
clone_depth=clone_depth)
|
||||
repo_info = self.get_transformed_repo_info_from_url(
|
||||
url,
|
||||
repo_path=repo_path,
|
||||
get_obj=False,
|
||||
sub_path=path,
|
||||
revision=revision,
|
||||
clone_depth=clone_depth,
|
||||
)
|
||||
lst_result.append(repo_info)
|
||||
return lst_result
|
||||
|
||||
|
|
@ -634,11 +726,18 @@ class GitTool:
|
|||
with open(file) as xml:
|
||||
xml_as_string = xml.read()
|
||||
xml_dict = xmltodict.parse(xml_as_string, dict_constructor=dict)
|
||||
manifest_filename = xml_dict.get("manifest").get("include").get("@name")
|
||||
manifest_filename = (
|
||||
xml_dict.get("manifest").get("include").get("@name")
|
||||
)
|
||||
return manifest_filename
|
||||
|
||||
def get_matching_repo(self, actual_repo="./", repo_compare_to="./",
|
||||
force_normalize_compare=False, sync_with_submodule=False):
|
||||
def get_matching_repo(
|
||||
self,
|
||||
actual_repo="./",
|
||||
repo_compare_to="./",
|
||||
force_normalize_compare=False,
|
||||
sync_with_submodule=False,
|
||||
):
|
||||
"""
|
||||
Compare repo with .gitmodules files
|
||||
:param actual_repo:
|
||||
|
|
@ -653,12 +752,15 @@ class GitTool:
|
|||
# set_actual_repo = set(
|
||||
# [a[a.find("_") + 1:] for a in dct_repo_info_actual.keys()])
|
||||
|
||||
dct_repo_info_actual_adapted = {key[key.find("_") + 1:]: item for key, item in
|
||||
dct_repo_info_actual.items()}
|
||||
dct_repo_info_actual_adapted = {
|
||||
key[key.find("_") + 1 :]: item
|
||||
for key, item in dct_repo_info_actual.items()
|
||||
}
|
||||
set_actual_repo = set(dct_repo_info_actual_adapted.keys())
|
||||
|
||||
lst_repo_info_compare = self.get_repo_info(repo_compare_to,
|
||||
is_manifest=not sync_with_submodule)
|
||||
lst_repo_info_compare = self.get_repo_info(
|
||||
repo_compare_to, is_manifest=not sync_with_submodule
|
||||
)
|
||||
if force_normalize_compare:
|
||||
for repo_info in lst_repo_info_compare:
|
||||
url_https = repo_info.get("url_https")
|
||||
|
|
@ -671,7 +773,9 @@ class GitTool:
|
|||
name = f"{repo_name}"
|
||||
repo_info["name"] = name
|
||||
|
||||
dct_repo_info_compare = {a.get("name"): a for a in lst_repo_info_compare}
|
||||
dct_repo_info_compare = {
|
||||
a.get("name"): a for a in lst_repo_info_compare
|
||||
}
|
||||
set_compare = set(dct_repo_info_compare.keys())
|
||||
|
||||
# TODO finish the match
|
||||
|
|
@ -681,16 +785,17 @@ class GitTool:
|
|||
lst_same_name_normalize = set_actual_repo.intersection(set_compare)
|
||||
lst_missing_name_normalize = set_compare.difference(set_actual_repo)
|
||||
lst_over_name_normalize = set_actual_repo.difference(set_compare)
|
||||
print(f"Has {len(lst_same_name_normalize)} sames, "
|
||||
f"{len(lst_missing_name_normalize)} missing, "
|
||||
f"{len(lst_over_name_normalize)} more.")
|
||||
print(
|
||||
f"Has {len(lst_same_name_normalize)} sames, "
|
||||
f"{len(lst_missing_name_normalize)} missing, "
|
||||
f"{len(lst_over_name_normalize)} more."
|
||||
)
|
||||
|
||||
lst_match = []
|
||||
for key in lst_same_name_normalize:
|
||||
lst_match.append((
|
||||
dct_repo_info_actual_adapted[key],
|
||||
dct_repo_info_compare[key]
|
||||
))
|
||||
lst_match.append(
|
||||
(dct_repo_info_actual_adapted[key], dct_repo_info_compare[key])
|
||||
)
|
||||
|
||||
return lst_match, lst_missing_name_normalize, lst_over_name_normalize
|
||||
|
||||
|
|
@ -728,14 +833,18 @@ class GitTool:
|
|||
repo_compare = Repo(compare_to.get("relative_path"))
|
||||
commit_compare = repo_compare.head.object.hexsha
|
||||
if commit_original != commit_compare:
|
||||
print(f"DIFF - {original.get('name')} - O {commit_original} - "
|
||||
f"R {commit_compare}")
|
||||
print(
|
||||
f"DIFF - {original.get('name')} - O {commit_original} - "
|
||||
f"R {commit_compare}"
|
||||
)
|
||||
lst_diff.append((original, compare_to))
|
||||
if checkout_when_diff:
|
||||
# Update all remote
|
||||
for remote in repo_original.remotes:
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
remote.fetch)()
|
||||
retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000,
|
||||
)(remote.fetch)()
|
||||
repo_original.git.checkout(commit_compare)
|
||||
else:
|
||||
print(f"SAME - {original.get('name')}")
|
||||
|
|
@ -743,8 +852,9 @@ class GitTool:
|
|||
print(f"finish same {len(lst_same)}, diff {len(lst_diff)}")
|
||||
|
||||
@staticmethod
|
||||
def add_and_fetch_remote(repo_info: Struct, root_repo: Repo = None,
|
||||
branch_name: str = ""):
|
||||
def add_and_fetch_remote(
|
||||
repo_info: Struct, root_repo: Repo = None, branch_name: str = ""
|
||||
):
|
||||
"""
|
||||
Deprecated function, not use anymore git submodule
|
||||
:param repo_info:
|
||||
|
|
@ -754,42 +864,57 @@ class GitTool:
|
|||
"""
|
||||
try:
|
||||
working_repo = Repo(repo_info.relative_path)
|
||||
if repo_info.organization in [a.name for a in working_repo.remotes]:
|
||||
print(f"Remote \"{repo_info.organization}\" already exist "
|
||||
f"in {repo_info.relative_path}")
|
||||
if repo_info.organization in [
|
||||
a.name for a in working_repo.remotes
|
||||
]:
|
||||
print(
|
||||
f'Remote "{repo_info.organization}" already exist '
|
||||
f"in {repo_info.relative_path}"
|
||||
)
|
||||
return
|
||||
except git.NoSuchPathError:
|
||||
print(f"New repo {repo_info.relative_path}")
|
||||
if not root_repo:
|
||||
print(f"Missing git repository to root for repo {repo_info.path}")
|
||||
print(
|
||||
f"Missing git repository to root for repo {repo_info.path}"
|
||||
)
|
||||
return
|
||||
if branch_name:
|
||||
submodule_repo = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(root_repo.create_submodule)(repo_info.path, repo_info.path,
|
||||
url=repo_info.url_https,
|
||||
branch=branch_name)
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(root_repo.create_submodule)(
|
||||
repo_info.path,
|
||||
repo_info.path,
|
||||
url=repo_info.url_https,
|
||||
branch=branch_name,
|
||||
)
|
||||
else:
|
||||
submodule_repo = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
)(root_repo.create_submodule)(repo_info.path, repo_info.path,
|
||||
url=repo_info.url_https)
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(root_repo.create_submodule)(
|
||||
repo_info.path, repo_info.path, url=repo_info.url_https
|
||||
)
|
||||
return
|
||||
# Add remote
|
||||
upstream_remote = retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
working_repo.create_remote)(repo_info.organization, repo_info.url_https)
|
||||
print('Remote "%s" created for %s' % (
|
||||
repo_info.organization, repo_info.url_https))
|
||||
upstream_remote = retry(
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(working_repo.create_remote)(
|
||||
repo_info.organization, repo_info.url_https
|
||||
)
|
||||
print(
|
||||
'Remote "%s" created for %s'
|
||||
% (repo_info.organization, repo_info.url_https)
|
||||
)
|
||||
|
||||
# Fetch the remote
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
upstream_remote.fetch)()
|
||||
upstream_remote.fetch
|
||||
)()
|
||||
print('Remote "%s" fetched' % repo_info.organization)
|
||||
|
||||
def get_pull_request_repo(self, upstream_url: str, github_token: str,
|
||||
organization_name: str = ""):
|
||||
def get_pull_request_repo(
|
||||
self, upstream_url: str, github_token: str, organization_name: str = ""
|
||||
):
|
||||
"""
|
||||
|
||||
:param upstream_url:
|
||||
|
|
@ -802,7 +927,9 @@ class GitTool:
|
|||
|
||||
# Fork the repo
|
||||
status, user = gh.user.get()
|
||||
user_name = user['login'] if not organization_name else organization_name
|
||||
user_name = (
|
||||
user["login"] if not organization_name else organization_name
|
||||
)
|
||||
status, lst_pull = gh.repos[user_name][parsed_url.repo].pulls.get()
|
||||
if type(lst_pull) is dict:
|
||||
print(f"For url {upstream_url}, got {lst_pull.get('message')}")
|
||||
|
|
@ -812,34 +939,41 @@ class GitTool:
|
|||
print(pull.get("html_url"))
|
||||
return lst_pull
|
||||
|
||||
def fork_repo(self, upstream_url: str, github_token: str,
|
||||
organization_name: str = ""):
|
||||
def fork_repo(
|
||||
self, upstream_url: str, github_token: str, organization_name: str = ""
|
||||
):
|
||||
# https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-scopes-for-oauth-apps/
|
||||
gh = GitHub(token=github_token)
|
||||
parsed_url = parse(upstream_url)
|
||||
|
||||
# Fork the repo
|
||||
status, user = gh.user.get()
|
||||
user_name = user['login'] if not organization_name else organization_name
|
||||
user_name = (
|
||||
user["login"] if not organization_name else organization_name
|
||||
)
|
||||
status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
|
||||
if status == 404:
|
||||
status, upstream_repo = (
|
||||
gh.repos[parsed_url.owner][parsed_url.repo].get())
|
||||
status, upstream_repo = gh.repos[parsed_url.owner][
|
||||
parsed_url.repo
|
||||
].get()
|
||||
if status == 404:
|
||||
print("Unable to find repo %s" % upstream_url)
|
||||
exit(1)
|
||||
args = {}
|
||||
if organization_name:
|
||||
args["organization"] = organization_name
|
||||
status, forked_repo = (
|
||||
gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args))
|
||||
status, forked_repo = gh.repos[parsed_url.owner][
|
||||
parsed_url.repo
|
||||
].forks.post(**args)
|
||||
if status == 404:
|
||||
print("Error when forking repo %s" % forked_repo)
|
||||
exit(1)
|
||||
else:
|
||||
print("Forked %s to %s" % (upstream_url, forked_repo['html_url']))
|
||||
print(
|
||||
"Forked %s to %s" % (upstream_url, forked_repo["html_url"])
|
||||
)
|
||||
elif status == 202:
|
||||
print("Forked repo %s already exists" % forked_repo['full_name'])
|
||||
print("Forked repo %s already exists" % forked_repo["full_name"])
|
||||
elif status != 200:
|
||||
print("Status not supported: %s - %s" % (status, forked_repo))
|
||||
exit(1)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from git import Repo # pip install gitpython
|
||||
from retrying import retry # pip install retrying
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -23,13 +23,18 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -38,13 +43,21 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir,
|
||||
add_repo_root=False)
|
||||
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"), repo_path=config.dir, get_obj=True,
|
||||
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"), clone_depth=a.get("clone_depth"))
|
||||
for a in lst_repo]
|
||||
lst_repo = git_tool.get_source_repo_addons(
|
||||
repo_path=config.dir, add_repo_root=False
|
||||
)
|
||||
lst_repo_organization = [
|
||||
git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"),
|
||||
repo_path=config.dir,
|
||||
get_obj=True,
|
||||
is_submodule=a.get("is_submodule"),
|
||||
sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"),
|
||||
clone_depth=a.get("clone_depth"),
|
||||
)
|
||||
for a in lst_repo
|
||||
]
|
||||
|
||||
i = 0
|
||||
total = len(lst_repo)
|
||||
|
|
@ -61,17 +74,22 @@ def main():
|
|||
# 1. Add remote if not exist
|
||||
try:
|
||||
upstream_remote = git_repo.remote(upstream_name)
|
||||
print(f'Remote "{upstream_name}" already exists in {repo.relative_path}')
|
||||
print(
|
||||
f'Remote "{upstream_name}" already exists in'
|
||||
f" {repo.relative_path}"
|
||||
)
|
||||
except ValueError:
|
||||
upstream_remote = retry(
|
||||
wait_exponential_multiplier=1000,
|
||||
stop_max_delay=15000
|
||||
wait_exponential_multiplier=1000, stop_max_delay=15000
|
||||
)(git_repo.create_remote)(upstream_name, repo.url_https)
|
||||
print('Remote "%s" created for %s' % (upstream_name, repo.url_https))
|
||||
print(
|
||||
'Remote "%s" created for %s' % (upstream_name, repo.url_https)
|
||||
)
|
||||
|
||||
# 2. Fetch the remote source
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
upstream_remote.fetch)()
|
||||
upstream_remote.fetch
|
||||
)()
|
||||
print('Remote "%s" fetched' % upstream_name)
|
||||
|
||||
# 3. Rebase actual branch with new branch
|
||||
|
|
@ -99,15 +117,19 @@ def main():
|
|||
# push
|
||||
try:
|
||||
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
|
||||
git_repo.git.push)(repo.organization, rev)
|
||||
git_repo.git.push
|
||||
)(repo.organization, rev)
|
||||
except:
|
||||
print("Cannot push, maybe need to push force or resolv rebase conflict",
|
||||
file=sys.stderr)
|
||||
print(
|
||||
"Cannot push, maybe need to push force or resolv rebase"
|
||||
" conflict",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(f"cd {repo.path}")
|
||||
print(f"git diff ERPLibre/v#.#.#..HEAD")
|
||||
print(f"git push --force {repo.organization} {rev}")
|
||||
print(f"cd -")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ echo "\n---- Installing nodeJS NPM and rtlcss for LTR support ----"
|
|||
brew install nodejs npm openssl
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -49,12 +49,18 @@ sudo su - postgres -c "createuser -s ${EL_USER}" 2> /dev/null || true
|
|||
echo -e "\n--- Installing debian dependency --"
|
||||
sudo apt-get install git build-essential wget libxslt-dev libzip-dev libldap2-dev libsasl2-dev libpng12-0 gdebi-core libffi-dev libbz2-dev -y
|
||||
sudo apt-get install libmariadbd-dev -y
|
||||
# Dependencies for pyenv
|
||||
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
|
||||
sudo npm install -g rtlcss
|
||||
sudo npm install -g less
|
||||
|
||||
echo -e "\n---- Test tool ----"
|
||||
sudo npm install -g prettier
|
||||
sudo npm install -g prettier @prettier/plugin-xml
|
||||
|
||||
sudo ln -fs /usr/local/bin/lessc /usr/bin/lessc
|
||||
|
||||
if [ ${EL_INSTALL_NGINX} = "True" ]; then
|
||||
|
|
|
|||
|
|
@ -129,9 +129,10 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then
|
|||
printf "${EL_HOME}/addons/OCA_wms," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/Smile-SA_odoo_addons," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/TechnoLibre_odoo-code-generator," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/TechnoLibre_odoo-code-generator-template," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/camptocamp_odoo-cloud-platform," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/dhongu_deltatech," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/it-projects-llc_odoo-saas-tools," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/it-projects-llc_saas-addons," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/itpp-labs_access-addons," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/itpp-labs_pos-addons," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/addons/itpp-labs_website-addons," >> ${EL_CONFIG_FILE}
|
||||
|
|
@ -154,7 +155,7 @@ if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then
|
|||
printf "${EL_HOME}/doc/itpp-labs_odoo-port-docs," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/doc/itpp-labs_odoo-test-docs," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/doc/odoo_documentation-user," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/image_db," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/script/OCA_maintainer-tools," >> ${EL_CONFIG_FILE}
|
||||
printf "${EL_HOME}/script/OCA_odoo-module-migrator," >> ${EL_CONFIG_FILE}
|
||||
fi
|
||||
printf "\n" >> ${EL_CONFIG_FILE}
|
||||
|
|
@ -177,13 +178,21 @@ if [[ ! -d "./addons/addons" ]]; then
|
|||
fi
|
||||
|
||||
PYENV_PATH=~/.pyenv
|
||||
PYENV_VERSION_PATH=${PYENV_PATH}/versions/3.7.7
|
||||
PYTHON_VERSION=3.7.7
|
||||
PYENV_VERSION_PATH=${PYENV_PATH}/versions/${PYTHON_VERSION}
|
||||
PYTHON_EXEC=${PYENV_VERSION_PATH}/bin/python
|
||||
POETRY_PATH=~/.poetry
|
||||
VENV_PATH=./.venv
|
||||
LOCAL_PYTHON_EXEC=${VENV_PATH}/bin/python
|
||||
VENV_REPO_PATH=${VENV_PATH}/repo
|
||||
VENV_MULTILINGUAL_MARKDOWN_PATH=${VENV_PATH}/multilang_md.py
|
||||
POETRY_VERSION=1.0.10
|
||||
|
||||
echo "Python path version home"
|
||||
echo ${PYENV_VERSION_PATH}
|
||||
echo "Python path version local"
|
||||
echo ${LOCAL_PYTHON_EXEC}
|
||||
|
||||
if [[ ! -d "${PYENV_PATH}" ]]; then
|
||||
echo -e "\n---- Installing pyenv in ${PYENV_PATH} ----"
|
||||
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
|
||||
|
|
@ -195,28 +204,37 @@ eval "$(pyenv init -)"
|
|||
eval "$(pyenv virtualenv-init -)"
|
||||
|
||||
if [[ ! -d "${PYENV_VERSION_PATH}" ]]; then
|
||||
echo -e "\n---- Installing python 3.7.7 with pyenv in ${PYENV_VERSION_PATH} ----"
|
||||
yes n|pyenv install 3.7.7
|
||||
echo -e "\n---- Installing python ${PYTHON_VERSION} with pyenv in ${PYENV_VERSION_PATH} ----"
|
||||
yes n|pyenv install ${PYTHON_VERSION}
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error when installing pyenv"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
pyenv local 3.7.7
|
||||
pyenv local ${PYTHON_VERSION}
|
||||
|
||||
if [[ ! -d ${VENV_PATH} ]]; then
|
||||
echo -e "\n---- Create Virtual environment Python ----"
|
||||
if [[ -e ${PYTHON_EXEC} ]]; then
|
||||
${PYTHON_EXEC} -m venv .venv
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Virtual environment, error when creating .venv"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Missing pyenv, please refer installation guide."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -d "${POETRY_PATH}" ]]; then
|
||||
# Delete directory ~/.poetry and .venv to force update to new version
|
||||
echo -e "\n---- Installing poetry for reliable python package ----"
|
||||
# curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | ${PYTHON_EXEC}
|
||||
curl -fsS -o get-poetry.py https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py
|
||||
python get-poetry.py -y --preview --version ${POETRY_VERSION}
|
||||
fi
|
||||
|
||||
if [[ ! -d ${VENV_PATH} ]]; then
|
||||
echo -e "\n---- Create Virtual environment Python ----"
|
||||
if [[ -e ${PYTHON_EXEC} ]]; then
|
||||
${PYTHON_EXEC} -m venv .venv
|
||||
else
|
||||
echo "Missing pyenv, please refer installation guide."
|
||||
exit 1
|
||||
fi
|
||||
${LOCAL_PYTHON_EXEC} get-poetry.py -y --preview --version ${POETRY_VERSION}
|
||||
fi
|
||||
|
||||
# Install git-repo if missing
|
||||
|
|
@ -229,11 +247,27 @@ if [[ ! -f ${VENV_REPO_PATH} ]]; then
|
|||
sed -i "1 i ${PYTHON_HASHBANG}" ${VENV_REPO_PATH}
|
||||
fi
|
||||
|
||||
# Install Multilingual Markdown Generator if missing
|
||||
if [[ ! -f ${VENV_MULTILINGUAL_MARKDOWN_PATH} ]]; then
|
||||
echo "\n---- Install Multilingual Markdown Generator ----"
|
||||
curl https://raw.githubusercontent.com/ERPLibre/multilingual-markdown/master/multilang_md.py > ${VENV_MULTILINGUAL_MARKDOWN_PATH}
|
||||
chmod +x ${VENV_MULTILINGUAL_MARKDOWN_PATH}
|
||||
sed -i 1d ${VENV_MULTILINGUAL_MARKDOWN_PATH}
|
||||
PYTHON_HASHBANG="#!./.venv/bin/python"
|
||||
sed -i "1 i ${PYTHON_HASHBANG}" ${VENV_MULTILINGUAL_MARKDOWN_PATH}
|
||||
fi
|
||||
|
||||
echo -e "\n---- Installing poetry dependency ----"
|
||||
${VENV_PATH}/bin/pip install --upgrade pip
|
||||
#/home/"${USER}"/.poetry/bin/poetry env use ${PYTHON_EXEC}
|
||||
source $HOME/.poetry/env
|
||||
poetry install
|
||||
# Force python instead of changing env
|
||||
#/home/"${USER}"/.poetry/bin/poetry env use ${LOCAL_PYTHON_EXEC}
|
||||
# source $HOME/.poetry/env
|
||||
${LOCAL_PYTHON_EXEC} ~/.poetry/bin/poetry install
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Poetry installation error."
|
||||
exit 1
|
||||
fi
|
||||
# Delete artifacts created by pip, cause error in next "poetry install"
|
||||
rm -rf artifacts
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,26 @@
|
|||
. ./env_var.sh
|
||||
|
||||
./script/install_locally.sh
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/install_locally.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update git-repo
|
||||
./script/update_manifest_local_dev.sh
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error manifest update, check git-repo."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install maintainer-tools
|
||||
cd script/OCA_maintainer-tools
|
||||
# virtualenv is not installed by default
|
||||
#virtualenv env
|
||||
../../.venv/bin/python -m venv env
|
||||
. env/bin/activate
|
||||
pip install setuptools-rust
|
||||
python setup.py install
|
||||
#${VENV_PATH}/bin/pip install ./script/OCA_maintainer-tools/
|
||||
cd -
|
||||
|
|
|
|||
|
|
@ -3,6 +3,15 @@
|
|||
. ./env_var.sh
|
||||
|
||||
./script/install_locally.sh
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/install_locally.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update git-repo
|
||||
./script/update_manifest_prod.sh
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error manifest update, check git-repo."
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
11
script/maintenance/autopep8.sh
Executable file
11
script/maintenance/autopep8.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
# This will format all python file
|
||||
# argument 1: directory or file to format
|
||||
NPROC=$(nproc)
|
||||
source ./script/OCA_maintainer-tools/env/bin/activate
|
||||
oca-autopep8 -j ${NPROC} --max-line-length 79 -ari $@
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error oca-autopep8 format"
|
||||
exit 1
|
||||
fi
|
||||
10
script/maintenance/black.sh
Executable file
10
script/maintenance/black.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
# This will format all python file
|
||||
# argument 1: directory or file to format
|
||||
source ./.venv/bin/activate
|
||||
black -l 79 --experimental-string-processing -t py37 $@
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error black format"
|
||||
exit 1
|
||||
fi
|
||||
9
script/maintenance/prettier.sh
Executable file
9
script/maintenance/prettier.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
# This will format all js,css,html
|
||||
# argument 1: directory or file to format
|
||||
prettier --write $@
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error prettier format"
|
||||
exit 1
|
||||
fi
|
||||
9
script/maintenance/prettier_xml.sh
Executable file
9
script/maintenance/prettier_xml.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
# This will format all xml
|
||||
# argument 1: directory or file to format
|
||||
prettier --xml-whitespace-sensitivity "ignore" --prose-wrap always --tab-width 4 --no-bracket-spacing --print-width 120 --write $@
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error prettier format"
|
||||
exit 1
|
||||
fi
|
||||
4
script/make.sh
Executable file
4
script/make.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
echo "==$&%== Begin ${@}"
|
||||
time make $@
|
||||
echo "==$&%== End ${@}"
|
||||
8
script/migrate_prod_to_test.sh
Executable file
8
script/migrate_prod_to_test.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
if [ $# -lt 1 ]; then
|
||||
# TODO: print usage
|
||||
echo "Missing database name"
|
||||
exit 1
|
||||
fi
|
||||
source ./.venv/bin/activate
|
||||
python3 ./odoo/odoo-bin -c ./config.conf --limit-time-real 99999 --limit-time-cpu 99999 --stop-after-init -i user_test,disable_mail_server,disable_auto_backup --dev all -d $@
|
||||
24
script/open_terminal_code_generator.sh
Executable file
24
script/open_terminal_code_generator.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
# Open a new gnome-terminal with different path on new tab
|
||||
working_path=`readlink -f .`
|
||||
paths=(
|
||||
"${working_path}/"
|
||||
"${working_path}/addons/TechnoLibre_odoo-code-generator"
|
||||
"${working_path}/addons/TechnoLibre_odoo-code-generator-template"
|
||||
|
||||
)
|
||||
cmd_before="cd "
|
||||
# when change directory, open a new tab with command to execute
|
||||
cmd_after=";gnome-terminal --tab -- bash -c 'git status;bash';"
|
||||
#cmd_after=";gnome-terminal --tab;"
|
||||
|
||||
LONGCMD=""
|
||||
for t in ${paths[@]}; do
|
||||
LONGCMD+=${cmd_before}${t}${cmd_after}
|
||||
done
|
||||
|
||||
#echo $LONGCMD
|
||||
|
||||
# Open all terminal from paths list
|
||||
#echo "gnome-terminal --window -- bash -c \"${LONGCMD}\""
|
||||
gnome-terminal --window -- bash -c "${LONGCMD}"
|
||||
|
|
@ -3,3 +3,9 @@ source $HOME/.poetry/env
|
|||
poetry add -vv $(grep -v ";" ./.venv/build_dependency.txt | grep -v "*" )
|
||||
# poetry add -vv $(grep -v ";" ./.venv/build_dependency.txt | grep -v "*" | sed 's/==/@^/' )
|
||||
# poetry export -f ./.venv/build_dependency.txt --dev | poetry run -- pip install -r /dev/stdin
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Error ./script/poetry_add_build_dependency.sh"
|
||||
cat ./.venv/build_dependency.txt
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from collections import OrderedDict, defaultdict
|
|||
from pathlib import Path
|
||||
import iscompatible
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script import git_tool
|
||||
|
|
@ -27,26 +27,46 @@ def get_config():
|
|||
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
description="""\
|
||||
Update pip dependency in Poetry, clear pyproject.toml, search all dependencies
|
||||
from requirements.txt, search conflict version and generate a new list.
|
||||
Launch Poetry installation.
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Force create new list of dependency, ignore poetry.lock.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="More information in execution, show stats.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('-f', '--force', action="store_true",
|
||||
help="Force create new list of dependency, ignore poetry.lock.")
|
||||
parser.add_argument('-v', '--verbose', action="store_true",
|
||||
help="More information in execution, show stats.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def get_lst_requirements_txt():
|
||||
return list(Path(".").rglob("requirements.[tT][xX][tT]"))
|
||||
# Ignore some item in list
|
||||
lst = [
|
||||
a
|
||||
for a in Path(".").rglob("requirements.[tT][xX][tT]")
|
||||
if not os.path.dirname(a).startswith(".repo/")
|
||||
and not os.path.dirname(a).startswith(".venv/")
|
||||
]
|
||||
return lst
|
||||
|
||||
|
||||
def get_lst_manifest_py():
|
||||
|
|
@ -61,7 +81,8 @@ def combine_requirements(config):
|
|||
:param config:
|
||||
:return:
|
||||
"""
|
||||
priority_filename_requirement = "odoo/requirements.txt"
|
||||
priority_filename_requirement = "requirements.txt"
|
||||
second_priority_filename_requirement = "odoo/requirements.txt"
|
||||
lst_sign = ("==", "!=", ">=", "<=", "<", ">", ";")
|
||||
lst_requirements = []
|
||||
ignore_requirements = ["sys_platform == 'win32'", "python_version < '3.7'"]
|
||||
|
|
@ -71,7 +92,7 @@ def combine_requirements(config):
|
|||
dct_special_condition = defaultdict(list)
|
||||
dct_requirements_module_filename = defaultdict(list)
|
||||
for requirements_filename in lst_requirements_file:
|
||||
with open(requirements_filename, 'r') as f:
|
||||
with open(requirements_filename, "r") as f:
|
||||
for a in f.readlines():
|
||||
b = a.strip()
|
||||
if not b or b[0] == "#":
|
||||
|
|
@ -81,10 +102,14 @@ def combine_requirements(config):
|
|||
for sign in lst_sign:
|
||||
if sign in b:
|
||||
# Exception, some time the sign ; can be first, just check
|
||||
if sign != ";" and ";" in b and b.find(sign) > b.find(";"):
|
||||
module_name = b[:b.find(";")]
|
||||
if (
|
||||
sign != ";"
|
||||
and ";" in b
|
||||
and b.find(sign) > b.find(";")
|
||||
):
|
||||
module_name = b[: b.find(";")]
|
||||
else:
|
||||
module_name = b[:b.find(sign)]
|
||||
module_name = b[: b.find(sign)]
|
||||
module_name = module_name.strip()
|
||||
# Special condition for ";", ignore it
|
||||
if ";" in b:
|
||||
|
|
@ -94,13 +119,15 @@ def combine_requirements(config):
|
|||
if ignore_string in b:
|
||||
break
|
||||
lst_requirements_with_condition.add(module_name)
|
||||
value = b[:b.find(";")].strip()
|
||||
value = b[: b.find(";")].strip()
|
||||
dct_special_condition[module_name].append(b)
|
||||
else:
|
||||
value = b
|
||||
dct_requirements[module_name].add(value)
|
||||
filename = str(requirements_filename)
|
||||
dct_requirements_module_filename[value].append(filename)
|
||||
dct_requirements_module_filename[value].append(
|
||||
filename
|
||||
)
|
||||
break
|
||||
else:
|
||||
dct_requirements[b].add(b)
|
||||
|
|
@ -110,16 +137,19 @@ def combine_requirements(config):
|
|||
|
||||
dct_requirements = get_manifest_external_dependencies(dct_requirements)
|
||||
|
||||
dct_requirements_diff_version = {k: v for k, v in dct_requirements.items() if
|
||||
len(v) > 1}
|
||||
dct_requirements_diff_version = {
|
||||
k: v for k, v in dct_requirements.items() if len(v) > 1
|
||||
}
|
||||
# dct_requirements_same_version = {k: v for k, v in dct_requirements.items() if
|
||||
# len(v) == 1}
|
||||
if config.verbose:
|
||||
# TODO show total repo to compare lst requirements
|
||||
print(f"Total requirements.txt {len(lst_requirements_file)}, "
|
||||
f"total module {len(lst_requirements)}, "
|
||||
f"unique module {len(dct_requirements)}, "
|
||||
f"module with different version {len(dct_requirements_diff_version)}.")
|
||||
print(
|
||||
f"Total requirements.txt {len(lst_requirements_file)}, total"
|
||||
f" module {len(lst_requirements)}, unique module"
|
||||
f" {len(dct_requirements)}, module with different version"
|
||||
f" {len(dct_requirements_diff_version)}."
|
||||
)
|
||||
|
||||
if dct_requirements_diff_version:
|
||||
# Validate compatibility
|
||||
|
|
@ -138,44 +168,71 @@ def combine_requirements(config):
|
|||
# TODO support me in iscompatible lib
|
||||
no_version = result_number[0][1]
|
||||
if "b" in no_version:
|
||||
result_number[0] = result_number[0][0], no_version[
|
||||
:no_version.find("b")]
|
||||
elif not no_version[no_version.rfind(".") + 1:].isnumeric():
|
||||
result_number[0] = result_number[0][0], no_version[
|
||||
:no_version.rfind(".")]
|
||||
result_number = iscompatible.string_to_tuple(result_number[0][1])
|
||||
result_number[0] = (
|
||||
result_number[0][0],
|
||||
no_version[: no_version.find("b")],
|
||||
)
|
||||
elif not no_version[no_version.rfind(".") + 1 :].isnumeric():
|
||||
result_number[0] = (
|
||||
result_number[0][0],
|
||||
no_version[: no_version.rfind(".")],
|
||||
)
|
||||
result_number = iscompatible.string_to_tuple(
|
||||
result_number[0][1]
|
||||
)
|
||||
lst_version_requirement.append((requirement, result_number))
|
||||
# Check compatibility with all possibility
|
||||
is_compatible = True
|
||||
if len(lst_version_requirement) > 1:
|
||||
highest_value = sorted(lst_version_requirement, key=lambda tup: tup[1])[-1]
|
||||
highest_value = sorted(
|
||||
lst_version_requirement, key=lambda tup: tup[1]
|
||||
)[-1]
|
||||
for version_requirement in lst_version_requirement:
|
||||
is_compatible &= iscompatible.iscompatible(version_requirement[0],
|
||||
highest_value[1])
|
||||
is_compatible &= iscompatible.iscompatible(
|
||||
version_requirement[0], highest_value[1]
|
||||
)
|
||||
if is_compatible:
|
||||
result = highest_value[0]
|
||||
else:
|
||||
# Find the requirements file and print the conflict
|
||||
# Take the version from Odoo by default, else take the more recent
|
||||
odoo_value = None
|
||||
erplibre_value = None
|
||||
for version_requirement in lst_version_requirement:
|
||||
filename_1 = dct_requirements_module_filename.get(
|
||||
version_requirement[0])
|
||||
version_requirement[0]
|
||||
)
|
||||
if priority_filename_requirement in filename_1:
|
||||
erplibre_value = version_requirement[0]
|
||||
elif (
|
||||
second_priority_filename_requirement in filename_1
|
||||
):
|
||||
odoo_value = version_requirement[0]
|
||||
break
|
||||
|
||||
if odoo_value:
|
||||
str_result_choose = f"Select {odoo_value} because from Odoo"
|
||||
if erplibre_value:
|
||||
str_result_choose = (
|
||||
f"Select {erplibre_value} because from ERPLibre"
|
||||
)
|
||||
result = erplibre_value
|
||||
elif odoo_value:
|
||||
str_result_choose = (
|
||||
f"Select {odoo_value} because from Odoo"
|
||||
)
|
||||
result = odoo_value
|
||||
else:
|
||||
result = highest_value[0]
|
||||
str_result_choose = f"Select highest value {result}"
|
||||
str_versions = " VS ".join(
|
||||
[f"{a[0]} from {dct_requirements_module_filename.get(a[0])}" for
|
||||
a in lst_version_requirement])
|
||||
print(f"WARNING - Not compatible {str_versions} - "
|
||||
f"{str_result_choose}.")
|
||||
[
|
||||
f"{a[0]} from"
|
||||
f" {dct_requirements_module_filename.get(a[0])}"
|
||||
for a in lst_version_requirement
|
||||
]
|
||||
)
|
||||
print(
|
||||
f"WARNING - Not compatible {str_versions} - "
|
||||
f"{str_result_choose}."
|
||||
)
|
||||
elif len(lst_version_requirement) == 1:
|
||||
result = lst_version_requirement[0][0]
|
||||
else:
|
||||
|
|
@ -196,13 +253,13 @@ def combine_requirements(config):
|
|||
for key in lst_ignored_key:
|
||||
del dct_requirements[key]
|
||||
|
||||
with open("./.venv/build_dependency.txt", 'w') as f:
|
||||
with open("./.venv/build_dependency.txt", "w") as f:
|
||||
f.writelines([f"{list(a)[0]}\n" for a in dct_requirements.values()])
|
||||
|
||||
|
||||
def sorted_dependency_poetry(pyproject_filename):
|
||||
# Open pyproject.toml
|
||||
with open(pyproject_filename, 'r') as f:
|
||||
with open(pyproject_filename, "r") as f:
|
||||
dct_pyproject = toml.load(f)
|
||||
|
||||
# Get dependencies and update list, sorted
|
||||
|
|
@ -212,19 +269,23 @@ def sorted_dependency_poetry(pyproject_filename):
|
|||
poetry = tool.get("poetry")
|
||||
if poetry:
|
||||
dependencies = poetry.get("dependencies")
|
||||
python_dependency = ("python", dependencies.get("python", ''))
|
||||
lst_dependency = [(k, v) for k, v in dependencies.items() if k != "python"]
|
||||
python_dependency = ("python", dependencies.get("python", ""))
|
||||
lst_dependency = [
|
||||
(k, v) for k, v in dependencies.items() if k != "python"
|
||||
]
|
||||
lst_dependency = sorted(lst_dependency, key=lambda tup: tup[0])
|
||||
poetry["dependencies"] = OrderedDict([python_dependency] + lst_dependency)
|
||||
poetry["dependencies"] = OrderedDict(
|
||||
[python_dependency] + lst_dependency
|
||||
)
|
||||
|
||||
# Rewrite pyproject.toml
|
||||
with open(pyproject_filename, 'w') as f:
|
||||
with open(pyproject_filename, "w") as f:
|
||||
toml.dump(dct_pyproject, f)
|
||||
|
||||
|
||||
def delete_dependency_poetry(pyproject_filename):
|
||||
# Open pyproject.toml
|
||||
with open(pyproject_filename, 'r') as f:
|
||||
with open(pyproject_filename, "r") as f:
|
||||
dct_pyproject = toml.load(f)
|
||||
|
||||
# Get dependencies and update list, sorted
|
||||
|
|
@ -234,11 +295,11 @@ def delete_dependency_poetry(pyproject_filename):
|
|||
poetry = tool.get("poetry")
|
||||
if poetry:
|
||||
dependencies = poetry.get("dependencies")
|
||||
python_dependency = ("python", dependencies.get("python", ''))
|
||||
python_dependency = ("python", dependencies.get("python", ""))
|
||||
poetry["dependencies"] = OrderedDict([python_dependency])
|
||||
|
||||
# Rewrite pyproject.toml
|
||||
with open(pyproject_filename, 'w') as f:
|
||||
with open(pyproject_filename, "w") as f:
|
||||
toml.dump(dct_pyproject, f)
|
||||
|
||||
|
||||
|
|
@ -246,7 +307,7 @@ def get_manifest_external_dependencies(dct_requirements):
|
|||
lst_manifest_file = get_lst_manifest_py()
|
||||
lst_dct_ext_depend = []
|
||||
for manifest_file in lst_manifest_file:
|
||||
with open(manifest_file, 'r') as f:
|
||||
with open(manifest_file, "r") as f:
|
||||
contents = f.read()
|
||||
try:
|
||||
dct = ast.literal_eval(contents)
|
||||
|
|
@ -270,11 +331,16 @@ def get_manifest_external_dependencies(dct_requirements):
|
|||
|
||||
|
||||
def call_poetry_add_build_dependency():
|
||||
os.system("./script/poetry_add_build_dependency.sh")
|
||||
"""
|
||||
|
||||
:return: True if success
|
||||
"""
|
||||
status = os.system("./script/poetry_add_build_dependency.sh")
|
||||
return status == 0
|
||||
|
||||
|
||||
def get_list_ignored():
|
||||
with open("./ignore_requirements.txt", 'r') as f:
|
||||
with open("./ignore_requirements.txt", "r") as f:
|
||||
lst_ignore_requirements = [a.strip() for a in f.readlines()]
|
||||
return lst_ignore_requirements
|
||||
|
||||
|
|
@ -283,15 +349,16 @@ def main():
|
|||
# repo = Repo(root_path)
|
||||
# lst_repo = get_all_repo()
|
||||
config = get_config()
|
||||
pyproject_toml_filename = f'{config.dir}pyproject.toml'
|
||||
pyproject_toml_filename = f"{config.dir}pyproject.toml"
|
||||
|
||||
delete_dependency_poetry(pyproject_toml_filename)
|
||||
combine_requirements(config)
|
||||
if config.force and os.path.isfile("./poetry.lock"):
|
||||
os.remove("./poetry.lock")
|
||||
call_poetry_add_build_dependency()
|
||||
sorted_dependency_poetry(pyproject_toml_filename)
|
||||
status = call_poetry_add_build_dependency()
|
||||
if status:
|
||||
sorted_dependency_poetry(pyproject_toml_filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import argparse
|
||||
import logging
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -24,18 +24,30 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--organization",
|
||||
dest="organization",
|
||||
default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github_token",
|
||||
dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
parser.add_argument('--organization', dest="organization", default="ERPLibre",
|
||||
help="Choose organization to fork and change all repo.")
|
||||
parser.add_argument('--github_token', dest="github_token",
|
||||
default=config.get(CST_EL_GITHUB_TOKEN),
|
||||
help="GitHub token generated by user")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -49,12 +61,21 @@ def main():
|
|||
raise ValueError("Missing github_token")
|
||||
|
||||
organization_name = config.organization
|
||||
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True)
|
||||
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"), repo_path=config.dir, organization_force=organization_name,
|
||||
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"), clone_depth=a.get("clone_depth"))
|
||||
for a in lst_repo]
|
||||
lst_repo = git_tool.get_source_repo_addons(
|
||||
repo_path=config.dir, add_repo_root=True
|
||||
)
|
||||
lst_repo_organization = [
|
||||
git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"),
|
||||
repo_path=config.dir,
|
||||
organization_force=organization_name,
|
||||
is_submodule=a.get("is_submodule"),
|
||||
sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"),
|
||||
clone_depth=a.get("clone_depth"),
|
||||
)
|
||||
for a in lst_repo
|
||||
]
|
||||
|
||||
url_not_found_count = 0
|
||||
url_found_count = 0
|
||||
|
|
@ -66,9 +87,11 @@ def main():
|
|||
print(f"Nb element {i}/{total} - {repo.project_name}")
|
||||
url = repo.url
|
||||
|
||||
status = git_tool.get_pull_request_repo(upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name=organization_name)
|
||||
status = git_tool.get_pull_request_repo(
|
||||
upstream_url=url,
|
||||
github_token=github_token,
|
||||
organization_name=organization_name,
|
||||
)
|
||||
if status is False:
|
||||
url_not_found_count += 1
|
||||
else:
|
||||
|
|
@ -78,5 +101,5 @@ def main():
|
|||
print(f"URL found: {url_found_count}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from pathlib import Path
|
|||
from git import Repo # pip install gitpython
|
||||
from git.exc import GitCommandError
|
||||
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
sys.path.append(new_path)
|
||||
|
||||
from script.git_tool import GitTool
|
||||
|
|
@ -24,13 +24,18 @@ def get_config():
|
|||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
''',
|
||||
epilog='''\
|
||||
'''
|
||||
description="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dir",
|
||||
dest="dir",
|
||||
default="./",
|
||||
help="Path of repo to change remote, including submodule.",
|
||||
)
|
||||
parser.add_argument('-d', '--dir', dest="dir", default="./",
|
||||
help="Path of repo to change remote, including submodule.")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
|
@ -39,13 +44,21 @@ def main():
|
|||
config = get_config()
|
||||
git_tool = GitTool()
|
||||
|
||||
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir,
|
||||
add_repo_root=False)
|
||||
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"), repo_path=config.dir, get_obj=True,
|
||||
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"), clone_depth=a.get("clone_depth"))
|
||||
for a in lst_repo]
|
||||
lst_repo = git_tool.get_source_repo_addons(
|
||||
repo_path=config.dir, add_repo_root=False
|
||||
)
|
||||
lst_repo_organization = [
|
||||
git_tool.get_transformed_repo_info_from_url(
|
||||
a.get("url"),
|
||||
repo_path=config.dir,
|
||||
get_obj=True,
|
||||
is_submodule=a.get("is_submodule"),
|
||||
sub_path=a.get("sub_path"),
|
||||
revision=a.get("revision"),
|
||||
clone_depth=a.get("clone_depth"),
|
||||
)
|
||||
for a in lst_repo
|
||||
]
|
||||
|
||||
lst_ignore_repo = ["odoo"]
|
||||
|
||||
|
|
@ -68,7 +81,9 @@ def main():
|
|||
is_checkout_branch = True
|
||||
except GitCommandError:
|
||||
try:
|
||||
git_repo.git.checkout("-t", f"{repo.organization}/{branch_name}")
|
||||
git_repo.git.checkout(
|
||||
"-t", f"{repo.organization}/{branch_name}"
|
||||
)
|
||||
is_checkout_branch = True
|
||||
except GitCommandError:
|
||||
pass
|
||||
|
|
@ -93,7 +108,7 @@ def get_manifest_external_dependencies(repo):
|
|||
lst_manifest_file = get_lst_manifest_py(repo.relative_path)
|
||||
for manifest_file in lst_manifest_file:
|
||||
has_change_manifest = False
|
||||
with open(manifest_file, 'r') as f:
|
||||
with open(manifest_file, "r") as f:
|
||||
lst_content = f.readlines()
|
||||
i = 0
|
||||
for content in lst_content:
|
||||
|
|
@ -102,16 +117,18 @@ def get_manifest_external_dependencies(repo):
|
|||
has_change = True
|
||||
first_char_index = content.find("auto_install")
|
||||
index = content.find("True", first_char_index)
|
||||
lst_content[i] = content[:index] + "False" + content[index + 4:]
|
||||
lst_content[i] = (
|
||||
content[:index] + "False" + content[index + 4 :]
|
||||
)
|
||||
i += 1
|
||||
|
||||
if has_change_manifest:
|
||||
print(f"Update file {manifest_file}")
|
||||
with open(manifest_file, 'w') as f:
|
||||
with open(manifest_file, "w") as f:
|
||||
f.writelines(lst_content)
|
||||
|
||||
return has_change
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
120
script/repo_revert_git_diff_date_from_code_generator.py
Executable file
120
script/repo_revert_git_diff_date_from_code_generator.py
Executable file
|
|
@ -0,0 +1,120 @@
|
|||
#!./.venv/bin/python
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
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)
|
||||
|
||||
_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="""\
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
# rex = r"\s+(?=\d{2}(?:\d{2})?-\d{1,2}-\d{1,2}\b)"
|
||||
rex = (
|
||||
r"[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])"
|
||||
r" (2[0-3]|[01][0-9]):[0-5][0-9]"
|
||||
)
|
||||
# TODO support argument instead of hardcoded values
|
||||
lst_path = [
|
||||
"./addons/TechnoLibre_odoo-code-generator-template",
|
||||
"./addons/OCA_server-tools",
|
||||
]
|
||||
for path in lst_path:
|
||||
repo = git.Repo(path)
|
||||
supported_ext = [".xml", ".pot", ".po"]
|
||||
translation_ext = [".pot", ".po"]
|
||||
for diff in repo.index.diff(None, create_patch=True):
|
||||
# if diff.change_type == "M":
|
||||
file_path = diff.a_path
|
||||
filename, file_extension = os.path.splitext(file_path)
|
||||
if file_extension in supported_ext:
|
||||
file_real_path = os.path.join(path, diff.a_path)
|
||||
if not os.path.isfile(file_real_path):
|
||||
continue
|
||||
if file_extension in translation_ext:
|
||||
is_modified = False
|
||||
lst_write_data = []
|
||||
# Delete code expression path caused by ERPLibre architecture
|
||||
with open(file_real_path, "r") as file:
|
||||
lst_data = file.readlines()
|
||||
for data in lst_data:
|
||||
if data.startswith("#: code:addons/addons/"):
|
||||
is_modified = True
|
||||
else:
|
||||
lst_write_data.append(data)
|
||||
if is_modified:
|
||||
with open(file_real_path, "w") as file:
|
||||
file.writelines(lst_write_data)
|
||||
|
||||
str_diff = repo.git.diff(diff.a_path)
|
||||
patch = PatchSet(str_diff)
|
||||
for modified_file in patch.modified_files:
|
||||
lst_to_write = []
|
||||
for hunk in modified_file:
|
||||
nb_line_source = len(hunk.source)
|
||||
nb_line_target = len(hunk.target)
|
||||
if nb_line_source != nb_line_target:
|
||||
# TODO support different line
|
||||
_logger.warning(
|
||||
"Source nb line different of target nb line"
|
||||
f" for file {path}/{file_path}."
|
||||
)
|
||||
continue
|
||||
# try:
|
||||
# assert nb_line_source == nb_line_target, f"Not the same line of diff:\n{str_diff}"
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
for i in range(nb_line_source):
|
||||
result_source = re.split(rex, hunk.source[i])
|
||||
if i > len(hunk.target):
|
||||
result_target = re.split(rex, hunk.target[i])
|
||||
else:
|
||||
result_target = ""
|
||||
if (
|
||||
len(result_source) > 1
|
||||
or len(result_target) > 1
|
||||
):
|
||||
line_to_change = hunk.target_start + i - 1
|
||||
lst_to_write.append(
|
||||
(line_to_change, hunk.source[i][1:])
|
||||
)
|
||||
# rewrite
|
||||
rewrite(file_real_path, lst_to_write)
|
||||
|
||||
|
||||
def rewrite(file_path, lst_to_write):
|
||||
# TODO not optimal for big file
|
||||
with open(file_path, "r") as file:
|
||||
data = file.readlines()
|
||||
for line in lst_to_write:
|
||||
data[line[0]] = line[1]
|
||||
with open(file_path, "w") as file:
|
||||
file.writelines(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
git daemon --base-path=. --export-all --reuseaddr --informative-errors --verbose &
|
||||
DAEMON_PID=$!
|
||||
|
||||
./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${EL_MANIFEST_DEV} -g code_generator
|
||||
./.venv/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${EL_MANIFEST_DEV} -g base,code_generator
|
||||
./.venv/repo sync -v --force-sync -m ${EL_MANIFEST_DEV}
|
||||
|
||||
kill ${DAEMON_PID}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ https://github.com/dhongu/deltatech.git,addons,,
|
|||
https://github.com/kinjal-sorathiya/Property-Management_odoo.git,addons,master,
|
||||
https://github.com/tegin/medical-fhir.git,addons,,
|
||||
https://github.com/odoomates/odooapps.git,addons,,
|
||||
https://github.com/it-projects-llc/odoo-saas-tools.git,addons,,
|
||||
https://github.com/it-projects-llc/saas-addons.git,addons,,
|
||||
https://github.com/itpp-labs/website-addons.git,addons,,
|
||||
https://github.com/itpp-labs/access-addons.git,addons,,
|
||||
https://github.com/itpp-labs/pos-addons.git,addons,,
|
||||
|
|
@ -125,4 +125,7 @@ https://github.com/itpp-labs/odoo-port-docs.git,doc,master,
|
|||
https://github.com/itpp-labs/odoo-test-docs.git,doc,master,
|
||||
https://github.com/odoo/documentation-user.git,doc,,
|
||||
https://github.com/OCA/odoo-module-migrator.git,script,master,
|
||||
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,,,
|
||||
|
|
|
|||
|
Loading…
Reference in a new issue