c2cgeoportal-geoportal 2.5.0.100__py2.py3-none-any.whl → 2.7.1.83__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 +261 -130
- c2cgeoportal_geoportal/lib/__init__.py +72 -120
- c2cgeoportal_geoportal/lib/authentication.py +170 -21
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +19 -11
- c2cgeoportal_geoportal/lib/caching.py +66 -160
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +62 -64
- c2cgeoportal_geoportal/lib/common_headers.py +170 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +70 -31
- c2cgeoportal_geoportal/lib/filter_capabilities.py +124 -96
- c2cgeoportal_geoportal/lib/fulltextsearch.py +50 -0
- c2cgeoportal_geoportal/lib/functionality.py +36 -21
- c2cgeoportal_geoportal/lib/headers.py +14 -5
- c2cgeoportal_geoportal/lib/i18n.py +39 -0
- c2cgeoportal_geoportal/lib/layers.py +29 -10
- c2cgeoportal_geoportal/lib/lingua_extractor.py +408 -211
- c2cgeoportal_geoportal/lib/loader.py +18 -16
- c2cgeoportal_geoportal/lib/metrics.py +29 -18
- c2cgeoportal_geoportal/lib/oauth2.py +1036 -0
- c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
- c2cgeoportal_geoportal/lib/xsd.py +29 -19
- 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/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -4
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +24 -15
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +1 -0
- 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 +104 -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/advance_create/{{cookiecutter.project}}/geoportal/setup.py +25 -0
- 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 +4 -4
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +47 -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/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js +12 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js +25 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +3 -6
- c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +32 -20
- 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} +4 -8
- 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} +34 -24
- 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 +158 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +474 -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} +43 -18
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +82 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +60 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +396 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-blue.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-gold.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-green.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker.png +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 +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +30 -27
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/legend.jrxml +109 -0
- 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/{{cookiecutter.project}}/pyproject.toml +3 -0
- 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 +107 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +111 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/setup.cfg +7 -0
- 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/{{cookiecutter.project}}/.upgrade.yaml +191 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1153 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +99 -47
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +1412 -0
- c2cgeoportal_geoportal/scripts/__init__.py +17 -33
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +295 -200
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +5 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -37
- c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +92 -25
- c2cgeoportal_geoportal/scripts/urllogin.py +23 -17
- c2cgeoportal_geoportal/templates/login.html +88 -84
- c2cgeoportal_geoportal/templates/notlogin.html +62 -0
- 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 +70 -40
- c2cgeoportal_geoportal/views/entry.py +93 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +36 -29
- c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +173 -134
- c2cgeoportal_geoportal/views/login.py +206 -87
- c2cgeoportal_geoportal/views/mapserverproxy.py +59 -35
- c2cgeoportal_geoportal/views/memory.py +13 -13
- c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
- c2cgeoportal_geoportal/views/pdfreport.py +31 -27
- c2cgeoportal_geoportal/views/printproxy.py +67 -53
- c2cgeoportal_geoportal/views/profile.py +25 -24
- c2cgeoportal_geoportal/views/proxy.py +97 -68
- c2cgeoportal_geoportal/views/raster.py +47 -29
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +31 -24
- c2cgeoportal_geoportal/views/theme.py +475 -365
- c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/METADATA +16 -11
- c2cgeoportal_geoportal-2.7.1.83.dist-info/RECORD +185 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/entry_points.txt +3 -1
- tests/__init__.py +24 -3
- tests/test_cachebuster.py +1 -3
- tests/test_caching.py +19 -26
- tests/test_checker.py +2 -3
- tests/test_decimaljson.py +4 -4
- tests/test_headerstween.py +0 -3
- tests/test_i18n.py +31 -0
- tests/test_init.py +12 -27
- tests/test_locale_negociator.py +6 -6
- tests/test_mapserverproxy_route_predicate.py +0 -2
- tests/test_raster.py +18 -5
- tests/test_wmstparsing.py +7 -8
- c2cgeoportal_geoportal/scaffolds/__init__.py +0 -226
- c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -11
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/ci.yaml_tmpl +0 -56
- c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -12
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -144
- c2cgeoportal_geoportal/scaffolds/create/docker-compose-lib.yaml_tmpl +0 -302
- c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml_tmpl +0 -54
- c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -49
- c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -39
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -5
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -19
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -48
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/images/favicon.ico +0 -0
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl +0 -37
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl +0 -22
- c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
- c2cgeoportal_geoportal/scaffolds/create/geoportal/requirements.txt +0 -2
- c2cgeoportal_geoportal/scaffolds/create/geoportal/setup.py_tmpl +0 -18
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
- c2cgeoportal_geoportal/scaffolds/create/geoportal/vars.yaml_tmpl +0 -224
- c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -71
- 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 -166
- c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/legend.jrxml +0 -27
- c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -29
- c2cgeoportal_geoportal/scaffolds/create/scripts/publish-docker +0 -124
- c2cgeoportal_geoportal/scaffolds/create/setup.cfg_tmpl +0 -3
- c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -169
- c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
- c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -171
- c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -64
- c2cgeoportal_geoportal/scaffolds/update/geoportal/CONST_vars.yaml_tmpl +0 -783
- c2cgeoportal_geoportal/templates/dynamic.js +0 -21
- c2cgeoportal_geoportal-2.5.0.100.dist-info/RECORD +0 -162
- tests/test_get_url.py +0 -96
- tests/test_lib.py +0 -77
- /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/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/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}}}/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/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2014-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2014-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -29,22 +27,23 @@
|
|
29
27
|
|
30
28
|
|
31
29
|
import argparse
|
32
|
-
from argparse import ArgumentParser
|
33
30
|
import atexit
|
34
31
|
import filecmp
|
35
32
|
import os
|
36
33
|
import re
|
37
34
|
import shutil
|
38
35
|
import subprocess
|
39
|
-
from subprocess import call, check_call, check_output
|
40
36
|
import sys
|
41
|
-
from
|
37
|
+
from argparse import ArgumentParser, Namespace
|
38
|
+
from json.decoder import JSONDecodeError
|
39
|
+
from subprocess import call, check_call, check_output
|
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)
|
66
95
|
|
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,9 +103,8 @@ def main():
|
|
71
103
|
c2cupgradetool.upgrade()
|
72
104
|
|
73
105
|
|
74
|
-
def _fill_arguments():
|
106
|
+
def _fill_arguments() -> ArgumentParser:
|
75
107
|
parser = ArgumentParser()
|
76
|
-
parser.add_argument("version", nargs="?", help="No more used")
|
77
108
|
parser.add_argument(
|
78
109
|
"--git-remote", metavar="GITREMOTE", help="Specify the remote branch", default="origin"
|
79
110
|
)
|
@@ -83,38 +114,40 @@ def _fill_arguments():
|
|
83
114
|
|
84
115
|
|
85
116
|
class InteruptedException(Exception):
|
86
|
-
|
117
|
+
"""The interrupted exception."""
|
87
118
|
|
88
119
|
|
89
120
|
current_step_number = 0
|
90
121
|
|
91
122
|
|
92
123
|
class Step:
|
93
|
-
|
124
|
+
"""Decorator used for en upgrade step."""
|
125
|
+
|
126
|
+
def __init__(self, step_number: int, file_marker: bool = True):
|
94
127
|
global current_step_number
|
95
128
|
current_step_number = step_number
|
96
129
|
self.step_number = step_number
|
97
130
|
self.file_marker = file_marker
|
98
131
|
|
99
|
-
def __call__(
|
100
|
-
|
132
|
+
def __call__(
|
133
|
+
self, current_step: Callable[["C2cUpgradeTool", int], None]
|
134
|
+
) -> Callable[["C2cUpgradeTool"], None]:
|
135
|
+
def decorate(c2cupgradetool: "C2cUpgradeTool") -> None:
|
101
136
|
try:
|
102
|
-
if os.path.isfile(".UPGRADE{
|
103
|
-
os.unlink(".UPGRADE{
|
137
|
+
if os.path.isfile(f".UPGRADE{self.step_number - 1}"):
|
138
|
+
os.unlink(f".UPGRADE{self.step_number - 1}")
|
104
139
|
if self.file_marker:
|
105
|
-
with open(".UPGRADE{
|
140
|
+
with open(f".UPGRADE{self.step_number}", "w", encoding="utf8"):
|
106
141
|
pass
|
107
|
-
print("Start step {}."
|
142
|
+
print(f"Start step {self.step_number}.")
|
108
143
|
sys.stdout.flush()
|
109
|
-
current_step(c2cupgradetool, self.step_number
|
144
|
+
current_step(c2cupgradetool, self.step_number)
|
110
145
|
except subprocess.CalledProcessError as exception:
|
146
|
+
command = " ".join([f"'{exception}'" for exception in exception.cmd])
|
111
147
|
c2cupgradetool.print_step(
|
112
148
|
self.step_number,
|
113
149
|
error=True,
|
114
|
-
message="The command `{}` returns the error code {}."
|
115
|
-
" ".join(["'{}'".format(exception) for exception in exception.cmd]),
|
116
|
-
exception.returncode,
|
117
|
-
),
|
150
|
+
message=f"The command `{command}` returns the error code {exception.returncode}.",
|
118
151
|
prompt="Fix the error and run the step again:",
|
119
152
|
)
|
120
153
|
sys.exit(1)
|
@@ -122,21 +155,20 @@ class Step:
|
|
122
155
|
c2cupgradetool.print_step(
|
123
156
|
self.step_number,
|
124
157
|
error=True,
|
125
|
-
message="There was an error: {}."
|
158
|
+
message=f"There was an error: {exception}.",
|
126
159
|
prompt="Fix the error and run the step again:",
|
127
160
|
)
|
128
161
|
sys.exit(1)
|
129
162
|
except Exception as exception:
|
130
|
-
|
163
|
+
catch_exception = exception
|
131
164
|
|
132
|
-
global current_step_number
|
133
165
|
if self.step_number == current_step_number:
|
134
166
|
|
135
|
-
def message():
|
167
|
+
def message() -> None:
|
136
168
|
c2cupgradetool.print_step(
|
137
169
|
self.step_number,
|
138
170
|
error=True,
|
139
|
-
message="The step had the error '{}'."
|
171
|
+
message=f"The step had the error '{catch_exception}'.",
|
140
172
|
prompt="Fix the error and run the step again:",
|
141
173
|
)
|
142
174
|
|
@@ -147,84 +179,101 @@ class Step:
|
|
147
179
|
|
148
180
|
|
149
181
|
class C2cUpgradeTool:
|
182
|
+
"""The tool used to upgrade the application."""
|
150
183
|
|
151
|
-
color_bar = colorize("================================================================", GREEN)
|
184
|
+
color_bar = colorize("================================================================", Color.GREEN)
|
152
185
|
|
153
|
-
def __init__(self, options):
|
186
|
+
def __init__(self, options: Namespace):
|
154
187
|
self.options = options
|
155
|
-
self.project
|
188
|
+
self.project = self.get_project()
|
156
189
|
|
157
190
|
@staticmethod
|
158
|
-
def get_project():
|
191
|
+
def get_project() -> Dict[str, Any]:
|
159
192
|
if not os.path.isfile("project.yaml"):
|
160
|
-
print(colorize("Unable to find the required 'project.yaml' file.", RED))
|
193
|
+
print(colorize("Unable to find the required 'project.yaml' file.", Color.RED))
|
161
194
|
sys.exit(1)
|
162
195
|
|
163
|
-
with open("project.yaml", "
|
164
|
-
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))
|
165
198
|
|
166
199
|
@staticmethod
|
167
|
-
def get_upgrade(section):
|
200
|
+
def get_upgrade(section: str) -> Union[List[Any], Dict[str, Any]]:
|
168
201
|
if not os.path.isfile(".upgrade.yaml"):
|
169
|
-
print(colorize("Unable to find the required '.upgrade.yaml' file.", RED))
|
202
|
+
print(colorize("Unable to find the required '.upgrade.yaml' file.", Color.RED))
|
170
203
|
sys.exit(1)
|
171
204
|
|
172
|
-
with open(".upgrade.yaml", "
|
173
|
-
return yaml.safe_load(project_file)[section]
|
174
|
-
|
175
|
-
def print_step(
|
176
|
-
|
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:
|
177
216
|
print("")
|
178
217
|
print(self.color_bar)
|
179
218
|
if message is not None:
|
180
|
-
print(colorize(message, RED if error else YELLOW))
|
181
|
-
instructions.write("{}\n"
|
219
|
+
print(colorize(message, Color.RED if error else Color.YELLOW))
|
220
|
+
instructions.write(f"{message}\n")
|
182
221
|
if step >= 0:
|
183
|
-
print(colorize(prompt, GREEN))
|
184
|
-
instructions.write("{}\n"
|
222
|
+
print(colorize(prompt, Color.GREEN))
|
223
|
+
instructions.write(f"{prompt}\n")
|
185
224
|
cmd = ["./upgrade", os.environ["VERSION"]]
|
186
225
|
if step != 0:
|
187
|
-
cmd.append("{}"
|
188
|
-
print(colorize(" ".join(cmd), GREEN))
|
189
|
-
instructions.write("{
|
226
|
+
cmd.append(f"{step}")
|
227
|
+
print(colorize(" ".join(cmd), Color.GREEN))
|
228
|
+
instructions.write(f"{' '.join(cmd)}\n")
|
190
229
|
|
191
|
-
def run_step(self, step):
|
192
|
-
getattr(self, "step{}"
|
230
|
+
def run_step(self, step: int) -> None:
|
231
|
+
getattr(self, f"step{step}")()
|
193
232
|
|
194
|
-
def test_checkers(self):
|
195
|
-
|
196
|
-
|
197
|
-
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()]
|
198
236
|
)
|
237
|
+
run_curl = f"Run `curl --insecure {headers} '{self.project['checker_url']}'` for more information."
|
199
238
|
try:
|
200
|
-
requests.packages.urllib3.disable_warnings()
|
239
|
+
requests.packages.urllib3.disable_warnings() # type: ignore
|
201
240
|
resp = requests.get(
|
202
|
-
self.project["checker_url"],
|
241
|
+
self.project["checker_url"],
|
242
|
+
headers=self.project.get("checker_headers"),
|
243
|
+
verify=False, # nosec
|
203
244
|
)
|
204
245
|
except requests.exceptions.ConnectionError as exception:
|
205
|
-
return False, "\n".join(["Connection error: {}"
|
246
|
+
return False, "\n".join([f"Connection error: {exception}", run_curl])
|
206
247
|
except ConnectionRefusedError as exception:
|
207
|
-
return False, "\n".join(["Connection refused: {}"
|
248
|
+
return False, "\n".join([f"Connection refused: {exception}", run_curl])
|
208
249
|
if resp.status_code < 200 or resp.status_code >= 300:
|
209
250
|
|
210
|
-
print(colorize("=============", RED))
|
211
|
-
print(colorize("Checker error", RED))
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
+
)
|
218
267
|
|
219
268
|
return False, "\n".join(["Checker error:", run_curl])
|
220
269
|
|
221
270
|
return True, None
|
222
271
|
|
223
|
-
def upgrade(self):
|
272
|
+
def upgrade(self) -> None:
|
224
273
|
self.run_step(self.options.step)
|
225
274
|
|
226
275
|
@Step(0, file_marker=False)
|
227
|
-
def step0(self, step):
|
276
|
+
def step0(self, step: int) -> None:
|
228
277
|
project_template_keys = list(cast(Dict[str, Any], self.project.get("template_vars")).keys())
|
229
278
|
messages = []
|
230
279
|
for required in REQUIRED_TEMPLATE_KEYS:
|
@@ -254,11 +303,13 @@ class C2cUpgradeTool:
|
|
254
303
|
self.print_step(
|
255
304
|
step + 1,
|
256
305
|
message="Here is the output of 'git status'. Please make sure to commit all your "
|
257
|
-
"changes before going further. All uncommitted changes will be lost
|
306
|
+
"changes before going further. All uncommitted changes will be lost.\n"
|
307
|
+
"Note that for debugging purpose it is possible to pass directly to step 2 "
|
308
|
+
f"e.-g.: ./upgrade --debug=../c2cgeoportal {os.environ['VERSION']} 2",
|
258
309
|
)
|
259
310
|
|
260
311
|
@Step(1)
|
261
|
-
def step1(self, step):
|
312
|
+
def step1(self, step: int) -> None:
|
262
313
|
shutil.copyfile("project.yaml", "/tmp/project.yaml")
|
263
314
|
try:
|
264
315
|
check_call(["git", "reset", "--hard"])
|
@@ -269,22 +320,38 @@ class C2cUpgradeTool:
|
|
269
320
|
self.run_step(step + 1)
|
270
321
|
|
271
322
|
@Step(2)
|
272
|
-
def step2(self, step):
|
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
|
327
|
+
|
328
|
+
self.run_step(step + 1)
|
329
|
+
|
330
|
+
@Step(3)
|
331
|
+
def step3(self, step: int) -> None:
|
273
332
|
project_path = os.path.join("/tmp", self.project["project_folder"])
|
274
333
|
os.mkdir(project_path)
|
275
334
|
shutil.copyfile("/src/project.yaml", os.path.join(project_path, "project.yaml"))
|
276
335
|
check_call(
|
277
336
|
[
|
278
337
|
"pcreate",
|
279
|
-
"--ignore-conflicting-name",
|
280
338
|
"--overwrite",
|
281
|
-
"--scaffold=
|
339
|
+
"--scaffold=update",
|
282
340
|
project_path,
|
283
341
|
]
|
284
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
|
+
)
|
285
352
|
|
286
353
|
shutil.copyfile(os.path.join(project_path, ".upgrade.yaml"), ".upgrade.yaml")
|
287
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
354
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
288
355
|
action = upgrade_file["action"]
|
289
356
|
if action == "remove":
|
290
357
|
self.files_to_remove(upgrade_file, prefix="CONST_create_template", force=True)
|
@@ -299,8 +366,8 @@ class C2cUpgradeTool:
|
|
299
366
|
|
300
367
|
self.run_step(step + 1)
|
301
368
|
|
302
|
-
@Step(
|
303
|
-
def
|
369
|
+
@Step(4)
|
370
|
+
def step4(self, step: int) -> None:
|
304
371
|
if os.path.exists("CONST_create_template"):
|
305
372
|
check_call(["git", "rm", "-r", "--force", "CONST_create_template/"])
|
306
373
|
|
@@ -309,37 +376,79 @@ class C2cUpgradeTool:
|
|
309
376
|
check_call(
|
310
377
|
[
|
311
378
|
"pcreate",
|
312
|
-
"--ignore-conflicting-name",
|
313
379
|
"--overwrite",
|
314
|
-
"--scaffold=
|
380
|
+
"--scaffold=update",
|
315
381
|
project_path,
|
316
382
|
]
|
317
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
|
+
)
|
318
393
|
os.remove(project_path)
|
319
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
|
+
|
320
429
|
check_call(["git", "add", "--all", "CONST_create_template/"])
|
321
430
|
check_call(["git", "clean", "-Xf", "CONST_create_template/"])
|
322
431
|
self.run_step(step + 1)
|
323
432
|
|
324
|
-
@Step(
|
325
|
-
def
|
433
|
+
@Step(5)
|
434
|
+
def step5(self, step: int) -> None:
|
326
435
|
if "managed_files" not in self.project:
|
436
|
+
unmanaged_files = "\n".join(["- " + e for e in self.project.get("unmanaged_files", [])])
|
327
437
|
self.print_step(
|
328
438
|
step,
|
329
|
-
message="In the new version, we will also manage almost all the create "
|
330
|
-
"
|
331
|
-
"
|
332
|
-
"
|
333
|
-
"`[]`.".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 `[]`.",
|
334
443
|
prompt="Fill it and run the step again:",
|
335
444
|
)
|
336
445
|
else:
|
337
446
|
self.run_step(step + 1)
|
338
447
|
|
339
|
-
@Step(
|
340
|
-
def
|
448
|
+
@Step(6)
|
449
|
+
def step6(self, step: int) -> None:
|
341
450
|
task_to_do = False
|
342
|
-
for upgrade_file in self.get_upgrade("upgrade_files"):
|
451
|
+
for upgrade_file in cast(List[Dict[str, Any]], self.get_upgrade("upgrade_files")):
|
343
452
|
action = upgrade_file["action"]
|
344
453
|
if action == "remove":
|
345
454
|
task_to_do |= self.files_to_remove(upgrade_file)
|
@@ -361,7 +470,7 @@ class C2cUpgradeTool:
|
|
361
470
|
else:
|
362
471
|
self.run_step(step + 1)
|
363
472
|
|
364
|
-
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:
|
365
474
|
task_to_do = False
|
366
475
|
for path in element["paths"]:
|
367
476
|
file_ = os.path.join(prefix, path.format(package=self.project["project_package"]))
|
@@ -379,31 +488,30 @@ class C2cUpgradeTool:
|
|
379
488
|
if no_touch:
|
380
489
|
managed = True
|
381
490
|
else:
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
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
|
+
)
|
389
498
|
task_to_do = True
|
390
499
|
for pattern in self.project.get("unmanaged_files", []):
|
391
500
|
if re.match(pattern + "$", file_):
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
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
|
+
)
|
399
508
|
task_to_do = True
|
400
509
|
if not managed:
|
401
|
-
print("The file '{}' is removed."
|
510
|
+
print(f"The file '{file_}' is removed.")
|
402
511
|
if "version" in element and "from" in element:
|
403
512
|
print(
|
404
|
-
"Was used in version {}, to be removed from version
|
405
|
-
|
406
|
-
)
|
513
|
+
f"Was used in version {element['from']}, to be removed from version "
|
514
|
+
f"{element['version']}."
|
407
515
|
)
|
408
516
|
if os.path.isdir(file_):
|
409
517
|
shutil.rmtree(file_)
|
@@ -411,7 +519,7 @@ class C2cUpgradeTool:
|
|
411
519
|
os.remove(file_)
|
412
520
|
return task_to_do
|
413
521
|
|
414
|
-
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:
|
415
523
|
task_to_do = False
|
416
524
|
src = os.path.join(prefix, element["from"].format(package=self.project["project_package"]))
|
417
525
|
dst = os.path.join(prefix, element["to"].format(package=self.project["project_package"]))
|
@@ -432,20 +540,18 @@ class C2cUpgradeTool:
|
|
432
540
|
else:
|
433
541
|
print(
|
434
542
|
colorize(
|
435
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
436
|
-
"but it has been moved to '{}'."
|
437
|
-
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,
|
438
546
|
)
|
439
547
|
)
|
440
548
|
task_to_do = True
|
441
549
|
if re.match(pattern + "$", dst):
|
442
550
|
print(
|
443
551
|
colorize(
|
444
|
-
"The {} '{}' is present in the `managed_files` as '{}', "
|
445
|
-
"but a file have been moved on it from '{}'."
|
446
|
-
|
447
|
-
),
|
448
|
-
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,
|
449
555
|
)
|
450
556
|
)
|
451
557
|
task_to_do = True
|
@@ -453,45 +559,46 @@ class C2cUpgradeTool:
|
|
453
559
|
if re.match(pattern + "$", src):
|
454
560
|
print(
|
455
561
|
colorize(
|
456
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
457
|
-
"but it has been moved to '{}'."
|
458
|
-
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,
|
459
565
|
)
|
460
566
|
)
|
461
567
|
task_to_do = True
|
462
568
|
if re.match(pattern + "$", dst):
|
463
569
|
print(
|
464
570
|
colorize(
|
465
|
-
"The {} '{}' is present in the `unmanaged_files` as '{}', "
|
466
|
-
"but a file have been moved on it from '{}'."
|
467
|
-
|
468
|
-
),
|
469
|
-
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,
|
470
574
|
)
|
471
575
|
)
|
472
576
|
task_to_do = True
|
473
|
-
if not managed and os.path.exists(dst):
|
474
|
-
print(colorize("The destination '{}' already exists, ignoring."
|
577
|
+
if not managed and os.path.exists(dst) and not element.get("override", False):
|
578
|
+
print(colorize(f"The destination '{dst}' already exists, ignoring.", Color.YELLOW))
|
475
579
|
elif not managed:
|
476
|
-
print("Move the {} '{}' to '{}'."
|
580
|
+
print(f"Move the {type_} '{src}' to '{dst}'.")
|
477
581
|
if "version" in element:
|
478
|
-
print("Needed from version {
|
582
|
+
print(f"Needed from version {element['version']}.")
|
479
583
|
if os.path.dirname(dst) != "":
|
480
584
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
481
585
|
try:
|
482
586
|
check_call(["git", "mv", src, dst])
|
483
587
|
except Exception as exception:
|
484
|
-
print("[Warning] Git move error: {}."
|
588
|
+
print(f"[Warning] Git move error: {exception}.")
|
485
589
|
os.rename(src, dst)
|
486
590
|
return task_to_do
|
487
591
|
|
488
|
-
@Step(
|
489
|
-
def
|
592
|
+
@Step(7)
|
593
|
+
def step7(self, step: int) -> None:
|
490
594
|
self.files_to_get(step)
|
491
595
|
self.run_step(step + 1)
|
492
596
|
|
493
|
-
def is_managed(self, file_, files_to_get=False):
|
494
|
-
|
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"))
|
495
602
|
|
496
603
|
# Managed means managed by the application owner, not the c2cupgrade
|
497
604
|
managed = False
|
@@ -502,23 +609,23 @@ class C2cUpgradeTool:
|
|
502
609
|
):
|
503
610
|
for pattern in default_project_file["include"]:
|
504
611
|
if re.match(pattern + "$", file_):
|
505
|
-
print("File '{}' included by migration config pattern '{}'."
|
612
|
+
print(f"File '{file_}' included by migration config pattern '{pattern}'.")
|
506
613
|
managed = True
|
507
614
|
break
|
508
615
|
if managed:
|
509
616
|
for pattern in default_project_file["exclude"]:
|
510
617
|
if re.match(pattern + "$", file_):
|
511
|
-
print("File '{}' excluded by migration config pattern '{}'."
|
618
|
+
print(f"File '{file_}' excluded by migration config pattern '{pattern}'.")
|
512
619
|
print("managed", file_, pattern)
|
513
620
|
managed = False
|
514
621
|
break
|
515
622
|
else:
|
516
|
-
print("New file '{}'."
|
623
|
+
print(f"New file '{file_}'.")
|
517
624
|
|
518
625
|
if not managed and not os.path.exists(file_):
|
519
626
|
for pattern in self.get_upgrade("extra"):
|
520
627
|
if re.match(pattern + "$", file_):
|
521
|
-
print("File '{}' is an extra by migration config pattern '{}'."
|
628
|
+
print(f"File '{file_}' is an extra by migration config pattern '{pattern}'.")
|
522
629
|
managed = True
|
523
630
|
|
524
631
|
if not managed:
|
@@ -528,39 +635,29 @@ class C2cUpgradeTool:
|
|
528
635
|
else:
|
529
636
|
pattern = files["pattern"]
|
530
637
|
if re.match(pattern + "$", file_):
|
531
|
-
print(
|
532
|
-
"File '{}' included by project config pattern `managed_files` '{}'.".format(
|
533
|
-
file_, pattern
|
534
|
-
)
|
535
|
-
)
|
638
|
+
print(f"File '{file_}' included by project config pattern `managed_files` '{pattern}'.")
|
536
639
|
print("managed", file_, pattern)
|
537
640
|
managed = True
|
538
641
|
break
|
539
642
|
if managed:
|
540
643
|
for pattern in self.project.get("unmanaged_files", []):
|
541
644
|
if re.match(pattern + "$", file_):
|
542
|
-
print(
|
543
|
-
"File '{}' excluded by project config pattern `unmanaged_files` '{}'.".format(
|
544
|
-
file_, pattern
|
545
|
-
)
|
546
|
-
)
|
645
|
+
print(f"File '{file_}' excluded by project config pattern `unmanaged_files` '{pattern}'.")
|
547
646
|
managed = False
|
548
647
|
break
|
549
648
|
|
550
649
|
return managed
|
551
650
|
|
552
|
-
def files_to_get(self, step, pre=False):
|
651
|
+
def files_to_get(self, step: int, pre: bool = False) -> bool:
|
553
652
|
error = False
|
554
653
|
for root, _, files in os.walk("CONST_create_template"):
|
555
|
-
|
556
|
-
root = root[len("CONST_create_template/"):]
|
557
|
-
# fmt: on
|
654
|
+
root = root[len("CONST_create_template/") :]
|
558
655
|
for file_ in files:
|
559
656
|
destination = os.path.join(root, file_)
|
560
657
|
managed = self.is_managed(destination, True)
|
561
658
|
source = os.path.join("CONST_create_template", destination)
|
562
659
|
if not managed and (not os.path.exists(destination) or not filecmp.cmp(source, destination)):
|
563
|
-
print(colorize("Get the file '{}' from the create template."
|
660
|
+
print(colorize(f"Get the file '{destination}' from the create template.", Color.GREEN))
|
564
661
|
if not pre:
|
565
662
|
if os.path.dirname(destination) != "":
|
566
663
|
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
@@ -579,17 +676,17 @@ class C2cUpgradeTool:
|
|
579
676
|
)
|
580
677
|
sys.exit(1)
|
581
678
|
elif managed:
|
582
|
-
print("The file '{}' is managed by the project."
|
679
|
+
print(f"The file '{destination}' is managed by the project.")
|
583
680
|
elif os.path.exists(destination) and filecmp.cmp(source, destination):
|
584
|
-
print("The file '{}' does not change."
|
681
|
+
print(f"The file '{destination}' does not change.")
|
585
682
|
else:
|
586
|
-
print("Unknown stat for the file '{}'."
|
683
|
+
print(f"Unknown stat for the file '{destination}'.")
|
587
684
|
sys.exit(2)
|
588
685
|
return error
|
589
686
|
|
590
|
-
@Step(
|
591
|
-
def
|
592
|
-
with open("changelog.diff", "w") as diff_file:
|
687
|
+
@Step(8)
|
688
|
+
def step8(self, step: int) -> None:
|
689
|
+
with open("changelog.diff", "w", encoding="utf8") as diff_file:
|
593
690
|
check_call(["git", "diff", "--", "CONST_CHANGELOG.txt"], stdout=diff_file)
|
594
691
|
|
595
692
|
from210 = False
|
@@ -610,29 +707,28 @@ class C2cUpgradeTool:
|
|
610
707
|
"file (listed in the `changelog.diff` file).",
|
611
708
|
)
|
612
709
|
|
613
|
-
def get_modified(self, status_path):
|
614
|
-
status = check_git_status_output([status_path])
|
615
|
-
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]
|
616
713
|
status = [s[3:] for s in status if s[:3].strip() == "M"]
|
617
714
|
for pattern in self.get_upgrade("no_diff"):
|
618
|
-
matcher = re.compile("CONST_create_template/{}$"
|
715
|
+
matcher = re.compile(f"CONST_create_template/{pattern}$")
|
619
716
|
status = [s for s in status if not matcher.match(s)]
|
620
|
-
|
621
|
-
status = [s for s in status if
|
622
|
-
status = [s for s in status if not filecmp.cmp(s, s[len("CONST_create_template/"):])]
|
623
|
-
# 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/") :])]
|
624
719
|
return status
|
625
720
|
|
626
|
-
@Step(
|
627
|
-
def
|
721
|
+
@Step(9)
|
722
|
+
def step9(self, step: int) -> None:
|
628
723
|
if os.path.isfile("changelog.diff"):
|
629
724
|
os.unlink("changelog.diff")
|
630
725
|
|
631
726
|
status = self.get_modified(
|
632
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo"
|
727
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo"
|
633
728
|
)
|
729
|
+
status += ["CONST_create_template/geoportal/vars.yaml"]
|
634
730
|
|
635
|
-
with open("ngeo.diff", "w") as diff_file:
|
731
|
+
with open("ngeo.diff", "w", encoding="utf8") as diff_file:
|
636
732
|
if status:
|
637
733
|
check_call(
|
638
734
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -649,8 +745,8 @@ class C2cUpgradeTool:
|
|
649
745
|
+ "\nNote that you can also apply them using: git apply --3way ngeo.diff",
|
650
746
|
)
|
651
747
|
|
652
|
-
@Step(
|
653
|
-
def
|
748
|
+
@Step(10)
|
749
|
+
def step10(self, step: int) -> None:
|
654
750
|
if os.path.isfile("ngeo.diff"):
|
655
751
|
os.unlink("ngeo.diff")
|
656
752
|
|
@@ -659,14 +755,13 @@ class C2cUpgradeTool:
|
|
659
755
|
s
|
660
756
|
for s in status
|
661
757
|
if not s.startswith(
|
662
|
-
"CONST_create_template/geoportal/{}_geoportal/static-ngeo/"
|
663
|
-
self.project["project_package"]
|
664
|
-
)
|
758
|
+
f"CONST_create_template/geoportal/{self.project['project_package']}_geoportal/static-ngeo/"
|
665
759
|
)
|
666
760
|
]
|
761
|
+
status = [s for s in status if s != "CONST_create_template/geoportal/vars.yaml"]
|
667
762
|
|
668
763
|
if status:
|
669
|
-
with open("create.diff", "w") as diff_file:
|
764
|
+
with open("create.diff", "w", encoding="utf8") as diff_file:
|
670
765
|
if status:
|
671
766
|
check_call(
|
672
767
|
["git", "diff", "--relative=CONST_create_template", "--staged", "--"] + status,
|
@@ -686,25 +781,25 @@ class C2cUpgradeTool:
|
|
686
781
|
else:
|
687
782
|
self.run_step(step + 1)
|
688
783
|
|
689
|
-
@Step(
|
690
|
-
def
|
784
|
+
@Step(11)
|
785
|
+
def step11(self, step: int) -> None:
|
691
786
|
if os.path.isfile("create.diff"):
|
692
787
|
os.unlink("create.diff")
|
693
788
|
|
694
789
|
message = [
|
695
790
|
"The upgrade is nearly done, now you should:",
|
696
|
-
"- Build your application with
|
697
|
-
"- Test your application on '{
|
791
|
+
"- Build your application with `./upgrade --finalize [build arguments]`",
|
792
|
+
f"- Test your application on '{self.project.get('application_url', '... missing ...')}'.",
|
698
793
|
]
|
699
794
|
|
700
795
|
if os.path.isfile(".upgrade.yaml"):
|
701
796
|
os.unlink(".upgrade.yaml")
|
702
|
-
with open(".UPGRADE_SUCCESS", "w"):
|
797
|
+
with open(".UPGRADE_SUCCESS", "w", encoding="utf8"):
|
703
798
|
pass
|
704
799
|
self.print_step(step + 1, message="\n".join(message))
|
705
800
|
|
706
|
-
@Step(
|
707
|
-
def
|
801
|
+
@Step(12, file_marker=False)
|
802
|
+
def step12(self, step: int) -> None:
|
708
803
|
if os.path.isfile(".UPGRADE_SUCCESS"):
|
709
804
|
os.unlink(".UPGRADE_SUCCESS")
|
710
805
|
good, message = self.test_checkers()
|
@@ -716,51 +811,51 @@ class C2cUpgradeTool:
|
|
716
811
|
error=True,
|
717
812
|
message=message,
|
718
813
|
prompt="Correct the checker, then run the step again "
|
719
|
-
"(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):",
|
720
815
|
)
|
721
816
|
sys.exit(1)
|
722
817
|
|
723
|
-
@Step(
|
724
|
-
def
|
818
|
+
@Step(13, file_marker=False)
|
819
|
+
def step13(self, step: int) -> None:
|
725
820
|
# Required to remove from the Git stage the ignored file when we lunch the step again
|
726
821
|
check_call(["git", "reset", "--mixed"])
|
727
822
|
|
728
|
-
check_call(["git", "add", "
|
823
|
+
check_call(["git", "add", "--all"])
|
729
824
|
check_call(["git", "status"])
|
730
825
|
|
731
826
|
self.print_step(
|
732
827
|
step + 1,
|
733
828
|
message="We will commit all the above files!\n"
|
734
829
|
"If there are some files which should not be committed, then you should "
|
735
|
-
"add them into the `.gitignore` file and launch upgrade {} again."
|
830
|
+
f"add them into the `.gitignore` file and launch upgrade {step} again.",
|
736
831
|
prompt="Then to commit your changes type:",
|
737
832
|
)
|
738
833
|
|
739
|
-
@Step(
|
740
|
-
def
|
834
|
+
@Step(14, file_marker=False)
|
835
|
+
def step14(self, _: int) -> None:
|
741
836
|
if os.path.isfile(".UPGRADE_INSTRUCTIONS"):
|
742
837
|
os.unlink(".UPGRADE_INSTRUCTIONS")
|
743
838
|
check_call(
|
744
839
|
[
|
745
840
|
"git",
|
746
841
|
"commit",
|
747
|
-
"--message=Upgrade to GeoMapFish
|
748
|
-
|
749
|
-
),
|
842
|
+
"--message=Upgrade to GeoMapFish "
|
843
|
+
f"{pkg_resources.get_distribution('c2cgeoportal_commons').version}",
|
750
844
|
]
|
751
845
|
)
|
752
846
|
|
753
847
|
print("")
|
754
848
|
print(self.color_bar)
|
755
849
|
print("")
|
756
|
-
print(colorize("Congratulations, your upgrade was successful.", GREEN))
|
850
|
+
print(colorize("Congratulations, your upgrade was successful.", Color.GREEN))
|
757
851
|
print("")
|
758
852
|
branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
|
759
853
|
print("Now all your files are committed; you should do a git push:")
|
760
|
-
print("git push {
|
854
|
+
print(f"git push {self.options.git_remote} {branch}.")
|
761
855
|
|
762
856
|
|
763
|
-
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."""
|
764
859
|
return check_output(["git", "status", "--short"] + (args if args is not None else [])).decode("utf-8")
|
765
860
|
|
766
861
|
|