c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.7.1.157__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 +224 -84
- c2cgeoportal_geoportal/lib/__init__.py +67 -43
- c2cgeoportal_geoportal/lib/authentication.py +50 -22
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
- c2cgeoportal_geoportal/lib/caching.py +61 -191
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +61 -63
- c2cgeoportal_geoportal/lib/common_headers.py +170 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +54 -39
- c2cgeoportal_geoportal/lib/filter_capabilities.py +122 -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 +361 -237
- c2cgeoportal_geoportal/lib/loader.py +10 -15
- c2cgeoportal_geoportal/lib/metrics.py +28 -17
- c2cgeoportal_geoportal/lib/oauth2.py +214 -145
- c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
- 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} +18 -9
- 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 +102 -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/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +2 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/tools/extract-messages.js +8 -6
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +75 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +31 -28
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +3 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +1 -1
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/__init__.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py} +11 -22
- 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 -7
- 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 +43 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +65 -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/{Dockerfile_tmpl → {{cookiecutter.project}}/Dockerfile} +20 -11
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +14 -0
- c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +162 -0
- c2cgeoportal_geoportal/scaffolds/create/{ci/config.yaml_tmpl → {{cookiecutter.project}}/ci/config.yaml} +7 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +133 -17
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +67 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +17 -12
- c2cgeoportal_geoportal/scaffolds/create/{env.default_tmpl → {{cookiecutter.project}}/env.default} +29 -14
- c2cgeoportal_geoportal/scaffolds/create/{env.project_tmpl → {{cookiecutter.project}}/env.project} +16 -4
- c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +93 -27
- 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 +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +7 -15
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +5 -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/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- 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 +3 -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/{+dot+upgrade.yaml_tmpl → {{cookiecutter.project}}/.upgrade.yaml} +49 -39
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1160 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +47 -2
- c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +350 -17
- c2cgeoportal_geoportal/scripts/__init__.py +16 -30
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +271 -232
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
- c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +72 -23
- 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 -4
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +56 -19
- c2cgeoportal_geoportal/views/entry.py +93 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +28 -22
- c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +160 -126
- c2cgeoportal_geoportal/views/login.py +106 -93
- c2cgeoportal_geoportal/views/mapserverproxy.py +46 -29
- c2cgeoportal_geoportal/views/memory.py +12 -12
- c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
- c2cgeoportal_geoportal/views/pdfreport.py +26 -22
- c2cgeoportal_geoportal/views/printproxy.py +60 -52
- c2cgeoportal_geoportal/views/profile.py +24 -23
- c2cgeoportal_geoportal/views/proxy.py +87 -69
- c2cgeoportal_geoportal/views/raster.py +35 -24
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +27 -24
- c2cgeoportal_geoportal/views/theme.py +427 -321
- c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.157.dist-info}/METADATA +25 -20
- c2cgeoportal_geoportal-2.7.1.157.dist-info/RECORD +185 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.157.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.157.dist-info}/entry_points.txt +3 -1
- tests/__init__.py +7 -3
- tests/test_cachebuster.py +0 -2
- tests/test_caching.py +17 -25
- tests/test_checker.py +0 -2
- tests/test_decimaljson.py +4 -4
- tests/test_headerstween.py +0 -2
- tests/test_i18n.py +1 -1
- tests/test_init.py +4 -7
- tests/test_locale_negociator.py +0 -2
- tests/test_mapserverproxy_route_predicate.py +0 -2
- tests/test_raster.py +0 -2
- tests/test_wmstparsing.py +0 -2
- 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/Makefile +0 -3
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
- 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/geoportal/+dot+dockerignore_tmpl +0 -6
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
- 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/requirements.txt +0 -2
- 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/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/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/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.157.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
1
|
# Copyright (c) 2014-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
@@ -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,101 @@ 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
250
|
|
209
|
-
print(colorize("=============", RED))
|
210
|
-
print(colorize("Checker error", RED))
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
251
|
+
print(colorize("=============", Color.RED))
|
252
|
+
print(colorize("Checker error", Color.RED))
|
253
|
+
try:
|
254
|
+
for name, value in resp.json()["failures"].items():
|
255
|
+
print(colorize(f"Test '{name}' failed with result:", Color.YELLOW))
|
256
|
+
del value["level"]
|
257
|
+
del value["timing"]
|
258
|
+
|
259
|
+
print(yaml.dump(value) if value != {} else "No result")
|
260
|
+
except JSONDecodeError:
|
261
|
+
print(
|
262
|
+
colorize(
|
263
|
+
f"Response is not a JSON '{resp.text}', {resp.reason} {resp.status_code}",
|
264
|
+
Color.RED,
|
265
|
+
)
|
266
|
+
)
|
217
267
|
|
218
268
|
return False, "\n".join(["Checker error:", run_curl])
|
219
269
|
|
220
270
|
return True, None
|
221
271
|
|
222
|
-
def upgrade(self):
|
272
|
+
def upgrade(self) -> None:
|
223
273
|
self.run_step(self.options.step)
|
224
274
|
|
225
275
|
@Step(0, file_marker=False)
|
226
|
-
def step0(self, step):
|
276
|
+
def step0(self, step: int) -> None:
|
227
277
|
project_template_keys = list(cast(Dict[str, Any], self.project.get("template_vars")).keys())
|
228
278
|
messages = []
|
229
279
|
for required in REQUIRED_TEMPLATE_KEYS:
|
@@ -255,11 +305,11 @@ class C2cUpgradeTool:
|
|
255
305
|
message="Here is the output of 'git status'. Please make sure to commit all your "
|
256
306
|
"changes before going further. All uncommitted changes will be lost.\n"
|
257
307
|
"Note that for debugging purpose it is possible to pass directly to step 2 "
|
258
|
-
"e.-g.: ./upgrade --debug=../c2cgeoportal {
|
308
|
+
f"e.-g.: ./upgrade --debug=../c2cgeoportal {os.environ['VERSION']} 2",
|
259
309
|
)
|
260
310
|
|
261
311
|
@Step(1)
|
262
|
-
def step1(self, step):
|
312
|
+
def step1(self, step: int) -> None:
|
263
313
|
shutil.copyfile("project.yaml", "/tmp/project.yaml")
|
264
314
|
try:
|
265
315
|
check_call(["git", "reset", "--hard"])
|
@@ -270,75 +320,38 @@ class C2cUpgradeTool:
|
|
270
320
|
self.run_step(step + 1)
|
271
321
|
|
272
322
|
@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"])
|
323
|
+
def step2(self, step: int) -> None:
|
324
|
+
fix_style()
|
325
|
+
subprocess.run(["git", "add", "-A"]) # pylint: disable=subprocess-run-check
|
326
|
+
subprocess.run(["git", "commit", "--message=Run code style"]) # pylint: disable=subprocess-run-check
|
322
327
|
|
323
328
|
self.run_step(step + 1)
|
324
329
|
|
325
330
|
@Step(3)
|
326
|
-
def step3(self, step):
|
331
|
+
def step3(self, step: int) -> None:
|
327
332
|
project_path = os.path.join("/tmp", self.project["project_folder"])
|
328
333
|
os.mkdir(project_path)
|
329
334
|
shutil.copyfile("/src/project.yaml", os.path.join(project_path, "project.yaml"))
|
330
335
|
check_call(
|
331
336
|
[
|
332
337
|
"pcreate",
|
333
|
-
"--ignore-conflicting-name",
|
334
338
|
"--overwrite",
|
335
|
-
"--scaffold=
|
339
|
+
"--scaffold=update",
|
336
340
|
project_path,
|
337
341
|
]
|
338
342
|
)
|
343
|
+
if self.get_project().get("advance", False):
|
344
|
+
check_call(
|
345
|
+
[
|
346
|
+
"pcreate",
|
347
|
+
"--overwrite",
|
348
|
+
"--scaffold=advance_update",
|
349
|
+
project_path,
|
350
|
+
]
|
351
|
+
)
|
339
352
|
|
340
353
|
shutil.copyfile(os.path.join(project_path, ".upgrade.yaml"), ".upgrade.yaml")
|
341
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
354
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
342
355
|
action = upgrade_file["action"]
|
343
356
|
if action == "remove":
|
344
357
|
self.files_to_remove(upgrade_file, prefix="CONST_create_template", force=True)
|
@@ -354,7 +367,7 @@ rules:
|
|
354
367
|
self.run_step(step + 1)
|
355
368
|
|
356
369
|
@Step(4)
|
357
|
-
def step4(self, step):
|
370
|
+
def step4(self, step: int) -> None:
|
358
371
|
if os.path.exists("CONST_create_template"):
|
359
372
|
check_call(["git", "rm", "-r", "--force", "CONST_create_template/"])
|
360
373
|
|
@@ -363,37 +376,79 @@ rules:
|
|
363
376
|
check_call(
|
364
377
|
[
|
365
378
|
"pcreate",
|
366
|
-
"--ignore-conflicting-name",
|
367
379
|
"--overwrite",
|
368
|
-
"--scaffold=
|
380
|
+
"--scaffold=update",
|
369
381
|
project_path,
|
370
382
|
]
|
371
383
|
)
|
384
|
+
if self.get_project().get("advance", False):
|
385
|
+
check_call(
|
386
|
+
[
|
387
|
+
"pcreate",
|
388
|
+
"--overwrite",
|
389
|
+
"--scaffold=advance_update",
|
390
|
+
project_path,
|
391
|
+
]
|
392
|
+
)
|
372
393
|
os.remove(project_path)
|
373
394
|
|
395
|
+
check_call(["git", "add", "--all", "CONST_create_template/"])
|
396
|
+
|
397
|
+
def changed_files() -> List[str]:
|
398
|
+
try:
|
399
|
+
status = [
|
400
|
+
[s for s in status.strip().split(" ", maxsplit=1) if s]
|
401
|
+
for status in check_git_status_output().strip().split("\n")
|
402
|
+
if status
|
403
|
+
]
|
404
|
+
return [
|
405
|
+
file.strip().split(" ")[-1]
|
406
|
+
for state, file in status
|
407
|
+
if state == "M" and not file.strip().startswith("CONST_")
|
408
|
+
]
|
409
|
+
except: # pylint: disable=bare-except
|
410
|
+
self.print_step(
|
411
|
+
step,
|
412
|
+
error=True,
|
413
|
+
message=f"Error while getting changed files:\n{check_git_status_output()}",
|
414
|
+
prompt="Fix the error and run the step again:",
|
415
|
+
)
|
416
|
+
sys.exit(1)
|
417
|
+
|
418
|
+
changed_before_style = changed_files()
|
419
|
+
|
420
|
+
fix_style()
|
421
|
+
|
422
|
+
# Revert code style changes in the project otherwise we get an error: does not match index
|
423
|
+
# on git apply.
|
424
|
+
changed_after_style = changed_files()
|
425
|
+
to_checkout = [file for file in changed_after_style if file not in changed_before_style]
|
426
|
+
if to_checkout:
|
427
|
+
subprocess.run(["git", "checkout"] + to_checkout, check=True)
|
428
|
+
|
374
429
|
check_call(["git", "add", "--all", "CONST_create_template/"])
|
375
430
|
check_call(["git", "clean", "-Xf", "CONST_create_template/"])
|
376
431
|
self.run_step(step + 1)
|
377
432
|
|
378
433
|
@Step(5)
|
379
|
-
def step5(self, step):
|
434
|
+
def step5(self, step: int) -> None:
|
380
435
|
if "managed_files" not in self.project:
|
436
|
+
unmanaged_files = "\n".join(["- " + e for e in self.project.get("unmanaged_files", [])])
|
381
437
|
self.print_step(
|
382
438
|
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", [])])),
|
439
|
+
message="In the new version, we will also manage almost all the create template files.\n"
|
440
|
+
"By default, files conforming to the following regex pattern will not be replaced:\n"
|
441
|
+
f"{unmanaged_files} Therefore, you should fill the 'managed_files' in you 'project.yaml' "
|
442
|
+
"file with at least `[]`.",
|
388
443
|
prompt="Fill it and run the step again:",
|
389
444
|
)
|
390
445
|
else:
|
391
446
|
self.run_step(step + 1)
|
392
447
|
|
393
448
|
@Step(6)
|
394
|
-
def step6(self, step):
|
449
|
+
def step6(self, step: int) -> None:
|
395
450
|
task_to_do = False
|
396
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
451
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
397
452
|
action = upgrade_file["action"]
|
398
453
|
if action == "remove":
|
399
454
|
task_to_do |= self.files_to_remove(upgrade_file)
|
@@ -415,7 +470,7 @@ rules:
|
|
415
470
|
else:
|
416
471
|
self.run_step(step + 1)
|
417
472
|
|
418
|
-
def files_to_remove(self, element, prefix="", force=False):
|
473
|
+
def files_to_remove(self, element: Dict[str, Any], prefix: str = "", force: bool = False) -> bool:
|
419
474
|
task_to_do = False
|
420
475
|
for path in element["paths"]:
|
421
476
|
file_ = os.path.join(prefix, path.format(package=self.project["project_package"]))
|
@@ -433,31 +488,30 @@ rules:
|
|
433
488
|
if no_touch:
|
434
489
|
managed = True
|
435
490
|
else:
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
491
|
+
print(
|
492
|
+
colorize(
|
493
|
+
f"The file '{file_}' has been removed but he is in the "
|
494
|
+
f"`managed_files` as '{pattern}'.",
|
495
|
+
Color.RED,
|
496
|
+
)
|
497
|
+
)
|
443
498
|
task_to_do = True
|
444
499
|
for pattern in self.project.get("unmanaged_files", []):
|
445
500
|
if re.match(pattern + "$", file_):
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
501
|
+
print(
|
502
|
+
colorize(
|
503
|
+
f"The file '{file_}' has been removed but he is in the "
|
504
|
+
f"`unmanaged_files` as '{pattern}'.",
|
505
|
+
Color.YELLOW,
|
506
|
+
)
|
507
|
+
)
|
453
508
|
task_to_do = True
|
454
509
|
if not managed:
|
455
|
-
print("The file '{}' is removed."
|
510
|
+
print(f"The file '{file_}' is removed.")
|
456
511
|
if "version" in element and "from" in element:
|
457
512
|
print(
|
458
|
-
"Was used in version {}, to be removed from version
|
459
|
-
|
460
|
-
)
|
513
|
+
f"Was used in version {element['from']}, to be removed from version "
|
514
|
+
f"{element['version']}."
|
461
515
|
)
|
462
516
|
if os.path.isdir(file_):
|
463
517
|
shutil.rmtree(file_)
|
@@ -465,7 +519,7 @@ rules:
|
|
465
519
|
os.remove(file_)
|
466
520
|
return task_to_do
|
467
521
|
|
468
|
-
def files_to_move(self, element, prefix="", force=False):
|
522
|
+
def files_to_move(self, element: Dict[str, Any], prefix: str = "", force: bool = False) -> bool:
|
469
523
|
task_to_do = False
|
470
524
|
src = os.path.join(prefix, element["from"].format(package=self.project["project_package"]))
|
471
525
|
dst = os.path.join(prefix, element["to"].format(package=self.project["project_package"]))
|
@@ -486,20 +540,18 @@ rules:
|
|
486
540
|
else:
|
487
541
|
print(
|
488
542
|
colorize(
|
489
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
490
|
-
"but it has been moved to '{}'."
|
491
|
-
RED,
|
543
|
+
f"The {type_} '{src}' is present in the `managed_files` as '{pattern}', "
|
544
|
+
f"but it has been moved to '{dst}'.",
|
545
|
+
Color.RED,
|
492
546
|
)
|
493
547
|
)
|
494
548
|
task_to_do = True
|
495
549
|
if re.match(pattern + "$", dst):
|
496
550
|
print(
|
497
551
|
colorize(
|
498
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
499
|
-
"but a file have been moved on it from '{}'."
|
500
|
-
|
501
|
-
),
|
502
|
-
RED,
|
552
|
+
f"The {type_} '{dst}' is present in the `managed_files` as '{pattern}', "
|
553
|
+
f"but a file have been moved on it from '{src}'.",
|
554
|
+
Color.RED,
|
503
555
|
)
|
504
556
|
)
|
505
557
|
task_to_do = True
|
@@ -507,45 +559,46 @@ rules:
|
|
507
559
|
if re.match(pattern + "$", src):
|
508
560
|
print(
|
509
561
|
colorize(
|
510
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
511
|
-
"but it has been moved to '{}'."
|
512
|
-
YELLOW,
|
562
|
+
f"The {type_} '{src}' is present in the `unmanaged_files` as '{pattern}', "
|
563
|
+
f"but it has been moved to '{dst}'.",
|
564
|
+
Color.YELLOW,
|
513
565
|
)
|
514
566
|
)
|
515
567
|
task_to_do = True
|
516
568
|
if re.match(pattern + "$", dst):
|
517
569
|
print(
|
518
570
|
colorize(
|
519
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
520
|
-
"but a file have been moved on it from '{}'."
|
521
|
-
|
522
|
-
),
|
523
|
-
YELLOW,
|
571
|
+
f"The {type_} '{dst}' is present in the `unmanaged_files` as '{pattern}', "
|
572
|
+
f"but a file have been moved on it from '{src}'.",
|
573
|
+
Color.YELLOW,
|
524
574
|
)
|
525
575
|
)
|
526
576
|
task_to_do = True
|
527
577
|
if not managed and os.path.exists(dst) and not element.get("override", False):
|
528
|
-
print(colorize("The destination '{}' already exists, ignoring."
|
578
|
+
print(colorize(f"The destination '{dst}' already exists, ignoring.", Color.YELLOW))
|
529
579
|
elif not managed:
|
530
|
-
print("Move the {} '{}' to '{}'."
|
580
|
+
print(f"Move the {type_} '{src}' to '{dst}'.")
|
531
581
|
if "version" in element:
|
532
|
-
print("Needed from version {
|
582
|
+
print(f"Needed from version {element['version']}.")
|
533
583
|
if os.path.dirname(dst) != "":
|
534
584
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
535
585
|
try:
|
536
586
|
check_call(["git", "mv", src, dst])
|
537
587
|
except Exception as exception:
|
538
|
-
print("[Warning] Git move error: {}."
|
588
|
+
print(f"[Warning] Git move error: {exception}.")
|
539
589
|
os.rename(src, dst)
|
540
590
|
return task_to_do
|
541
591
|
|
542
592
|
@Step(7)
|
543
|
-
def step7(self, step):
|
593
|
+
def step7(self, step: int) -> None:
|
544
594
|
self.files_to_get(step)
|
545
595
|
self.run_step(step + 1)
|
546
596
|
|
547
|
-
def is_managed(self, file_, files_to_get=False):
|
548
|
-
|
597
|
+
def is_managed(self, file_: str, files_to_get: bool = False) -> bool:
|
598
|
+
# Dictionary with:
|
599
|
+
# include: list of include regular expression
|
600
|
+
# exclude: list of exclude regular expression
|
601
|
+
default_project_file = cast(Dict[str, List[str]], self.get_upgrade("default_project_file"))
|
549
602
|
|
550
603
|
# Managed means managed by the application owner, not the c2cupgrade
|
551
604
|
managed = False
|
@@ -556,23 +609,23 @@ rules:
|
|
556
609
|
):
|
557
610
|
for pattern in default_project_file["include"]:
|
558
611
|
if re.match(pattern + "$", file_):
|
559
|
-
print("File '{}' included by migration config pattern '{}'."
|
612
|
+
print(f"File '{file_}' included by migration config pattern '{pattern}'.")
|
560
613
|
managed = True
|
561
614
|
break
|
562
615
|
if managed:
|
563
616
|
for pattern in default_project_file["exclude"]:
|
564
617
|
if re.match(pattern + "$", file_):
|
565
|
-
print("File '{}' excluded by migration config pattern '{}'."
|
618
|
+
print(f"File '{file_}' excluded by migration config pattern '{pattern}'.")
|
566
619
|
print("managed", file_, pattern)
|
567
620
|
managed = False
|
568
621
|
break
|
569
622
|
else:
|
570
|
-
print("New file '{}'."
|
623
|
+
print(f"New file '{file_}'.")
|
571
624
|
|
572
625
|
if not managed and not os.path.exists(file_):
|
573
626
|
for pattern in self.get_upgrade("extra"):
|
574
627
|
if re.match(pattern + "$", file_):
|
575
|
-
print("File '{}' is an extra by migration config pattern '{}'."
|
628
|
+
print(f"File '{file_}' is an extra by migration config pattern '{pattern}'.")
|
576
629
|
managed = True
|
577
630
|
|
578
631
|
if not managed:
|
@@ -582,39 +635,29 @@ rules:
|
|
582
635
|
else:
|
583
636
|
pattern = files["pattern"]
|
584
637
|
if re.match(pattern + "$", file_):
|
585
|
-
print(
|
586
|
-
"File '{}' included by project config pattern `managed_files` '{}'.".format(
|
587
|
-
file_, pattern
|
588
|
-
)
|
589
|
-
)
|
638
|
+
print(f"File '{file_}' included by project config pattern `managed_files` '{pattern}'.")
|
590
639
|
print("managed", file_, pattern)
|
591
640
|
managed = True
|
592
641
|
break
|
593
642
|
if managed:
|
594
643
|
for pattern in self.project.get("unmanaged_files", []):
|
595
644
|
if re.match(pattern + "$", file_):
|
596
|
-
print(
|
597
|
-
"File '{}' excluded by project config pattern `unmanaged_files` '{}'.".format(
|
598
|
-
file_, pattern
|
599
|
-
)
|
600
|
-
)
|
645
|
+
print(f"File '{file_}' excluded by project config pattern `unmanaged_files` '{pattern}'.")
|
601
646
|
managed = False
|
602
647
|
break
|
603
648
|
|
604
649
|
return managed
|
605
650
|
|
606
|
-
def files_to_get(self, step, pre=False):
|
651
|
+
def files_to_get(self, step: int, pre: bool = False) -> bool:
|
607
652
|
error = False
|
608
653
|
for root, _, files in os.walk("CONST_create_template"):
|
609
|
-
|
610
|
-
root = root[len("CONST_create_template/"):]
|
611
|
-
# fmt: on
|
654
|
+
root = root[len("CONST_create_template/") :]
|
612
655
|
for file_ in files:
|
613
656
|
destination = os.path.join(root, file_)
|
614
657
|
managed = self.is_managed(destination, True)
|
615
658
|
source = os.path.join("CONST_create_template", destination)
|
616
659
|
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."
|
660
|
+
print(colorize(f"Get the file '{destination}' from the create template.", Color.GREEN))
|
618
661
|
if not pre:
|
619
662
|
if os.path.dirname(destination) != "":
|
620
663
|
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
@@ -633,17 +676,17 @@ rules:
|
|
633
676
|
)
|
634
677
|
sys.exit(1)
|
635
678
|
elif managed:
|
636
|
-
print("The file '{}' is managed by the project."
|
679
|
+
print(f"The file '{destination}' is managed by the project.")
|
637
680
|
elif os.path.exists(destination) and filecmp.cmp(source, destination):
|
638
|
-
print("The file '{}' does not change."
|
681
|
+
print(f"The file '{destination}' does not change.")
|
639
682
|
else:
|
640
|
-
print("Unknown stat for the file '{}'."
|
683
|
+
print(f"Unknown stat for the file '{destination}'.")
|
641
684
|
sys.exit(2)
|
642
685
|
return error
|
643
686
|
|
644
687
|
@Step(8)
|
645
|
-
def step8(self, step):
|
646
|
-
with open("changelog.diff", "w") as diff_file:
|
688
|
+
def step8(self, step: int) -> None:
|
689
|
+
with open("changelog.diff", "w", encoding="utf8") as diff_file:
|
647
690
|
check_call(["git", "diff", "--", "CONST_CHANGELOG.txt"], stdout=diff_file)
|
648
691
|
|
649
692
|
from210 = False
|
@@ -664,30 +707,28 @@ rules:
|
|
664
707
|
"file (listed in the `changelog.diff` file).",
|
665
708
|
)
|
666
709
|
|
667
|
-
def get_modified(self, status_path):
|
668
|
-
status = check_git_status_output([status_path])
|
669
|
-
status = [s for s in status
|
710
|
+
def get_modified(self, status_path: str) -> List[str]:
|
711
|
+
status = check_git_status_output([status_path]).split("\n")
|
712
|
+
status = [s for s in status if len(s) > 3]
|
670
713
|
status = [s[3:] for s in status if s[:3].strip() == "M"]
|
671
714
|
for pattern in self.get_upgrade("no_diff"):
|
672
|
-
matcher = re.compile("CONST_create_template/{}$"
|
715
|
+
matcher = re.compile(f"CONST_create_template/{pattern}$")
|
673
716
|
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
|
717
|
+
status = [s for s in status if os.path.exists(s[len("CONST_create_template/") :])]
|
718
|
+
status = [s for s in status if not filecmp.cmp(s, s[len("CONST_create_template/") :])]
|
678
719
|
return status
|
679
720
|
|
680
721
|
@Step(9)
|
681
|
-
def step9(self, step):
|
722
|
+
def step9(self, step: int) -> None:
|
682
723
|
if os.path.isfile("changelog.diff"):
|
683
724
|
os.unlink("changelog.diff")
|
684
725
|
|
685
726
|
status = self.get_modified(
|
686
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo"
|
727
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo"
|
687
728
|
)
|
688
729
|
status += ["CONST_create_template/geoportal/vars.yaml"]
|
689
730
|
|
690
|
-
with open("ngeo.diff", "w") as diff_file:
|
731
|
+
with open("ngeo.diff", "w", encoding="utf8") as diff_file:
|
691
732
|
if status:
|
692
733
|
check_call(
|
693
734
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -705,7 +746,7 @@ rules:
|
|
705
746
|
)
|
706
747
|
|
707
748
|
@Step(10)
|
708
|
-
def step10(self, step):
|
749
|
+
def step10(self, step: int) -> None:
|
709
750
|
if os.path.isfile("ngeo.diff"):
|
710
751
|
os.unlink("ngeo.diff")
|
711
752
|
|
@@ -714,15 +755,13 @@ rules:
|
|
714
755
|
s
|
715
756
|
for s in status
|
716
757
|
if not s.startswith(
|
717
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo/"
|
718
|
-
self.project["project_package"]
|
719
|
-
)
|
758
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo/"
|
720
759
|
)
|
721
760
|
]
|
722
761
|
status = [s for s in status if s != "CONST_create_template/geoportal/vars.yaml"]
|
723
762
|
|
724
763
|
if status:
|
725
|
-
with open("create.diff", "w") as diff_file:
|
764
|
+
with open("create.diff", "w", encoding="utf8") as diff_file:
|
726
765
|
if status:
|
727
766
|
check_call(
|
728
767
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -743,24 +782,24 @@ rules:
|
|
743
782
|
self.run_step(step + 1)
|
744
783
|
|
745
784
|
@Step(11)
|
746
|
-
def step11(self, step):
|
785
|
+
def step11(self, step: int) -> None:
|
747
786
|
if os.path.isfile("create.diff"):
|
748
787
|
os.unlink("create.diff")
|
749
788
|
|
750
789
|
message = [
|
751
790
|
"The upgrade is nearly done, now you should:",
|
752
791
|
"- Build your application with `./upgrade --finalize [build arguments]`",
|
753
|
-
"- Test your application on '{
|
792
|
+
f"- Test your application on '{self.project.get('application_url', '... missing ...')}'.",
|
754
793
|
]
|
755
794
|
|
756
795
|
if os.path.isfile(".upgrade.yaml"):
|
757
796
|
os.unlink(".upgrade.yaml")
|
758
|
-
with open(".UPGRADE_SUCCESS", "w"):
|
797
|
+
with open(".UPGRADE_SUCCESS", "w", encoding="utf8"):
|
759
798
|
pass
|
760
799
|
self.print_step(step + 1, message="\n".join(message))
|
761
800
|
|
762
801
|
@Step(12, file_marker=False)
|
763
|
-
def step12(self, step):
|
802
|
+
def step12(self, step: int) -> None:
|
764
803
|
if os.path.isfile(".UPGRADE_SUCCESS"):
|
765
804
|
os.unlink(".UPGRADE_SUCCESS")
|
766
805
|
good, message = self.test_checkers()
|
@@ -772,12 +811,12 @@ rules:
|
|
772
811
|
error=True,
|
773
812
|
message=message,
|
774
813
|
prompt="Correct the checker, then run the step again "
|
775
|
-
"(If you want to fix it later you can pass to the next step):",
|
814
|
+
"(If you want to fix it later you can pass to the next step:int):",
|
776
815
|
)
|
777
816
|
sys.exit(1)
|
778
817
|
|
779
818
|
@Step(13, file_marker=False)
|
780
|
-
def step13(self, step):
|
819
|
+
def step13(self, step: int) -> None:
|
781
820
|
# Required to remove from the Git stage the ignored file when we lunch the step again
|
782
821
|
check_call(["git", "reset", "--mixed"])
|
783
822
|
|
@@ -788,35 +827,35 @@ rules:
|
|
788
827
|
step + 1,
|
789
828
|
message="We will commit all the above files!\n"
|
790
829
|
"If there are some files which should not be committed, then you should "
|
791
|
-
"add them into the `.gitignore` file and launch upgrade {} again."
|
830
|
+
f"add them into the `.gitignore` file and launch upgrade {step} again.",
|
792
831
|
prompt="Then to commit your changes type:",
|
793
832
|
)
|
794
833
|
|
795
834
|
@Step(14, file_marker=False)
|
796
|
-
def step14(self, _):
|
835
|
+
def step14(self, _: int) -> None:
|
797
836
|
if os.path.isfile(".UPGRADE_INSTRUCTIONS"):
|
798
837
|
os.unlink(".UPGRADE_INSTRUCTIONS")
|
799
838
|
check_call(
|
800
839
|
[
|
801
840
|
"git",
|
802
841
|
"commit",
|
803
|
-
"--message=Upgrade to GeoMapFish
|
804
|
-
|
805
|
-
),
|
842
|
+
"--message=Upgrade to GeoMapFish "
|
843
|
+
f"{pkg_resources.get_distribution('c2cgeoportal_commons').version}",
|
806
844
|
]
|
807
845
|
)
|
808
846
|
|
809
847
|
print("")
|
810
848
|
print(self.color_bar)
|
811
849
|
print("")
|
812
|
-
print(colorize("Congratulations, your upgrade was successful.", GREEN))
|
850
|
+
print(colorize("Congratulations, your upgrade was successful.", Color.GREEN))
|
813
851
|
print("")
|
814
852
|
branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
|
815
853
|
print("Now all your files are committed; you should do a git push:")
|
816
|
-
print("git push {
|
854
|
+
print(f"git push {self.options.git_remote} {branch}.")
|
817
855
|
|
818
856
|
|
819
|
-
def check_git_status_output(args=None):
|
857
|
+
def check_git_status_output(args: Optional[List[str]] = None) -> str:
|
858
|
+
"""Check if there is something that's not committed."""
|
820
859
|
return check_output(["git", "status", "--short"] + (args if args is not None else [])).decode("utf-8")
|
821
860
|
|
822
861
|
|