c2cgeoportal-geoportal 2.7.1.156__py2.py3-none-any.whl → 2.8.1.180__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. c2cgeoportal_geoportal/__init__.py +24 -14
  2. c2cgeoportal_geoportal/lib/authentication.py +10 -14
  3. c2cgeoportal_geoportal/lib/caching.py +8 -6
  4. c2cgeoportal_geoportal/lib/checker.py +10 -6
  5. c2cgeoportal_geoportal/lib/common_headers.py +5 -8
  6. c2cgeoportal_geoportal/lib/dbreflection.py +8 -8
  7. c2cgeoportal_geoportal/lib/filter_capabilities.py +5 -1
  8. c2cgeoportal_geoportal/lib/lingua_extractor.py +11 -12
  9. c2cgeoportal_geoportal/lib/loader.py +1 -1
  10. c2cgeoportal_geoportal/lib/oauth2.py +217 -100
  11. c2cgeoportal_geoportal/lib/wmstparsing.py +8 -12
  12. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/Dockerfile +9 -11
  13. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/development.ini +1 -1
  14. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +0 -2
  15. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +1 -1
  16. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +6 -4
  17. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js +1 -3
  18. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.commons.js +1 -0
  19. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +1 -6
  20. c2cgeoportal_geoportal/scaffolds/advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile +0 -20
  21. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +20 -6
  22. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +4 -3
  23. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +22 -22
  24. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +58 -2
  25. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +48 -24
  26. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +2 -5
  27. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
  28. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -1
  29. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +26 -0
  30. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +53 -26
  31. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +23 -0
  32. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +0 -1
  33. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.yaml +3 -3
  34. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +21 -2
  35. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +9 -0
  36. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +38 -14
  37. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/data/Readme.txt +2 -2
  38. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +15 -0
  39. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.map.tmpl +2 -3
  40. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Landscape.jrxml +5 -0
  41. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Portrait.jrxml +5 -0
  42. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Landscape.jrxml +5 -0
  43. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Portrait.jrxml +5 -0
  44. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/config.yaml.tmpl +6 -0
  45. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml +4 -0
  46. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/run_alembic.sh +3 -5
  47. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +1 -1
  48. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +1 -1
  49. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +2 -0
  50. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
  51. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +38 -0
  52. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +2 -132
  53. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +210 -1097
  54. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
  55. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_config-schema.yaml +17 -15
  56. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +46 -2
  57. c2cgeoportal_geoportal/scripts/c2cupgrade.py +1 -2
  58. c2cgeoportal_geoportal/scripts/pcreate.py +8 -10
  59. c2cgeoportal_geoportal/scripts/theme2fts.py +58 -3
  60. c2cgeoportal_geoportal/views/__init__.py +1 -3
  61. c2cgeoportal_geoportal/views/dynamic.py +1 -1
  62. c2cgeoportal_geoportal/views/entry.py +2 -10
  63. c2cgeoportal_geoportal/views/fulltextsearch.py +1 -1
  64. c2cgeoportal_geoportal/views/geometry_processing.py +3 -3
  65. c2cgeoportal_geoportal/views/layers.py +10 -11
  66. c2cgeoportal_geoportal/views/login.py +63 -8
  67. c2cgeoportal_geoportal/views/mapserverproxy.py +2 -3
  68. c2cgeoportal_geoportal/views/ogcproxy.py +6 -2
  69. c2cgeoportal_geoportal/views/pdfreport.py +4 -4
  70. c2cgeoportal_geoportal/views/printproxy.py +2 -2
  71. c2cgeoportal_geoportal/views/profile.py +1 -1
  72. c2cgeoportal_geoportal/views/proxy.py +2 -4
  73. c2cgeoportal_geoportal/views/raster.py +2 -2
  74. c2cgeoportal_geoportal/views/resourceproxy.py +1 -1
  75. c2cgeoportal_geoportal/views/shortener.py +1 -2
  76. c2cgeoportal_geoportal/views/theme.py +97 -63
  77. c2cgeoportal_geoportal/views/tinyowsproxy.py +3 -12
  78. c2cgeoportal_geoportal/views/vector_tiles.py +1 -1
  79. {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/METADATA +21 -15
  80. {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/RECORD +96 -90
  81. {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/entry_points.txt +1 -0
  82. tests/__init__.py +3 -2
  83. tests/test_cachebuster.py +3 -3
  84. tests/test_caching.py +7 -7
  85. tests/test_checker.py +1 -1
  86. tests/test_decimaljson.py +1 -1
  87. tests/test_headerstween.py +1 -1
  88. tests/test_i18n.py +1 -1
  89. tests/test_init.py +14 -15
  90. tests/test_locale_negociator.py +4 -4
  91. tests/test_mapserverproxy_route_predicate.py +1 -2
  92. tests/test_raster.py +15 -15
  93. tests/test_wmstparsing.py +10 -10
  94. tests/xmlstr.py +1 -3
  95. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tools/extract-messages.js +0 -41
  96. {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/WHEEL +0 -0
  97. {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2024, Camptocamp SA
1
+ # Copyright (c) 2013-2023, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -131,7 +131,7 @@ class TimeExtentValue:
131
131
  max_def_value: Optional[datetime.datetime],
132
132
  ):
133
133
  """
134
- Initialise.
134
+ Initialize.
135
135
 
136
136
  Arguments:
137
137
 
@@ -212,20 +212,16 @@ class TimeExtentInterval:
212
212
  self.min_def_value = (
213
213
  self.min_def_value
214
214
  if extent.min_def_value is None
215
- else (
216
- extent.min_def_value
217
- if self.min_def_value is None
218
- else min_none(self.min_def_value, extent.min_def_value)
219
- )
215
+ else extent.min_def_value
216
+ if self.min_def_value is None
217
+ else min_none(self.min_def_value, extent.min_def_value)
220
218
  )
221
219
  self.max_def_value = (
222
220
  self.max_def_value
223
221
  if extent.max_def_value is None
224
- else (
225
- extent.max_def_value
226
- if self.max_def_value is None
227
- else max_none(self.max_def_value, extent.max_def_value)
228
- )
222
+ else extent.max_def_value
223
+ if self.max_def_value is None
224
+ else max_none(self.max_def_value, extent.max_def_value)
229
225
  )
230
226
 
231
227
  def to_dict(self) -> Dict[str, Any]:
@@ -5,9 +5,8 @@ FROM camptocamp/geomapfish-tools:{{cookiecutter.geomapfish_version_tag_env}} as
5
5
  LABEL maintainer Camptocamp "info@camptocamp.com"
6
6
 
7
7
  COPY requirements.txt /tmp/requirements.txt
8
- RUN \
9
- python3 -m pip install --disable-pip-version-check --no-cache-dir --requirement=/tmp/requirements.txt && \
10
- rm --recursive --force /tmp/* /var/tmp/* /root/.cache/*
8
+ RUN --mount=type=cache,target=/root/.cache \
9
+ python3 -m pip install --disable-pip-version-check --requirement=/tmp/requirements.txt
11
10
 
12
11
  WORKDIR /app
13
12
  COPY webpack.*.js Makefile CONST_Makefile /app/
@@ -16,7 +15,6 @@ RUN make apps
16
15
 
17
16
  COPY . /app
18
17
 
19
- RUN make checks
20
18
  RUN make build
21
19
  RUN mv webpack.apps.js webpack.apps.js.tmpl
22
20
 
@@ -28,9 +26,8 @@ CMD [ "webpack-dev-server", "--mode=development", "--debug", "--watch", "--no-in
28
26
  FROM camptocamp/geomapfish:{{cookiecutter.geomapfish_major_version_tag_env}} as runner
29
27
 
30
28
  COPY requirements.txt /tmp/requirements.txt
31
- RUN \
32
- python3 -m pip install --disable-pip-version-check --no-cache-dir --requirement=/tmp/requirements.txt && \
33
- rm --recursive --force /tmp/* /var/tmp/* /root/.cache/*
29
+ RUN --mount=type=cache,target=/root/.cache \
30
+ python3 -m pip install --disable-pip-version-check --requirement=/tmp/requirements.txt
34
31
 
35
32
  WORKDIR /app
36
33
  COPY . /app
@@ -41,10 +38,11 @@ COPY --from=builder /etc/static-ngeo/* /etc/static-ngeo/
41
38
  COPY --from=builder /app/alembic.ini /app/alembic.yaml ./
42
39
  RUN chmod go+w /etc/static-ngeo/
43
40
 
44
- RUN python3 -m pip install --disable-pip-version-check --no-cache-dir --editable=/app/ && \
45
- python3 -m compileall -q /usr/local/lib/python3.* \
46
- -x '/(debugpy|pipenv|.*pydev.*|networkx)/' && \
47
- python3 -m compileall -q /app/{{cookiecutter.package}}_geoportal -x /app/{{cookiecutter.package}}_geoportal/static.*
41
+ RUN --mount=type=cache,target=/root/.cache \
42
+ python3 -m pip install --disable-pip-version-check --editable=/app/ \
43
+ && python3 -m compileall -q /usr/local/lib/python3.* \
44
+ -x '/(ptvsd|.*pydev.*|networkx)/' \
45
+ && python3 -m compileall -q /app/{{cookiecutter.package}}_geoportal -x /app/{{cookiecutter.package}}_geoportal/static.*
48
46
 
49
47
  ARG GIT_HASH
50
48
  RUN c2cwsgiutils-genversion ${GIT_HASH}
@@ -48,7 +48,7 @@ use = egg:PasteDeploy#prefix
48
48
  prefix = %(VISIBLE_ENTRY_POINT)s
49
49
 
50
50
  [pipeline:main]
51
- pipeline = egg:c2cwsgiutils#client_info egg:c2cwsgiutils#profiler egg:c2cwsgiutils#sentry app
51
+ pipeline = egg:c2cwsgiutils#client_info egg:c2cwsgiutils#sentry app
52
52
 
53
53
  ###
54
54
  # logging configuration
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  # Copyright (c) 2019-2024, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
@@ -1,2 +1,2 @@
1
- #debugpy # Remote debugging
1
+ #ptvsd # Remote debugging
2
2
  #wsgi-lineprof # Profiling
@@ -7,9 +7,7 @@ const babelPresets = [
7
7
  [
8
8
  require.resolve('@babel/preset-env'),
9
9
  {
10
- targets: {
11
- browsers: ['> 0.7% in CH', '> 0.7% in FR', 'Firefox ESR'],
12
- },
10
+ targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10',
13
11
  modules: false,
14
12
  loose: true,
15
13
  },
@@ -32,7 +30,11 @@ module.exports = (env, argv) => {
32
30
  presets: babelPresets,
33
31
  babelrc: false,
34
32
  comments: false,
35
- plugins: [require.resolve('babel-plugin-angularjs-annotate')],
33
+ plugins: [
34
+ require.resolve('babel-plugin-angularjs-annotate'),
35
+ require.resolve('@babel/plugin-proposal-nullish-coalescing-operator'),
36
+ require.resolve('@babel/plugin-proposal-optional-chaining'),
37
+ ],
36
38
  },
37
39
  },
38
40
  },
@@ -34,9 +34,7 @@ const babelPresets = [
34
34
  [
35
35
  require.resolve('@babel/preset-env'),
36
36
  {
37
- targets: {
38
- browsers: ['> 0.7% in CH', '> 0.7% in FR', 'Firefox ESR'],
39
- },
37
+ targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10',
40
38
  modules: false,
41
39
  loose: true,
42
40
  },
@@ -5,6 +5,7 @@ const config = commons({
5
5
  DllReferencePluginOptions: {
6
6
  context: '/usr/lib/',
7
7
  },
8
+ browsers: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10',
8
9
  });
9
10
 
10
11
  for (const plugin of config.plugins) {
@@ -1,11 +1,9 @@
1
- import distutils.core
2
-
3
1
  from pyramid.config import Configurator
4
2
 
5
3
  import {{cookiecutter.package}}_geoportal.authentication
6
4
  import {{cookiecutter.package}}_geoportal.dev
7
5
  import {{cookiecutter.package}}_geoportal.multi_organization
8
- from c2cgeoportal_geoportal import INTERFACE_TYPE_NGEO, add_interface_config, locale_negotiator
6
+ from c2cgeoportal_geoportal import add_interface_config, locale_negotiator
9
7
  from c2cgeoportal_geoportal.lib.i18n import LOCALE_PATH
10
8
  from {{cookiecutter.package}}_geoportal.resources import Root
11
9
 
@@ -28,10 +26,7 @@ def main(global_config, **settings):
28
26
 
29
27
  config.add_translation_dirs(LOCALE_PATH)
30
28
 
31
- # Workaround to not have the error: distutils.errors.DistutilsArgError: no commands supplied
32
- distutils.core._setup_stop_after = "config" # pylint: disable=protected-access
33
29
  config.include("c2cgeoportal_geoportal")
34
- distutils.core._setup_stop_after = None # pylint: disable=protected-access
35
30
 
36
31
  config.include({{cookiecutter.package}}_geoportal.multi_organization.includeme)
37
32
 
@@ -43,32 +43,12 @@ VALIDATE_PY_FOLDERS = admin/$(PACKAGE)_admin \
43
43
  $(PACKAGE)_geoportal/scripts $(PACKAGE)_geoportal/views
44
44
  VALIDATE_PY_TEST_FOLDERS = $(PACKAGE)_geoportal/tests
45
45
 
46
- PY_FILES = $(shell find $(PACKAGE) -type f -name '*.py' -print 2> /dev/null)
47
-
48
- # Templates
49
-
50
-
51
46
  # Disabling Make built-in rules to speed up execution time
52
47
  .SUFFIXES:
53
48
 
54
49
  .PHONY: build
55
50
  build: $(BUILD_RULES)
56
51
 
57
- .PHONY: checks
58
- checks: prospector eslint
59
-
60
- .PHONY: prospector
61
- prospector:
62
- prospector
63
-
64
- .PHONY: eslint
65
- eslint: $(APP_JS_FILES)
66
- eslint $?
67
-
68
- .PHONY: eslint-fix
69
- eslint-fix: $(APP_JS_FILES)
70
- eslint --fix $?
71
-
72
52
  # Server localisation
73
53
 
74
54
  PO_FILES = $(addprefix $(PACKAGE)_geoportal/locale/, $(addsuffix /LC_MESSAGES/$(PACKAGE)_geoportal-server.po, $(LANGUAGES)))
@@ -5,12 +5,9 @@ on:
5
5
  push:
6
6
 
7
7
  # To publish the images to be used on Kubernetes
8
- #env:
9
- # PROJECT: {{cookiecutter.package}}
10
- # HAS_SECRETS: ${{'{{'}} secrets.HAS_SECRETS }}
11
- # # Requires CI_GPG_PRIVATE_KEY and GOPASS_CI_GITHUB_TOKEN secrets.
12
- # # The release branches
13
- # HELM_RELEASE_NAMES: int-{{cookiecutter.geomapfish_main_version_dash}},prod-{{cookiecutter.geomapfish_main_version_dash}}
8
+ # env:
9
+ # PROJECT: {{cookiecutter.package}}
10
+ # HAS_SECRETS: ${{'{{'}} secrets.HAS_SECRETS }}
14
11
 
15
12
  jobs:
16
13
  main:
@@ -32,12 +29,29 @@ jobs:
32
29
  - run: echo "${HOME}/.local/bin" >> ${GITHUB_PATH}
33
30
  - run: python3 -m pip install --user --requirement=ci/requirements.txt
34
31
 
32
+ # Can be used to have some secrets (with mask)
33
+ # - run: make secrets
34
+ # - run: cat env.secrets |grep '^[# A-Z0-9_]\+='|sed -e 's/^[# A-Z0-9_]\+=\(.*\)/::add-mask::\1/g'
35
+
35
36
  - name: Checks
36
37
  run: c2cciutils-checks
37
38
 
39
+ # - name: Initialize the acceptance tests
40
+ # run: make acceptance-init
41
+ # - run: c2cciutils-docker-logs
42
+ # if: always()
43
+
44
+ # - name: Run the acceptance tests
45
+ # run: make acceptance
46
+ # - run: c2cciutils-docker-logs
47
+ # if: always()
48
+
38
49
  - name: Build
39
50
  run: ./build --docker-compose-version-2
40
51
 
52
+ - name: Application checks
53
+ run: make checks
54
+
41
55
  # To publish the images to be used on Kubernetes
42
56
  # - name: Publish
43
57
  # run: c2cciutils-publish
@@ -7,7 +7,7 @@ on:
7
7
 
8
8
  jobs:
9
9
  l10n:
10
- runs-on: ubuntu-18.04
10
+ runs-on: ubuntu-22.04
11
11
  name: Update l10n cron job
12
12
  timeout-minutes: 10
13
13
 
@@ -15,9 +15,9 @@ jobs:
15
15
  fail-fast: false
16
16
  matrix:
17
17
  include:
18
- - branch: int
18
+ - branch: int-{{cookiecutter.geomapfish_main_version_dash}}
19
19
  base_url: int.customer.ch
20
- - branch: prod
20
+ - branch: prod-{{cookiecutter.geomapfish_main_version_dash}}
21
21
  base_url: prod.customer.ch
22
22
 
23
23
  steps:
@@ -59,6 +59,7 @@ jobs:
59
59
  'Authorization': 'Bearer ${{'{{'}} secrets.GOPASS_CI_GITHUB_TOKEN {{'}}'}}',
60
60
  'Content-Type': 'application/json',
61
61
  },
62
+ timeout=120,
62
63
  )
63
64
  # 422 is the return code when the pull request already exists
64
65
  assert response.status_code < 300 or response.status_code == 422, f'{response.status_code} - {response.text}'"
@@ -14,7 +14,7 @@ ENV CONFIG_VARS sqlalchemy.url sqlalchemy.pool_recycle sqlalchemy.pool_size sqla
14
14
  dbsessions urllogin host_forward_host headers_whitelist headers_blacklist \
15
15
  smtp c2c.base_path welcome_email \
16
16
  lingua_extractor interfaces_config interfaces devserver_url api authentication intranet metrics pdfreport \
17
- vector_tiles i18next
17
+ vector_tiles i18next main_ogc_server
18
18
 
19
19
  COPY . /tmp/config/
20
20
 
@@ -27,14 +27,14 @@ ARG PGSCHEMA
27
27
  ENV PGSCHEMA=$PGSCHEMA
28
28
 
29
29
  RUN \
30
- cd /tmp/config/geoportal/ && \
31
- c2c-template --vars ${VARS_FILE} \
30
+ cd /tmp/config/geoportal/ \
31
+ && c2c-template --vars ${VARS_FILE} \
32
32
  --get-config {{cookiecutter.package}}_geoportal/config.yaml \
33
- ${CONFIG_VARS} && \
34
- pykwalify --data-file {{cookiecutter.package}}_geoportal/config.yaml \
35
- --schema-file CONST_config-schema.yaml && \
36
- rm CONST_* vars.yaml && \
37
- qgisserver-plugin-config {{cookiecutter.package}}_geoportal/config.yaml ../qgisserver/geomapfish.yaml.tmpl
33
+ ${CONFIG_VARS} \
34
+ && pykwalify --data-file {{cookiecutter.package}}_geoportal/config.yaml \
35
+ --schema-file CONST_config-schema.yaml \
36
+ && rm CONST_* vars.yaml \
37
+ && qgisserver-plugin-config {{cookiecutter.package}}_geoportal/config.yaml ../qgisserver/geomapfish.yaml.tmpl
38
38
 
39
39
  ###############################################################################
40
40
 
@@ -46,26 +46,26 @@ ENV PGSCHEMA=$PGSCHEMA
46
46
  COPY --from=builder /tmp/config/ /tmp/config/
47
47
 
48
48
  RUN \
49
- if [ -e /tmp/config/mapserver ]; then mv /tmp/config/mapserver /etc/; fi && \
50
- if [ -e /tmp/config/tilegeneration ]; then mv /tmp/config/tilegeneration /etc/; fi && \
51
- if [ -e /tmp/config/qgisserver ]; then mv /tmp/config/qgisserver /etc/qgisserver; fi && \
52
- if [ -e /tmp/config/haproxy ]; then mv /tmp/config/haproxy/* /etc/haproxy/; fi && \
53
- mkdir --parent /usr/local/tomcat/webapps/ROOT/ && \
54
- if [ -e /tmp/config/print ]; then mv /tmp/config/print/print-apps /usr/local/tomcat/webapps/ROOT/; fi && \
55
- mv /tmp/config/geoportal/{{cookiecutter.package}}_geoportal/ /etc/geomapfish/ && \
56
- mv /tmp/config/geoportal/* /etc/geomapfish/ || true && \
57
- chmod g+w -R \
49
+ mvif /tmp/config/mapserver /etc/ \
50
+ && mvif /tmp/config/tilegeneration /etc/ \
51
+ && mvif /tmp/config/qgisserver /etc/qgisserver \
52
+ && mvif /tmp/config/haproxy/* /etc/haproxy/ \
53
+ && mkdir --parent /usr/local/tomcat/webapps/ROOT/ \
54
+ && mvif /tmp/config/print /tmp/config/print/print-apps /usr/local/tomcat/webapps/ROOT/ \
55
+ && mv /tmp/config/geoportal/{{cookiecutter.package}}_geoportal/ /etc/geomapfish/ \
56
+ && mv /tmp/config/geoportal/* /etc/geomapfish/ || true \
57
+ && chmod g+w -R \
58
58
  /etc/geomapfish \
59
59
  /etc/mapserver \
60
60
  /etc/qgisserver \
61
61
  /etc/tilegeneration \
62
62
  /usr/local/tomcat/webapps/ROOT/print-apps \
63
63
  /etc/haproxy_dev \
64
- /etc/haproxy && \
65
- adduser www-data root && \
66
- sed 's#bind :80#bind *:443 ssl crt /etc/haproxy_dev/localhost.pem#g' /etc/haproxy/haproxy.cfg.tmpl \
67
- > /etc/haproxy_dev/haproxy.cfg.tmpl && \
68
- echo ' http-request set-header X-Forwarded-Proto https' >> /etc/haproxy_dev/haproxy.cfg.tmpl
64
+ /etc/haproxy \
65
+ && adduser www-data root \
66
+ && sed 's#bind :80#bind *:443 ssl crt /etc/haproxy_dev/localhost.pem#g' /etc/haproxy/haproxy.cfg.tmpl \
67
+ > /etc/haproxy_dev/haproxy.cfg.tmpl \
68
+ && echo ' http-request set-header X-Forwarded-Proto https' >> /etc/haproxy_dev/haproxy.cfg.tmpl
69
69
 
70
70
  VOLUME /etc/geomapfish \
71
71
  /etc/mapserver \
@@ -1,7 +1,16 @@
1
1
  PROJECT_PUBLIC_URL=https://example.camptocamp.com/
2
+ DUMP_FILE=dump.backup
2
3
  PACKAGE={{cookiecutter.package}}
3
4
  LANGUAGES=en fr de it
4
5
 
6
+ .PHONY: help
7
+ help: ## Display this help message
8
+ @echo "Usage: make <target>"
9
+ @echo
10
+ @echo "Available targets:"
11
+ @grep --extended-regexp --no-filename '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) | sort | \
12
+ awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s%s\n", $$1, $$2}'
13
+
5
14
  .PHONY: update-po-from-url
6
15
  update-po-from-url: ## Update the po files from the URL provide by PROJECT_PUBLIC_URL
7
16
  curl --fail --retry 5 --retry-delay 1 \
@@ -10,5 +19,52 @@ update-po-from-url: ## Update the po files from the URL provide by PROJECT_PUBLI
10
19
  docker-compose run --rm -T tools update-po-only `id --user` `id --group` $(LANGUAGES)
11
20
 
12
21
  .PHONY: update-po
13
- update-po:
14
- docker-compose exec -T tools sh -c "USER_ID=`id --user` GROUP_ID=`id --group` make -C geoportal update-po"
22
+ update-po: ## Update the po files from the running composition
23
+ docker-compose exec -T tools sh -c "USER_ID=`id --user` GROUP_ID=`id --group` make --directory=geoportal update-po"
24
+
25
+ .PHONY: checks
26
+ checks: prospector eslint ## Runs the checks
27
+
28
+ .PHONY: prospector
29
+ prospector: ## Runs the Prospector checks
30
+ docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \
31
+ prospector --output-format=pylint --die-on-tool-error
32
+
33
+ .PHONY: eslint
34
+ eslint: ## Runs the eslint checks
35
+ docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \
36
+ eslint $(find {{cookiecutter.package}} -type f -name '*.js' -print 2> /dev/null)
37
+ docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \
38
+ eslint $(find {{cookiecutter.package}} -type f -name '*.ts' -print 2> /dev/null)
39
+
40
+ .PHONY: qgis
41
+ qgis: ## Run QGIS desktop
42
+ docker-compose -f docker-compose.yaml -f docker-compose-qgis.yaml run --rm qgis
43
+
44
+ secrets.tar.bz2.gpg: env.secrets ## Encrypt the secrets for committing changes
45
+ tar -jcf secrets.tar.bz2 $^
46
+ rm -f $@
47
+ gpg --symmetric --cipher-algo AES256 --batch \
48
+ --passphrase=$(shell gopass show gs/ci/large-secret-passphrase) secrets.tar.bz2
49
+ rm secrets.tar.bz2
50
+
51
+ .PHONY: secrets
52
+ secrets: ## Decrypt the secrets.tar.bz2.gpg file
53
+ gpg --quiet --batch --yes --decrypt --passphrase=$(shell gopass show gs/ci/large-secret-passphrase) \
54
+ --output secrets.tar.bz2 secrets.tar.bz2.gpg
55
+ tar --touch -jxf secrets.tar.bz2
56
+ rm secrets.tar.bz2
57
+
58
+ .PHONY: acceptance-init
59
+ acceptance-init: ## Initialize the acceptance tests
60
+ docker-compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d db tools
61
+ docker-compose exec -T tools wait-db
62
+ docker-compose exec -T tools psql --command="DROP EXTENSION IF EXISTS postgis CASCADE"
63
+ scripts/db-restore --docker-compose-file=docker-compose.yaml --docker-compose-file=docker-compose-db.yaml \
64
+ --arg=--clean --arg=--if-exists --arg=--verbose $(DUMP_FILE) || true
65
+ docker-compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d
66
+
67
+ .PHONY: acceptance
68
+ acceptance: ## Run the acceptance tests
69
+ docker-compose exec -T tools pytest -vv tests/
70
+ ci/docker-compose-check
@@ -5,26 +5,42 @@ import os
5
5
  import os.path
6
6
  import platform
7
7
  import re
8
+ import shlex
8
9
  import shutil
9
10
  import stat
10
11
  import subprocess
11
12
  import sys
12
13
  import urllib.request
13
- from typing import Any, Dict, List, Optional
14
+ from typing import TYPE_CHECKING, Any, List, Optional
14
15
 
15
16
  import yaml
16
17
 
18
+ CompletedProcess = subprocess.CompletedProcess[str] if TYPE_CHECKING else subprocess.CompletedProcess
17
19
 
18
- def run(args: argparse.Namespace, command: List[str], **kwargs: Any) -> None:
20
+
21
+ def run(
22
+ args: argparse.Namespace, command: List[str], exit_on_error: bool = True, **kwargs: Any
23
+ ) -> Optional[CompletedProcess]:
19
24
  if args.verbose or args.dry_run:
20
- print(" ".join(command))
21
- if not args.dry_run:
22
- subprocess.run(command, **kwargs) # nosec
25
+ print(" ".join([shlex.quote(c) for c in command]))
26
+ if not args.dry_run or "stdout" in kwargs:
27
+ if args.stack_trace and exit_on_error and not "checks" in kwargs:
28
+ kwargs["check"] = True
29
+ process = subprocess.run(command, **kwargs) # nosec
30
+ if exit_on_error and process.returncode != 0:
31
+ print(
32
+ "An error occurred during execution of `{}`".format(
33
+ " ".join([shlex.quote(c) for c in command])
34
+ )
35
+ )
36
+ sys.exit(process.returncode)
37
+ return process
38
+ return None
23
39
 
24
40
 
25
41
  def main() -> None:
26
42
  parser = argparse.ArgumentParser(description="Build the project")
27
- parser.add_argument("--verbose", action="store_true", help="Display the docker build commands")
43
+ parser.add_argument("--verbose", action="store_true", help="Display the Docker build commands")
28
44
  parser.add_argument(
29
45
  "--dry-run", action="store_true", help="Display the docker build commands without executing them"
30
46
  )
@@ -34,9 +50,11 @@ def main() -> None:
34
50
  parser.add_argument("--not-simple", action="store_true", help="Force not simple application mode")
35
51
  parser.add_argument("--upgrade", help="Start upgrading the project to version")
36
52
  parser.add_argument(
37
- "--fast-reload",
38
- action="store_true",
39
- help="Restart the composition without Redis to don't lost the cache",
53
+ "--reload",
54
+ nargs="?",
55
+ action="store",
56
+ const="",
57
+ help="Comma separate list of services that will be reloaded after the build",
40
58
  )
41
59
  parser.add_argument(
42
60
  "--no-pull",
@@ -47,6 +65,7 @@ def main() -> None:
47
65
  parser.add_argument(
48
66
  "--debug", help="Path to c2cgeoportal source folder to be able to debug the upgrade procedure"
49
67
  )
68
+ parser.add_argument("--stack-trace", action="store_true", help="Display the stack trace on error")
50
69
  parser.add_argument(
51
70
  "--docker-compose-version-2", action="store_true", help="Use Docker Compose version 2"
52
71
  )
@@ -61,7 +80,7 @@ def main() -> None:
61
80
  match = re.match(r"^([0-9]+\.[0-9]+)\.[0-9a-z]+\.[0-9]+$", args.upgrade)
62
81
  if match is not None:
63
82
  major_version = match.group(1)
64
- full_version = args.upgrade if args.upgrade != "master" else "latest"
83
+ full_version = args.upgrade
65
84
  with open("upgrade", "w", encoding="utf-8") as f:
66
85
  with urllib.request.urlopen( # nosec
67
86
  "https://raw.githubusercontent.com/camptocamp/c2cgeoportal/{major_version}/scripts/upgrade".format(
@@ -80,9 +99,9 @@ def main() -> None:
80
99
  os.chmod("upgrade", os.stat("upgrade").st_mode | stat.S_IXUSR)
81
100
  try:
82
101
  if platform.system() == "Windows":
83
- run(args, ["python", "upgrade", full_version] + debug_args, check=True)
102
+ run(args, ["python", "upgrade", full_version] + debug_args)
84
103
  else:
85
- run(args, ["./upgrade", full_version] + debug_args, check=True)
104
+ run(args, ["./upgrade", full_version] + debug_args)
86
105
  except subprocess.CalledProcessError:
87
106
  sys.exit(1)
88
107
  sys.exit(0)
@@ -110,11 +129,7 @@ def main() -> None:
110
129
  if args.not_simple:
111
130
  simple = False
112
131
 
113
- git_hash = (
114
- subprocess.run(["git", "rev-parse", "HEAD"], check=True, stdout=subprocess.PIPE)
115
- .stdout.strip()
116
- .decode()
117
- )
132
+ git_hash = run(args, ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE).stdout.decode().strip()
118
133
 
119
134
  dest.write("SIMPLE={}\n".format(str(simple).upper()))
120
135
  dest.write("GIT_HASH={git_hash}\n".format(git_hash=git_hash))
@@ -128,7 +143,7 @@ def main() -> None:
128
143
  if not args.no_pull:
129
144
  # Pull all the images
130
145
  if not args.service:
131
- run(args, [*docker_compose, "pull", "--ignore-pull-failures"], check=True) # nosec
146
+ run(args, [*docker_compose, "pull", "--ignore-pull-failures"]) # nosec
132
147
  docker_compose_build_cmd.append("--pull")
133
148
 
134
149
  if args.service:
@@ -138,24 +153,33 @@ def main() -> None:
138
153
  print_args = [a.replace('"', '\\"') for a in print_args]
139
154
  print_args = [a.replace("'", "\\'") for a in print_args]
140
155
  try:
141
- run(args, docker_compose_build_cmd, check=True) # nosec
156
+ env = {"DOCKER_BUILDKIT": "1", "COMPOSE_DOCKER_CLI_BUILD": "1"}
157
+ env.update(os.environ)
158
+ run(args, docker_compose_build_cmd, env=env) # nosec
142
159
  except subprocess.CalledProcessError as e:
143
160
  print("Error with command: " + " ".join(print_args))
144
161
  sys.exit(e.returncode)
145
162
 
146
- if args.fast_reload:
163
+ if args.reload:
164
+ services = args.reload.split(",")
165
+ elif args.reload == "":
147
166
  services = [
148
167
  service
149
- for service in subprocess.run(
150
- [*docker_compose, "ps", "--services", "--all"], stdout=subprocess.PIPE, check=True
168
+ for service in run(
169
+ args,
170
+ [*docker_compose, "ps", "--services", "--all"],
171
+ stdout=subprocess.PIPE,
172
+ exit_on_error=True,
151
173
  )
152
174
  .stdout.decode()
153
175
  .splitlines()
154
176
  if not service.startswith("redis")
155
177
  ]
156
178
 
157
- run(args, [*docker_compose, "rm", "--stop", "--force"] + services, check=True)
158
- run(args, [*docker_compose, "up", "-d"], check=True)
179
+ if args.reload is not None:
180
+ run(args, [*docker_compose, "rm", "--force", "-v", "config"])
181
+ for service in services:
182
+ run(args, [*docker_compose, "up", "--detach", "--force-recreate", service])
159
183
 
160
184
 
161
185
  if __name__ == "__main__":
@@ -1,11 +1,7 @@
1
- # yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/master/c2cciutils/schema.json
1
+ # yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/1.4/c2cciutils/schema.json
2
2
 
3
3
  checks:
4
- black: False
5
- isort: False
6
- prettier: False
7
4
  codespell: False
8
- eof: False
9
5
  required_workflows: False
10
6
  dependabot_config: False
11
7
  prospector_config: False
@@ -21,5 +17,6 @@ version:
21
17
  publish:
22
18
  pypi: false
23
19
  docker:
20
+ dispatch: {}
24
21
  images:
25
22
  - name: camptocamp/{{cookiecutter.package}}-config
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import argparse
4
+ import subprocess
5
+ import sys
6
+
7
+
8
+ def _main() -> None:
9
+ argparser = argparse.ArgumentParser("Tests that's all the services are running")
10
+ argparser.parse_args()
11
+
12
+ services = [
13
+ s.strip()
14
+ for s in subprocess.run(["docker", "compose", "ps"], check=True, stdout=subprocess.PIPE)
15
+ .stdout.decode("utf-8")
16
+ .splitlines()
17
+ ]
18
+ errors_statuses = [s for s in services if " Exit " in s and not s.endswith(" Exit 0")]
19
+ if errors_statuses:
20
+ print("\n".join(errors_statuses))
21
+ sys.exit(1)
22
+
23
+
24
+ if __name__ == "__main__":
25
+ _main()
@@ -1 +1 @@
1
- c2cciutils==1.1.*
1
+ c2cciutils[checks,publish]==1.4.21