c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.8.1.180__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- c2cgeoportal_geoportal/__init__.py +245 -95
- c2cgeoportal_geoportal/lib/__init__.py +67 -43
- c2cgeoportal_geoportal/lib/authentication.py +50 -26
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
- c2cgeoportal_geoportal/lib/caching.py +65 -193
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +67 -65
- c2cgeoportal_geoportal/lib/common_headers.py +167 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +61 -46
- c2cgeoportal_geoportal/lib/filter_capabilities.py +126 -88
- c2cgeoportal_geoportal/lib/fulltextsearch.py +6 -5
- c2cgeoportal_geoportal/lib/functionality.py +20 -17
- c2cgeoportal_geoportal/lib/headers.py +14 -5
- c2cgeoportal_geoportal/lib/i18n.py +4 -4
- c2cgeoportal_geoportal/lib/layers.py +30 -11
- c2cgeoportal_geoportal/lib/lingua_extractor.py +363 -240
- c2cgeoportal_geoportal/lib/loader.py +11 -16
- c2cgeoportal_geoportal/lib/metrics.py +28 -17
- c2cgeoportal_geoportal/lib/oauth2.py +392 -206
- c2cgeoportal_geoportal/lib/wmstparsing.py +105 -84
- c2cgeoportal_geoportal/lib/xsd.py +26 -16
- c2cgeoportal_geoportal/resources.py +15 -9
- c2cgeoportal_geoportal/scaffolds/advance_create/ci/config.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.dockerignore +6 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.eslintrc.yaml +19 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +22 -15
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/alembic.yaml_tmpl → advance_create/{{cookiecutter.project}}/geoportal/alembic.yaml} +1 -1
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/development.ini_tmpl → advance_create/{{cookiecutter.project}}/geoportal/development.ini} +34 -15
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +100 -0
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-client.cfg +1 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/production.ini +38 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +77 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +29 -28
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +4 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +1 -1
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +42 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/resources.py +4 -3
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js} +1 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js} +4 -4
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +1 -3
- c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +3 -27
- c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
- c2cgeoportal_geoportal/scaffolds/create/{+dot+editorconfig → {{cookiecutter.project}}/.editorconfig} +2 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +57 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +76 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +70 -0
- c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +186 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +22 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +165 -22
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +23 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +20 -15
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +101 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +69 -0
- c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +126 -36
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +3 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +15 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +9 -18
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +11 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{project.yaml_tmpl → {{cookiecutter.project}}/project.yaml} +6 -6
- c2cgeoportal_geoportal/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +3 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +110 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +114 -0
- c2cgeoportal_geoportal/scaffolds/create/{setup.cfg_tmpl → {{cookiecutter.project}}/setup.cfg} +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +38 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
- c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +61 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +273 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +64 -17
- c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +396 -19
- c2cgeoportal_geoportal/scripts/__init__.py +16 -30
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +272 -234
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
- c2cgeoportal_geoportal/scripts/pcreate.py +310 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +128 -24
- c2cgeoportal_geoportal/scripts/urllogin.py +19 -11
- c2cgeoportal_geoportal/templates/login.html +88 -84
- c2cgeoportal_geoportal/templates/notlogin.html +59 -59
- c2cgeoportal_geoportal/templates/testi18n.html +6 -8
- c2cgeoportal_geoportal/views/__init__.py +23 -6
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +56 -19
- c2cgeoportal_geoportal/views/entry.py +85 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +29 -23
- c2cgeoportal_geoportal/views/geometry_processing.py +17 -9
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +166 -133
- c2cgeoportal_geoportal/views/login.py +161 -93
- c2cgeoportal_geoportal/views/mapserverproxy.py +47 -31
- c2cgeoportal_geoportal/views/memory.py +12 -12
- c2cgeoportal_geoportal/views/ogcproxy.py +52 -30
- c2cgeoportal_geoportal/views/pdfreport.py +30 -26
- c2cgeoportal_geoportal/views/printproxy.py +60 -52
- c2cgeoportal_geoportal/views/profile.py +24 -23
- c2cgeoportal_geoportal/views/proxy.py +88 -72
- c2cgeoportal_geoportal/views/raster.py +37 -26
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +27 -25
- c2cgeoportal_geoportal/views/theme.py +472 -332
- c2cgeoportal_geoportal/views/tinyowsproxy.py +42 -44
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/METADATA +19 -8
- c2cgeoportal_geoportal-2.8.1.180.dist-info/RECORD +191 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/entry_points.txt +3 -0
- tests/__init__.py +10 -5
- tests/test_cachebuster.py +3 -5
- tests/test_caching.py +18 -26
- tests/test_checker.py +1 -3
- tests/test_decimaljson.py +5 -5
- tests/test_headerstween.py +1 -3
- tests/test_i18n.py +2 -2
- tests/test_init.py +16 -20
- tests/test_locale_negociator.py +4 -6
- tests/test_mapserverproxy_route_predicate.py +1 -4
- tests/test_raster.py +15 -17
- tests/test_wmstparsing.py +10 -12
- tests/xmlstr.py +1 -3
- c2cgeoportal_geoportal/scaffolds/__init__.py +0 -227
- c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -12
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/main.yaml_tmpl +0 -89
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/rebuild.yaml_tmpl +0 -78
- c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/Dockerfile_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/Makefile +0 -3
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
- c2cgeoportal_geoportal/scaffolds/create/ci/config.yaml_tmpl +0 -23
- c2cgeoportal_geoportal/scaffolds/create/ci/requirements.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/ci/trigger +0 -68
- c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml +0 -54
- c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -48
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -6
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -58
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
- c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tools/extract-messages.js +0 -39
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
- c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -72
- c2cgeoportal_geoportal/scaffolds/create/mapserver/demo.map.tmpl_tmpl +0 -262
- c2cgeoportal_geoportal/scaffolds/create/mapserver/tinyows.xml +0 -36
- c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/config.yaml +0 -168
- c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -185
- c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
- c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -181
- c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -454
- c2cgeoportal_geoportal/templates/dynamic.js +0 -21
- c2cgeoportal_geoportal-2.6.0.dist-info/RECORD +0 -173
- /c2cgeoportal_geoportal/{scaffolds/create/geoportal/+package+_geoportal/static/css/desktop.css → py.typed} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/Makefile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Makefile} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/language_mapping +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/requirements.txt +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/views/__init__.py +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/locale/en/LC_MESSAGES/+package+_geoportal-client.po → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/locale/en/LC_MESSAGES/{{cookiecutter.package}}_geoportal-client.po} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/iframe_api.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/mobile.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_left.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_right.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/blank.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-blue.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-gold.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-green.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/robot.txt.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/TM_EUROPE_BORDERS-0.3.sql +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arial.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbd.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbi.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Ariali.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Bold.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-BoldItalic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Italic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Regular.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdana.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanab.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanai.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanaz.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts.conf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/tinyows.xml.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/legend.jrxml +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/logo.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/north.svg +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/results.jrxml +0 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2014-2021, Camptocamp SA
|
1
|
+
# Copyright (c) 2014-2023, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -36,15 +34,16 @@ import re
|
|
36
34
|
import shutil
|
37
35
|
import subprocess
|
38
36
|
import sys
|
39
|
-
from argparse import ArgumentParser
|
37
|
+
from argparse import ArgumentParser, Namespace
|
38
|
+
from json.decoder import JSONDecodeError
|
40
39
|
from subprocess import call, check_call, check_output
|
41
|
-
from typing import Any, Dict, cast
|
40
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, cast
|
42
41
|
|
43
42
|
import pkg_resources
|
44
43
|
import requests
|
45
44
|
import yaml
|
46
45
|
|
47
|
-
from c2cgeoportal_geoportal.lib.bashcolor import
|
46
|
+
from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize
|
48
47
|
|
49
48
|
REQUIRED_TEMPLATE_KEYS = ["package", "srid", "extent"]
|
50
49
|
TEMPLATE_EXAMPLE = {"package": "${package}", "srid": "${srid}", "extent": "489246, 78873, 837119, 296543"}
|
@@ -59,11 +58,44 @@ DIFF_NOTICE = (
|
|
59
58
|
)
|
60
59
|
|
61
60
|
|
62
|
-
def
|
63
|
-
"""
|
64
|
-
|
65
|
-
|
61
|
+
def fix_style() -> None:
|
62
|
+
"""Fix the style of all the project files using isort, Black and Prettier."""
|
63
|
+
|
64
|
+
file_to_clean = []
|
65
|
+
for filename, content in (
|
66
|
+
(".prettierignore", "*.min.js\n"),
|
67
|
+
("pyproject.toml", "[tool.black]\nline-length = 110\ntarget-version = ['py38']\n"),
|
68
|
+
(".prettierrc.yaml", "bracketSpacing: false\nquoteProps: preserve\n"),
|
69
|
+
(
|
70
|
+
".editorconfig",
|
71
|
+
"""root = true
|
72
|
+
[*]
|
73
|
+
max_line_length = 110
|
74
|
+
""",
|
75
|
+
),
|
76
|
+
):
|
77
|
+
if not os.path.exists(filename):
|
78
|
+
file_to_clean.append(filename)
|
79
|
+
if os.path.exists(os.path.join("CONST_create_template", filename)):
|
80
|
+
shutil.copyfile(os.path.join("CONST_create_template", filename), filename)
|
81
|
+
else:
|
82
|
+
with open(filename, "w", encoding="utf8") as file_:
|
83
|
+
file_.write(content)
|
84
|
+
|
85
|
+
if os.path.exists("ci/config.yaml"):
|
86
|
+
os.rename("ci/config.yaml", "ci/config.yaml_")
|
87
|
+
subprocess.run(["c2cciutils-checks", "--fix", "--check=isort"]) # pylint: disable=subprocess-run-check
|
88
|
+
subprocess.run(["c2cciutils-checks", "--fix", "--check=black"]) # pylint: disable=subprocess-run-check
|
89
|
+
subprocess.run(["c2cciutils-checks", "--fix", "--check=prettier"]) # pylint: disable=subprocess-run-check
|
90
|
+
if os.path.exists("ci/config.yaml_"):
|
91
|
+
os.rename("ci/config.yaml_", "ci/config.yaml")
|
92
|
+
|
93
|
+
for filename in file_to_clean:
|
94
|
+
os.remove(filename)
|
95
|
+
|
66
96
|
|
97
|
+
def main() -> None:
|
98
|
+
"""Tool used to do the application upgrade."""
|
67
99
|
parser = _fill_arguments()
|
68
100
|
options = parser.parse_args()
|
69
101
|
|
@@ -71,7 +103,7 @@ def main():
|
|
71
103
|
c2cupgradetool.upgrade()
|
72
104
|
|
73
105
|
|
74
|
-
def _fill_arguments():
|
106
|
+
def _fill_arguments() -> ArgumentParser:
|
75
107
|
parser = ArgumentParser()
|
76
108
|
parser.add_argument(
|
77
109
|
"--git-remote", metavar="GITREMOTE", help="Specify the remote branch", default="origin"
|
@@ -82,38 +114,40 @@ def _fill_arguments():
|
|
82
114
|
|
83
115
|
|
84
116
|
class InteruptedException(Exception):
|
85
|
-
|
117
|
+
"""The interrupted exception."""
|
86
118
|
|
87
119
|
|
88
120
|
current_step_number = 0
|
89
121
|
|
90
122
|
|
91
123
|
class Step:
|
92
|
-
|
124
|
+
"""Decorator used for en upgrade step."""
|
125
|
+
|
126
|
+
def __init__(self, step_number: int, file_marker: bool = True):
|
93
127
|
global current_step_number
|
94
128
|
current_step_number = step_number
|
95
129
|
self.step_number = step_number
|
96
130
|
self.file_marker = file_marker
|
97
131
|
|
98
|
-
def __call__(
|
99
|
-
|
132
|
+
def __call__(
|
133
|
+
self, current_step: Callable[["C2cUpgradeTool", int], None]
|
134
|
+
) -> Callable[["C2cUpgradeTool"], None]:
|
135
|
+
def decorate(c2cupgradetool: "C2cUpgradeTool") -> None:
|
100
136
|
try:
|
101
|
-
if os.path.isfile(".UPGRADE{
|
102
|
-
os.unlink(".UPGRADE{
|
137
|
+
if os.path.isfile(f".UPGRADE{self.step_number - 1}"):
|
138
|
+
os.unlink(f".UPGRADE{self.step_number - 1}")
|
103
139
|
if self.file_marker:
|
104
|
-
with open(".UPGRADE{
|
140
|
+
with open(f".UPGRADE{self.step_number}", "w", encoding="utf8"):
|
105
141
|
pass
|
106
|
-
print("Start step {}."
|
142
|
+
print(f"Start step {self.step_number}.")
|
107
143
|
sys.stdout.flush()
|
108
|
-
current_step(c2cupgradetool, self.step_number
|
144
|
+
current_step(c2cupgradetool, self.step_number)
|
109
145
|
except subprocess.CalledProcessError as exception:
|
146
|
+
command = " ".join([f"'{exception}'" for exception in exception.cmd])
|
110
147
|
c2cupgradetool.print_step(
|
111
148
|
self.step_number,
|
112
149
|
error=True,
|
113
|
-
message="The command `{}` returns the error code {}."
|
114
|
-
" ".join(["'{}'".format(exception) for exception in exception.cmd]),
|
115
|
-
exception.returncode,
|
116
|
-
),
|
150
|
+
message=f"The command `{command}` returns the error code {exception.returncode}.",
|
117
151
|
prompt="Fix the error and run the step again:",
|
118
152
|
)
|
119
153
|
sys.exit(1)
|
@@ -121,21 +155,20 @@ class Step:
|
|
121
155
|
c2cupgradetool.print_step(
|
122
156
|
self.step_number,
|
123
157
|
error=True,
|
124
|
-
message="There was an error: {}."
|
158
|
+
message=f"There was an error: {exception}.",
|
125
159
|
prompt="Fix the error and run the step again:",
|
126
160
|
)
|
127
161
|
sys.exit(1)
|
128
162
|
except Exception as exception:
|
129
|
-
|
163
|
+
catch_exception = exception
|
130
164
|
|
131
|
-
global current_step_number
|
132
165
|
if self.step_number == current_step_number:
|
133
166
|
|
134
|
-
def message():
|
167
|
+
def message() -> None:
|
135
168
|
c2cupgradetool.print_step(
|
136
169
|
self.step_number,
|
137
170
|
error=True,
|
138
|
-
message="The step had the error '{}'."
|
171
|
+
message=f"The step had the error '{catch_exception}'.",
|
139
172
|
prompt="Fix the error and run the step again:",
|
140
173
|
)
|
141
174
|
|
@@ -146,84 +179,100 @@ class Step:
|
|
146
179
|
|
147
180
|
|
148
181
|
class C2cUpgradeTool:
|
182
|
+
"""The tool used to upgrade the application."""
|
149
183
|
|
150
|
-
color_bar = colorize("================================================================", GREEN)
|
184
|
+
color_bar = colorize("================================================================", Color.GREEN)
|
151
185
|
|
152
|
-
def __init__(self, options):
|
186
|
+
def __init__(self, options: Namespace):
|
153
187
|
self.options = options
|
154
|
-
self.project
|
188
|
+
self.project = self.get_project()
|
155
189
|
|
156
190
|
@staticmethod
|
157
|
-
def get_project():
|
191
|
+
def get_project() -> Dict[str, Any]:
|
158
192
|
if not os.path.isfile("project.yaml"):
|
159
|
-
print(colorize("Unable to find the required 'project.yaml' file.", RED))
|
193
|
+
print(colorize("Unable to find the required 'project.yaml' file.", Color.RED))
|
160
194
|
sys.exit(1)
|
161
195
|
|
162
|
-
with open("project.yaml", "
|
163
|
-
return yaml.safe_load(project_file)
|
196
|
+
with open("project.yaml", encoding="utf8") as project_file:
|
197
|
+
return cast(Dict[str, Any], yaml.safe_load(project_file))
|
164
198
|
|
165
199
|
@staticmethod
|
166
|
-
def get_upgrade(section):
|
200
|
+
def get_upgrade(section: str) -> Union[List[Any], Dict[str, Any]]:
|
167
201
|
if not os.path.isfile(".upgrade.yaml"):
|
168
|
-
print(colorize("Unable to find the required '.upgrade.yaml' file.", RED))
|
202
|
+
print(colorize("Unable to find the required '.upgrade.yaml' file.", Color.RED))
|
169
203
|
sys.exit(1)
|
170
204
|
|
171
|
-
with open(".upgrade.yaml", "
|
172
|
-
return yaml.safe_load(project_file)[section]
|
173
|
-
|
174
|
-
def print_step(
|
175
|
-
|
205
|
+
with open(".upgrade.yaml", encoding="utf8") as project_file:
|
206
|
+
return cast(Union[List[Any], Dict[str, Any]], yaml.safe_load(project_file)[section])
|
207
|
+
|
208
|
+
def print_step(
|
209
|
+
self,
|
210
|
+
step: int,
|
211
|
+
error: bool = False,
|
212
|
+
message: Optional[str] = None,
|
213
|
+
prompt: str = "To continue, type:",
|
214
|
+
) -> None:
|
215
|
+
with open(".UPGRADE_INSTRUCTIONS", "w", encoding="utf8") as instructions:
|
176
216
|
print("")
|
177
217
|
print(self.color_bar)
|
178
218
|
if message is not None:
|
179
|
-
print(colorize(message, RED if error else YELLOW))
|
180
|
-
instructions.write("{}\n"
|
219
|
+
print(colorize(message, Color.RED if error else Color.YELLOW))
|
220
|
+
instructions.write(f"{message}\n")
|
181
221
|
if step >= 0:
|
182
|
-
print(colorize(prompt, GREEN))
|
183
|
-
instructions.write("{}\n"
|
222
|
+
print(colorize(prompt, Color.GREEN))
|
223
|
+
instructions.write(f"{prompt}\n")
|
184
224
|
cmd = ["./upgrade", os.environ["VERSION"]]
|
185
225
|
if step != 0:
|
186
|
-
cmd.append("{}"
|
187
|
-
print(colorize(" ".join(cmd), GREEN))
|
188
|
-
instructions.write("{
|
226
|
+
cmd.append(f"{step}")
|
227
|
+
print(colorize(" ".join(cmd), Color.GREEN))
|
228
|
+
instructions.write(f"{' '.join(cmd)}\n")
|
189
229
|
|
190
|
-
def run_step(self, step):
|
191
|
-
getattr(self, "step{}"
|
230
|
+
def run_step(self, step: int) -> None:
|
231
|
+
getattr(self, f"step{step}")()
|
192
232
|
|
193
|
-
def test_checkers(self):
|
194
|
-
|
195
|
-
|
196
|
-
self.project["checker_url"],
|
233
|
+
def test_checkers(self) -> Tuple[bool, Optional[str]]:
|
234
|
+
headers = " ".join(
|
235
|
+
[f"--header {i[0]}={i[1]}" for i in self.project.get("checker_headers", {}).items()]
|
197
236
|
)
|
237
|
+
run_curl = f"Run `curl --insecure {headers} '{self.project['checker_url']}'` for more information."
|
198
238
|
try:
|
199
|
-
requests.packages.urllib3.disable_warnings()
|
239
|
+
requests.packages.urllib3.disable_warnings() # type: ignore
|
200
240
|
resp = requests.get(
|
201
|
-
self.project["checker_url"],
|
241
|
+
self.project["checker_url"],
|
242
|
+
headers=self.project.get("checker_headers"),
|
243
|
+
verify=False, # nosec
|
202
244
|
)
|
203
245
|
except requests.exceptions.ConnectionError as exception:
|
204
|
-
return False, "\n".join(["Connection error: {}"
|
246
|
+
return False, "\n".join([f"Connection error: {exception}", run_curl])
|
205
247
|
except ConnectionRefusedError as exception:
|
206
|
-
return False, "\n".join(["Connection refused: {}"
|
248
|
+
return False, "\n".join([f"Connection refused: {exception}", run_curl])
|
207
249
|
if resp.status_code < 200 or resp.status_code >= 300:
|
208
|
-
|
209
|
-
print(colorize("
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
250
|
+
print(colorize("=============", Color.RED))
|
251
|
+
print(colorize("Checker error", Color.RED))
|
252
|
+
try:
|
253
|
+
for name, value in resp.json()["failures"].items():
|
254
|
+
print(colorize(f"Test '{name}' failed with result:", Color.YELLOW))
|
255
|
+
del value["level"]
|
256
|
+
del value["timing"]
|
257
|
+
|
258
|
+
print(yaml.dump(value) if value != {} else "No result")
|
259
|
+
except JSONDecodeError:
|
260
|
+
print(
|
261
|
+
colorize(
|
262
|
+
f"Response is not a JSON '{resp.text}', {resp.reason} {resp.status_code}",
|
263
|
+
Color.RED,
|
264
|
+
)
|
265
|
+
)
|
217
266
|
|
218
267
|
return False, "\n".join(["Checker error:", run_curl])
|
219
268
|
|
220
269
|
return True, None
|
221
270
|
|
222
|
-
def upgrade(self):
|
271
|
+
def upgrade(self) -> None:
|
223
272
|
self.run_step(self.options.step)
|
224
273
|
|
225
274
|
@Step(0, file_marker=False)
|
226
|
-
def step0(self, step):
|
275
|
+
def step0(self, step: int) -> None:
|
227
276
|
project_template_keys = list(cast(Dict[str, Any], self.project.get("template_vars")).keys())
|
228
277
|
messages = []
|
229
278
|
for required in REQUIRED_TEMPLATE_KEYS:
|
@@ -255,11 +304,11 @@ class C2cUpgradeTool:
|
|
255
304
|
message="Here is the output of 'git status'. Please make sure to commit all your "
|
256
305
|
"changes before going further. All uncommitted changes will be lost.\n"
|
257
306
|
"Note that for debugging purpose it is possible to pass directly to step 2 "
|
258
|
-
"e.-g.: ./upgrade --debug=../c2cgeoportal {
|
307
|
+
f"e.-g.: ./upgrade --debug=../c2cgeoportal {os.environ['VERSION']} 2",
|
259
308
|
)
|
260
309
|
|
261
310
|
@Step(1)
|
262
|
-
def step1(self, step):
|
311
|
+
def step1(self, step: int) -> None:
|
263
312
|
shutil.copyfile("project.yaml", "/tmp/project.yaml")
|
264
313
|
try:
|
265
314
|
check_call(["git", "reset", "--hard"])
|
@@ -270,75 +319,38 @@ class C2cUpgradeTool:
|
|
270
319
|
self.run_step(step + 1)
|
271
320
|
|
272
321
|
@Step(2)
|
273
|
-
def step2(self, step):
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
- openlayers
|
278
|
-
globals:
|
279
|
-
'{}': false
|
280
|
-
env:
|
281
|
-
jquery: true
|
282
|
-
parserOptions:
|
283
|
-
ecmaVersion: 2017
|
284
|
-
rules:
|
285
|
-
no-console: 0
|
286
|
-
comma-dangle: 0
|
287
|
-
import/no-unresolved: 0
|
288
|
-
valid-jsdoc: 0
|
289
|
-
sort-imports-es6-autofix/sort-imports-es6: 0
|
290
|
-
prettier/prettier: 1
|
291
|
-
""".format(
|
292
|
-
self.project["project_package"]
|
293
|
-
)
|
294
|
-
)
|
295
|
-
|
296
|
-
app_js_files = []
|
297
|
-
for base in ("CONST_create_template/", ""):
|
298
|
-
try:
|
299
|
-
app_js_files.extend(
|
300
|
-
check_output(
|
301
|
-
[
|
302
|
-
"find",
|
303
|
-
base + self.project["project_package"] + "_geoportal/static-ngeo/js",
|
304
|
-
"-type",
|
305
|
-
"f",
|
306
|
-
"-name",
|
307
|
-
"*.js",
|
308
|
-
]
|
309
|
-
)
|
310
|
-
.decode()
|
311
|
-
.split()
|
312
|
-
)
|
313
|
-
except Exception:
|
314
|
-
pass
|
315
|
-
|
316
|
-
if app_js_files:
|
317
|
-
call(["eslint", "--fix"] + app_js_files)
|
318
|
-
|
319
|
-
os.remove(".eslintrc")
|
320
|
-
check_call(["git", "add"] + app_js_files)
|
321
|
-
call(["git", "commit", "--message=Run code style"])
|
322
|
+
def step2(self, step: int) -> None:
|
323
|
+
fix_style()
|
324
|
+
subprocess.run(["git", "add", "-A"]) # pylint: disable=subprocess-run-check
|
325
|
+
subprocess.run(["git", "commit", "--message=Run code style"]) # pylint: disable=subprocess-run-check
|
322
326
|
|
323
327
|
self.run_step(step + 1)
|
324
328
|
|
325
329
|
@Step(3)
|
326
|
-
def step3(self, step):
|
330
|
+
def step3(self, step: int) -> None:
|
327
331
|
project_path = os.path.join("/tmp", self.project["project_folder"])
|
328
332
|
os.mkdir(project_path)
|
329
333
|
shutil.copyfile("/src/project.yaml", os.path.join(project_path, "project.yaml"))
|
330
334
|
check_call(
|
331
335
|
[
|
332
336
|
"pcreate",
|
333
|
-
"--ignore-conflicting-name",
|
334
337
|
"--overwrite",
|
335
|
-
"--scaffold=
|
338
|
+
"--scaffold=update",
|
336
339
|
project_path,
|
337
340
|
]
|
338
341
|
)
|
342
|
+
if self.get_project().get("advance", False):
|
343
|
+
check_call(
|
344
|
+
[
|
345
|
+
"pcreate",
|
346
|
+
"--overwrite",
|
347
|
+
"--scaffold=advance_update",
|
348
|
+
project_path,
|
349
|
+
]
|
350
|
+
)
|
339
351
|
|
340
352
|
shutil.copyfile(os.path.join(project_path, ".upgrade.yaml"), ".upgrade.yaml")
|
341
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
353
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
342
354
|
action = upgrade_file["action"]
|
343
355
|
if action == "remove":
|
344
356
|
self.files_to_remove(upgrade_file, prefix="CONST_create_template", force=True)
|
@@ -354,7 +366,7 @@ rules:
|
|
354
366
|
self.run_step(step + 1)
|
355
367
|
|
356
368
|
@Step(4)
|
357
|
-
def step4(self, step):
|
369
|
+
def step4(self, step: int) -> None:
|
358
370
|
if os.path.exists("CONST_create_template"):
|
359
371
|
check_call(["git", "rm", "-r", "--force", "CONST_create_template/"])
|
360
372
|
|
@@ -363,37 +375,79 @@ rules:
|
|
363
375
|
check_call(
|
364
376
|
[
|
365
377
|
"pcreate",
|
366
|
-
"--ignore-conflicting-name",
|
367
378
|
"--overwrite",
|
368
|
-
"--scaffold=
|
379
|
+
"--scaffold=update",
|
369
380
|
project_path,
|
370
381
|
]
|
371
382
|
)
|
383
|
+
if self.get_project().get("advance", False):
|
384
|
+
check_call(
|
385
|
+
[
|
386
|
+
"pcreate",
|
387
|
+
"--overwrite",
|
388
|
+
"--scaffold=advance_update",
|
389
|
+
project_path,
|
390
|
+
]
|
391
|
+
)
|
372
392
|
os.remove(project_path)
|
373
393
|
|
394
|
+
check_call(["git", "add", "--all", "CONST_create_template/"])
|
395
|
+
|
396
|
+
def changed_files() -> List[str]:
|
397
|
+
try:
|
398
|
+
status = [
|
399
|
+
[s for s in status.strip().split(" ", maxsplit=1) if s]
|
400
|
+
for status in check_git_status_output().strip().split("\n")
|
401
|
+
if status
|
402
|
+
]
|
403
|
+
return [
|
404
|
+
file.strip().split(" ")[-1]
|
405
|
+
for state, file in status
|
406
|
+
if state == "M" and not file.strip().startswith("CONST_")
|
407
|
+
]
|
408
|
+
except: # pylint: disable=bare-except
|
409
|
+
self.print_step(
|
410
|
+
step,
|
411
|
+
error=True,
|
412
|
+
message=f"Error while getting changed files:\n{check_git_status_output()}",
|
413
|
+
prompt="Fix the error and run the step again:",
|
414
|
+
)
|
415
|
+
sys.exit(1)
|
416
|
+
|
417
|
+
changed_before_style = changed_files()
|
418
|
+
|
419
|
+
fix_style()
|
420
|
+
|
421
|
+
# Revert code style changes in the project otherwise we get an error: does not match index
|
422
|
+
# on git apply.
|
423
|
+
changed_after_style = changed_files()
|
424
|
+
to_checkout = [file for file in changed_after_style if file not in changed_before_style]
|
425
|
+
if to_checkout:
|
426
|
+
subprocess.run(["git", "checkout"] + to_checkout, check=True)
|
427
|
+
|
374
428
|
check_call(["git", "add", "--all", "CONST_create_template/"])
|
375
429
|
check_call(["git", "clean", "-Xf", "CONST_create_template/"])
|
376
430
|
self.run_step(step + 1)
|
377
431
|
|
378
432
|
@Step(5)
|
379
|
-
def step5(self, step):
|
433
|
+
def step5(self, step: int) -> None:
|
380
434
|
if "managed_files" not in self.project:
|
435
|
+
unmanaged_files = "\n".join(["- " + e for e in self.project.get("unmanaged_files", [])])
|
381
436
|
self.print_step(
|
382
437
|
step,
|
383
|
-
message="In the new version, we will also manage almost all the create "
|
384
|
-
"
|
385
|
-
"
|
386
|
-
"
|
387
|
-
"`[]`.".format("\n".join(["- " + e for e in self.project.get("unmanaged_files", [])])),
|
438
|
+
message="In the new version, we will also manage almost all the create template files.\n"
|
439
|
+
"By default, files conforming to the following regex pattern will not be replaced:\n"
|
440
|
+
f"{unmanaged_files} Therefore, you should fill the 'managed_files' in you 'project.yaml' "
|
441
|
+
"file with at least `[]`.",
|
388
442
|
prompt="Fill it and run the step again:",
|
389
443
|
)
|
390
444
|
else:
|
391
445
|
self.run_step(step + 1)
|
392
446
|
|
393
447
|
@Step(6)
|
394
|
-
def step6(self, step):
|
448
|
+
def step6(self, step: int) -> None:
|
395
449
|
task_to_do = False
|
396
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
450
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
397
451
|
action = upgrade_file["action"]
|
398
452
|
if action == "remove":
|
399
453
|
task_to_do |= self.files_to_remove(upgrade_file)
|
@@ -415,7 +469,7 @@ rules:
|
|
415
469
|
else:
|
416
470
|
self.run_step(step + 1)
|
417
471
|
|
418
|
-
def files_to_remove(self, element, prefix="", force=False):
|
472
|
+
def files_to_remove(self, element: Dict[str, Any], prefix: str = "", force: bool = False) -> bool:
|
419
473
|
task_to_do = False
|
420
474
|
for path in element["paths"]:
|
421
475
|
file_ = os.path.join(prefix, path.format(package=self.project["project_package"]))
|
@@ -433,31 +487,30 @@ rules:
|
|
433
487
|
if no_touch:
|
434
488
|
managed = True
|
435
489
|
else:
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
490
|
+
print(
|
491
|
+
colorize(
|
492
|
+
f"The file '{file_}' has been removed but he is in the "
|
493
|
+
f"`managed_files` as '{pattern}'.",
|
494
|
+
Color.RED,
|
495
|
+
)
|
496
|
+
)
|
443
497
|
task_to_do = True
|
444
498
|
for pattern in self.project.get("unmanaged_files", []):
|
445
499
|
if re.match(pattern + "$", file_):
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
500
|
+
print(
|
501
|
+
colorize(
|
502
|
+
f"The file '{file_}' has been removed but he is in the "
|
503
|
+
f"`unmanaged_files` as '{pattern}'.",
|
504
|
+
Color.YELLOW,
|
505
|
+
)
|
506
|
+
)
|
453
507
|
task_to_do = True
|
454
508
|
if not managed:
|
455
|
-
print("The file '{}' is removed."
|
509
|
+
print(f"The file '{file_}' is removed.")
|
456
510
|
if "version" in element and "from" in element:
|
457
511
|
print(
|
458
|
-
"Was used in version {}, to be removed from version
|
459
|
-
|
460
|
-
)
|
512
|
+
f"Was used in version {element['from']}, to be removed from version "
|
513
|
+
f"{element['version']}."
|
461
514
|
)
|
462
515
|
if os.path.isdir(file_):
|
463
516
|
shutil.rmtree(file_)
|
@@ -465,7 +518,7 @@ rules:
|
|
465
518
|
os.remove(file_)
|
466
519
|
return task_to_do
|
467
520
|
|
468
|
-
def files_to_move(self, element, prefix="", force=False):
|
521
|
+
def files_to_move(self, element: Dict[str, Any], prefix: str = "", force: bool = False) -> bool:
|
469
522
|
task_to_do = False
|
470
523
|
src = os.path.join(prefix, element["from"].format(package=self.project["project_package"]))
|
471
524
|
dst = os.path.join(prefix, element["to"].format(package=self.project["project_package"]))
|
@@ -486,20 +539,18 @@ rules:
|
|
486
539
|
else:
|
487
540
|
print(
|
488
541
|
colorize(
|
489
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
490
|
-
"but it has been moved to '{}'."
|
491
|
-
RED,
|
542
|
+
f"The {type_} '{src}' is present in the `managed_files` as '{pattern}', "
|
543
|
+
f"but it has been moved to '{dst}'.",
|
544
|
+
Color.RED,
|
492
545
|
)
|
493
546
|
)
|
494
547
|
task_to_do = True
|
495
548
|
if re.match(pattern + "$", dst):
|
496
549
|
print(
|
497
550
|
colorize(
|
498
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
499
|
-
"but a file have been moved on it from '{}'."
|
500
|
-
|
501
|
-
),
|
502
|
-
RED,
|
551
|
+
f"The {type_} '{dst}' is present in the `managed_files` as '{pattern}', "
|
552
|
+
f"but a file have been moved on it from '{src}'.",
|
553
|
+
Color.RED,
|
503
554
|
)
|
504
555
|
)
|
505
556
|
task_to_do = True
|
@@ -507,45 +558,46 @@ rules:
|
|
507
558
|
if re.match(pattern + "$", src):
|
508
559
|
print(
|
509
560
|
colorize(
|
510
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
511
|
-
"but it has been moved to '{}'."
|
512
|
-
YELLOW,
|
561
|
+
f"The {type_} '{src}' is present in the `unmanaged_files` as '{pattern}', "
|
562
|
+
f"but it has been moved to '{dst}'.",
|
563
|
+
Color.YELLOW,
|
513
564
|
)
|
514
565
|
)
|
515
566
|
task_to_do = True
|
516
567
|
if re.match(pattern + "$", dst):
|
517
568
|
print(
|
518
569
|
colorize(
|
519
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
520
|
-
"but a file have been moved on it from '{}'."
|
521
|
-
|
522
|
-
),
|
523
|
-
YELLOW,
|
570
|
+
f"The {type_} '{dst}' is present in the `unmanaged_files` as '{pattern}', "
|
571
|
+
f"but a file have been moved on it from '{src}'.",
|
572
|
+
Color.YELLOW,
|
524
573
|
)
|
525
574
|
)
|
526
575
|
task_to_do = True
|
527
576
|
if not managed and os.path.exists(dst) and not element.get("override", False):
|
528
|
-
print(colorize("The destination '{}' already exists, ignoring."
|
577
|
+
print(colorize(f"The destination '{dst}' already exists, ignoring.", Color.YELLOW))
|
529
578
|
elif not managed:
|
530
|
-
print("Move the {} '{}' to '{}'."
|
579
|
+
print(f"Move the {type_} '{src}' to '{dst}'.")
|
531
580
|
if "version" in element:
|
532
|
-
print("Needed from version {
|
581
|
+
print(f"Needed from version {element['version']}.")
|
533
582
|
if os.path.dirname(dst) != "":
|
534
583
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
535
584
|
try:
|
536
585
|
check_call(["git", "mv", src, dst])
|
537
586
|
except Exception as exception:
|
538
|
-
print("[Warning] Git move error: {}."
|
587
|
+
print(f"[Warning] Git move error: {exception}.")
|
539
588
|
os.rename(src, dst)
|
540
589
|
return task_to_do
|
541
590
|
|
542
591
|
@Step(7)
|
543
|
-
def step7(self, step):
|
592
|
+
def step7(self, step: int) -> None:
|
544
593
|
self.files_to_get(step)
|
545
594
|
self.run_step(step + 1)
|
546
595
|
|
547
|
-
def is_managed(self, file_, files_to_get=False):
|
548
|
-
|
596
|
+
def is_managed(self, file_: str, files_to_get: bool = False) -> bool:
|
597
|
+
# Dictionary with:
|
598
|
+
# include: list of include regular expression
|
599
|
+
# exclude: list of exclude regular expression
|
600
|
+
default_project_file = cast(Dict[str, List[str]], self.get_upgrade("default_project_file"))
|
549
601
|
|
550
602
|
# Managed means managed by the application owner, not the c2cupgrade
|
551
603
|
managed = False
|
@@ -556,23 +608,23 @@ rules:
|
|
556
608
|
):
|
557
609
|
for pattern in default_project_file["include"]:
|
558
610
|
if re.match(pattern + "$", file_):
|
559
|
-
print("File '{}' included by migration config pattern '{}'."
|
611
|
+
print(f"File '{file_}' included by migration config pattern '{pattern}'.")
|
560
612
|
managed = True
|
561
613
|
break
|
562
614
|
if managed:
|
563
615
|
for pattern in default_project_file["exclude"]:
|
564
616
|
if re.match(pattern + "$", file_):
|
565
|
-
print("File '{}' excluded by migration config pattern '{}'."
|
617
|
+
print(f"File '{file_}' excluded by migration config pattern '{pattern}'.")
|
566
618
|
print("managed", file_, pattern)
|
567
619
|
managed = False
|
568
620
|
break
|
569
621
|
else:
|
570
|
-
print("New file '{}'."
|
622
|
+
print(f"New file '{file_}'.")
|
571
623
|
|
572
624
|
if not managed and not os.path.exists(file_):
|
573
625
|
for pattern in self.get_upgrade("extra"):
|
574
626
|
if re.match(pattern + "$", file_):
|
575
|
-
print("File '{}' is an extra by migration config pattern '{}'."
|
627
|
+
print(f"File '{file_}' is an extra by migration config pattern '{pattern}'.")
|
576
628
|
managed = True
|
577
629
|
|
578
630
|
if not managed:
|
@@ -582,39 +634,29 @@ rules:
|
|
582
634
|
else:
|
583
635
|
pattern = files["pattern"]
|
584
636
|
if re.match(pattern + "$", file_):
|
585
|
-
print(
|
586
|
-
"File '{}' included by project config pattern `managed_files` '{}'.".format(
|
587
|
-
file_, pattern
|
588
|
-
)
|
589
|
-
)
|
637
|
+
print(f"File '{file_}' included by project config pattern `managed_files` '{pattern}'.")
|
590
638
|
print("managed", file_, pattern)
|
591
639
|
managed = True
|
592
640
|
break
|
593
641
|
if managed:
|
594
642
|
for pattern in self.project.get("unmanaged_files", []):
|
595
643
|
if re.match(pattern + "$", file_):
|
596
|
-
print(
|
597
|
-
"File '{}' excluded by project config pattern `unmanaged_files` '{}'.".format(
|
598
|
-
file_, pattern
|
599
|
-
)
|
600
|
-
)
|
644
|
+
print(f"File '{file_}' excluded by project config pattern `unmanaged_files` '{pattern}'.")
|
601
645
|
managed = False
|
602
646
|
break
|
603
647
|
|
604
648
|
return managed
|
605
649
|
|
606
|
-
def files_to_get(self, step, pre=False):
|
650
|
+
def files_to_get(self, step: int, pre: bool = False) -> bool:
|
607
651
|
error = False
|
608
652
|
for root, _, files in os.walk("CONST_create_template"):
|
609
|
-
|
610
|
-
root = root[len("CONST_create_template/"):]
|
611
|
-
# fmt: on
|
653
|
+
root = root[len("CONST_create_template/") :]
|
612
654
|
for file_ in files:
|
613
655
|
destination = os.path.join(root, file_)
|
614
656
|
managed = self.is_managed(destination, True)
|
615
657
|
source = os.path.join("CONST_create_template", destination)
|
616
658
|
if not managed and (not os.path.exists(destination) or not filecmp.cmp(source, destination)):
|
617
|
-
print(colorize("Get the file '{}' from the create template."
|
659
|
+
print(colorize(f"Get the file '{destination}' from the create template.", Color.GREEN))
|
618
660
|
if not pre:
|
619
661
|
if os.path.dirname(destination) != "":
|
620
662
|
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
@@ -633,17 +675,17 @@ rules:
|
|
633
675
|
)
|
634
676
|
sys.exit(1)
|
635
677
|
elif managed:
|
636
|
-
print("The file '{}' is managed by the project."
|
678
|
+
print(f"The file '{destination}' is managed by the project.")
|
637
679
|
elif os.path.exists(destination) and filecmp.cmp(source, destination):
|
638
|
-
print("The file '{}' does not change."
|
680
|
+
print(f"The file '{destination}' does not change.")
|
639
681
|
else:
|
640
|
-
print("Unknown stat for the file '{}'."
|
682
|
+
print(f"Unknown stat for the file '{destination}'.")
|
641
683
|
sys.exit(2)
|
642
684
|
return error
|
643
685
|
|
644
686
|
@Step(8)
|
645
|
-
def step8(self, step):
|
646
|
-
with open("changelog.diff", "w") as diff_file:
|
687
|
+
def step8(self, step: int) -> None:
|
688
|
+
with open("changelog.diff", "w", encoding="utf8") as diff_file:
|
647
689
|
check_call(["git", "diff", "--", "CONST_CHANGELOG.txt"], stdout=diff_file)
|
648
690
|
|
649
691
|
from210 = False
|
@@ -664,30 +706,28 @@ rules:
|
|
664
706
|
"file (listed in the `changelog.diff` file).",
|
665
707
|
)
|
666
708
|
|
667
|
-
def get_modified(self, status_path):
|
668
|
-
status = check_git_status_output([status_path])
|
669
|
-
status = [s for s in status
|
709
|
+
def get_modified(self, status_path: str) -> List[str]:
|
710
|
+
status = check_git_status_output([status_path]).split("\n")
|
711
|
+
status = [s for s in status if len(s) > 3]
|
670
712
|
status = [s[3:] for s in status if s[:3].strip() == "M"]
|
671
713
|
for pattern in self.get_upgrade("no_diff"):
|
672
|
-
matcher = re.compile("CONST_create_template/{}$"
|
714
|
+
matcher = re.compile(f"CONST_create_template/{pattern}$")
|
673
715
|
status = [s for s in status if not matcher.match(s)]
|
674
|
-
|
675
|
-
status = [s for s in status if
|
676
|
-
status = [s for s in status if not filecmp.cmp(s, s[len("CONST_create_template/"):])]
|
677
|
-
# fmt: on
|
716
|
+
status = [s for s in status if os.path.exists(s[len("CONST_create_template/") :])]
|
717
|
+
status = [s for s in status if not filecmp.cmp(s, s[len("CONST_create_template/") :])]
|
678
718
|
return status
|
679
719
|
|
680
720
|
@Step(9)
|
681
|
-
def step9(self, step):
|
721
|
+
def step9(self, step: int) -> None:
|
682
722
|
if os.path.isfile("changelog.diff"):
|
683
723
|
os.unlink("changelog.diff")
|
684
724
|
|
685
725
|
status = self.get_modified(
|
686
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo"
|
726
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo"
|
687
727
|
)
|
688
728
|
status += ["CONST_create_template/geoportal/vars.yaml"]
|
689
729
|
|
690
|
-
with open("ngeo.diff", "w") as diff_file:
|
730
|
+
with open("ngeo.diff", "w", encoding="utf8") as diff_file:
|
691
731
|
if status:
|
692
732
|
check_call(
|
693
733
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -705,7 +745,7 @@ rules:
|
|
705
745
|
)
|
706
746
|
|
707
747
|
@Step(10)
|
708
|
-
def step10(self, step):
|
748
|
+
def step10(self, step: int) -> None:
|
709
749
|
if os.path.isfile("ngeo.diff"):
|
710
750
|
os.unlink("ngeo.diff")
|
711
751
|
|
@@ -714,15 +754,13 @@ rules:
|
|
714
754
|
s
|
715
755
|
for s in status
|
716
756
|
if not s.startswith(
|
717
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo/"
|
718
|
-
self.project["project_package"]
|
719
|
-
)
|
757
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo/"
|
720
758
|
)
|
721
759
|
]
|
722
760
|
status = [s for s in status if s != "CONST_create_template/geoportal/vars.yaml"]
|
723
761
|
|
724
762
|
if status:
|
725
|
-
with open("create.diff", "w") as diff_file:
|
763
|
+
with open("create.diff", "w", encoding="utf8") as diff_file:
|
726
764
|
if status:
|
727
765
|
check_call(
|
728
766
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -743,24 +781,24 @@ rules:
|
|
743
781
|
self.run_step(step + 1)
|
744
782
|
|
745
783
|
@Step(11)
|
746
|
-
def step11(self, step):
|
784
|
+
def step11(self, step: int) -> None:
|
747
785
|
if os.path.isfile("create.diff"):
|
748
786
|
os.unlink("create.diff")
|
749
787
|
|
750
788
|
message = [
|
751
789
|
"The upgrade is nearly done, now you should:",
|
752
790
|
"- Build your application with `./upgrade --finalize [build arguments]`",
|
753
|
-
"- Test your application on '{
|
791
|
+
f"- Test your application on '{self.project.get('application_url', '... missing ...')}'.",
|
754
792
|
]
|
755
793
|
|
756
794
|
if os.path.isfile(".upgrade.yaml"):
|
757
795
|
os.unlink(".upgrade.yaml")
|
758
|
-
with open(".UPGRADE_SUCCESS", "w"):
|
796
|
+
with open(".UPGRADE_SUCCESS", "w", encoding="utf8"):
|
759
797
|
pass
|
760
798
|
self.print_step(step + 1, message="\n".join(message))
|
761
799
|
|
762
800
|
@Step(12, file_marker=False)
|
763
|
-
def step12(self, step):
|
801
|
+
def step12(self, step: int) -> None:
|
764
802
|
if os.path.isfile(".UPGRADE_SUCCESS"):
|
765
803
|
os.unlink(".UPGRADE_SUCCESS")
|
766
804
|
good, message = self.test_checkers()
|
@@ -772,12 +810,12 @@ rules:
|
|
772
810
|
error=True,
|
773
811
|
message=message,
|
774
812
|
prompt="Correct the checker, then run the step again "
|
775
|
-
"(If you want to fix it later you can pass to the next step):",
|
813
|
+
"(If you want to fix it later you can pass to the next step:int):",
|
776
814
|
)
|
777
815
|
sys.exit(1)
|
778
816
|
|
779
817
|
@Step(13, file_marker=False)
|
780
|
-
def step13(self, step):
|
818
|
+
def step13(self, step: int) -> None:
|
781
819
|
# Required to remove from the Git stage the ignored file when we lunch the step again
|
782
820
|
check_call(["git", "reset", "--mixed"])
|
783
821
|
|
@@ -788,35 +826,35 @@ rules:
|
|
788
826
|
step + 1,
|
789
827
|
message="We will commit all the above files!\n"
|
790
828
|
"If there are some files which should not be committed, then you should "
|
791
|
-
"add them into the `.gitignore` file and launch upgrade {} again."
|
829
|
+
f"add them into the `.gitignore` file and launch upgrade {step} again.",
|
792
830
|
prompt="Then to commit your changes type:",
|
793
831
|
)
|
794
832
|
|
795
833
|
@Step(14, file_marker=False)
|
796
|
-
def step14(self, _):
|
834
|
+
def step14(self, _: int) -> None:
|
797
835
|
if os.path.isfile(".UPGRADE_INSTRUCTIONS"):
|
798
836
|
os.unlink(".UPGRADE_INSTRUCTIONS")
|
799
837
|
check_call(
|
800
838
|
[
|
801
839
|
"git",
|
802
840
|
"commit",
|
803
|
-
"--message=Upgrade to GeoMapFish
|
804
|
-
|
805
|
-
),
|
841
|
+
"--message=Upgrade to GeoMapFish "
|
842
|
+
f"{pkg_resources.get_distribution('c2cgeoportal_commons').version}",
|
806
843
|
]
|
807
844
|
)
|
808
845
|
|
809
846
|
print("")
|
810
847
|
print(self.color_bar)
|
811
848
|
print("")
|
812
|
-
print(colorize("Congratulations, your upgrade was successful.", GREEN))
|
849
|
+
print(colorize("Congratulations, your upgrade was successful.", Color.GREEN))
|
813
850
|
print("")
|
814
851
|
branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
|
815
852
|
print("Now all your files are committed; you should do a git push:")
|
816
|
-
print("git push {
|
853
|
+
print(f"git push {self.options.git_remote} {branch}.")
|
817
854
|
|
818
855
|
|
819
|
-
def check_git_status_output(args=None):
|
856
|
+
def check_git_status_output(args: Optional[List[str]] = None) -> str:
|
857
|
+
"""Check if there is something that's not committed."""
|
820
858
|
return check_output(["git", "status", "--short"] + (args if args is not None else [])).decode("utf-8")
|
821
859
|
|
822
860
|
|