This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-atr-experiments.git

commit 34ca2f5d67fd950930b3940a59130173e58085a6
Author: Thomas Neidhart <[email protected]>
AuthorDate: Tue Mar 4 13:54:14 2025 +0100

    inject dynamic version / commit information in development mode and when 
building a docker image
---
 Dockerfile.alpine                  |  2 ++
 Dockerfile.ubuntu                  |  2 ++
 Makefile                           |  2 +-
 atr/server.py                      |  3 +++
 atr/templates/includes/footer.html | 15 +++++------
 atr/version.py                     | 50 ++++++++++++++++++++++++++++++++++
 poetry.lock                        | 55 ++++++++++++++++++++++++--------------
 pyproject.toml                     |  3 +++
 scripts/build                      | 11 +++++++-
 uv.lock                            | 18 +++++++++++--
 10 files changed, 129 insertions(+), 32 deletions(-)

diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index b808115..052b5fc 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -6,6 +6,8 @@ ARG SCRIPTS=scripts/poetry
 ENV SCRIPTS=${SCRIPTS}
 ARG VERSION=unknown
 ENV VERSION=${VERSION}
+ARG COMMIT=unknown
+ENV COMMIT=${COMMIT}
 
 # gcompat is required for ruff to work
 # # go is required for syft
diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu
index f122f07..c3ecd7b 100644
--- a/Dockerfile.ubuntu
+++ b/Dockerfile.ubuntu
@@ -7,6 +7,8 @@ ARG SCRIPTS=scripts/poetry
 ENV SCRIPTS=${SCRIPTS}
 ARG VERSION=unknown
 ENV VERSION=${VERSION}
+ARG COMMIT=unknown
+ENV COMMIT=${COMMIT}
 
 RUN apt-get update && apt-get install -y \
     curl \
diff --git a/Makefile b/Makefile
index 26c3579..35db32c 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ report:
        @echo SCRIPTS = $(SCRIPTS)
 
 run:
-        scripts/run
+       scripts/run
 
 serve:
        $(SCRIPTS)/run hypercorn --bind $(BIND) --keyfile key.pem --certfile 
cert.pem atr.server:app --debug --reload
diff --git a/atr/server.py b/atr/server.py
index 4370a54..db256b2 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -121,10 +121,13 @@ def app_setup_context(app: QuartApp) -> None:
     @app.context_processor
     async def app_wide() -> dict[str, Any]:
         from atr.util import is_admin
+        from atr.version import __commit__, __version__
 
         return {
             "current_user": await asfquart.session.read(),
             "is_admin": is_admin,
+            "commit": __commit__,
+            "version": __version__,
         }
 
 
diff --git a/atr/templates/includes/footer.html 
b/atr/templates/includes/footer.html
index e07eb08..d97eef7 100644
--- a/atr/templates/includes/footer.html
+++ b/atr/templates/includes/footer.html
@@ -1,11 +1,10 @@
 <footer class="footer">
   <p>
     Copyright © 2025, The Apache Software Foundation. Material licensed under 
the
-    <a href="https://www.apache.org/licenses/LICENSE-2.0";>Apache License, 
version
-      2.0</a>.
-    </p>
-    <p>
-      This is ATR version <code id="atr-version">ATR-VERSION</code>. For 
inquiries,
-      contact <a 
href="mailto:[email protected]";>[email protected]</a>
-    </p>
-  </footer>
+    <a href="https://www.apache.org/licenses/LICENSE-2.0";>Apache License, 
version 2.0</a>.
+  </p>
+  <p>
+    This is ATR version <code id="atr-version"><a 
href="https://github.com/apache/tooling-atr-experiments/commit/{{ commit }}">{{ 
version }}</a></code>.
+    For inquiries, contact <a 
href="mailto:[email protected]";>[email protected]</a>
+  </p>
+</footer>
diff --git a/atr/version.py b/atr/version.py
new file mode 100644
index 0000000..d554780
--- /dev/null
+++ b/atr/version.py
@@ -0,0 +1,50 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import os
+
+
+def _get_development_version() -> tuple[str, str] | None:
+    """Returns the version when within a development environment."""
+
+    try:
+        from dunamai import Version
+    except ImportError:
+        # dunamai is not installed, so probably we are not in
+        # a development environment.
+        return None
+
+    try:
+        version = Version.from_git()
+        if version.distance > 0:
+            return version.serialize(format="v{base}+{distance}.{commit}"), 
version.serialize(format="{commit}")
+        else:
+            return version.serialize(format="v{base}"), 
version.serialize(format="{commit}")
+
+    except RuntimeError:
+        return None
+
+
+def _get_version_from_env() -> tuple[str, str | None]:
+    """Returns the version from an environment variable."""
+
+    return os.environ.get("VERSION", "undefined"), os.environ.get("COMMIT")
+
+
+# Try to determine the version from a development environment first.
+# If this fails, try to get it from environment variables that are set when 
building a docker image.
+__version__, __commit__ = _get_development_version() or _get_version_from_env()
diff --git a/poetry.lock b/poetry.lock
index e586555..183654a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.0.1 and should not be 
changed by hand.
+# This file is automatically @generated by Poetry 2.1.1 and should not be 
changed by hand.
 
 [[package]]
 name = "aiofiles"
@@ -125,7 +125,7 @@ propcache = ">=0.2.0"
 yarl = ">=1.17.0,<2.0"
 
 [package.extras]
-speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"]
+speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns 
(>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", 
"brotlicffi ; platform_python_implementation != \"CPython\""]
 
 [[package]]
 name = "aiosignal"
@@ -179,7 +179,7 @@ SQLAlchemy = ">=1.3.0"
 typing-extensions = ">=4"
 
 [package.extras]
-tz = ["backports.zoneinfo", "tzdata"]
+tz = ["backports.zoneinfo ; python_version < \"3.9\"", "tzdata"]
 
 [[package]]
 name = "annotated-types"
@@ -211,7 +211,7 @@ sniffio = ">=1.1"
 
 [package.extras]
 doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints 
(>=1.2.0)", "sphinx_rtd_theme"]
-test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", 
"hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", 
"truststore (>=0.9.1)", "uvloop (>=0.21)"]
+test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", 
"hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", 
"truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; 
platform_python_implementation == \"CPython\" and platform_system != 
\"Windows\" and python_version < \"3.14\""]
 trio = ["trio (>=0.26.1)"]
 
 [[package]]
@@ -284,12 +284,12 @@ files = [
 ]
 
 [package.extras]
-benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", 
"pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", 
"pytest-xdist[psutil]"]
-cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy 
(>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", 
"pytest-xdist[psutil]"]
-dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", 
"pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", 
"hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" 
and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", 
"pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == 
\"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
+cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", 
"coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; 
platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", 
"pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; 
platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", 
"pytest-xdist[psutil]"]
+dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", 
"hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" 
and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest 
(>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == 
\"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
 docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", 
"sphinxcontrib-towncrier", "towncrier (<24.7)"]
-tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest 
(>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
+tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", 
"hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" 
and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", 
"pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and 
python_version >= \"3.10\"", "pytest-xdist[psutil]"]
+tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" 
and python_version >= \"3.10\"", "pytest-mypy-plugins ; 
platform_python_implementation == \"CPython\" and python_version >= \"3.10\""]
 
 [[package]]
 name = "blinker"
@@ -602,10 +602,10 @@ files = [
 cffi = {version = ">=1.12", markers = "platform_python_implementation != 
\"PyPy\""}
 
 [package.extras]
-docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"]
+docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= 
\"3.8\""]
 docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", 
"sphinxcontrib-spelling (>=7.3.1)"]
-nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"]
-pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
+nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""]
+pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", 
"mypy (>=1.4)", "ruff (>=0.3.6)"]
 sdist = ["build (>=1.0.0)"]
 ssh = ["bcrypt (>=3.1.5)"]
 test = ["certifi (>=2024)", "cryptography-vectors (==44.0.2)", "pretend 
(>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov 
(>=2.10.1)", "pytest-xdist (>=3.5.0)"]
@@ -683,6 +683,21 @@ pyyaml = ">=6"
 regex = ">=2023"
 tqdm = ">=4.62.2"
 
+[[package]]
+name = "dunamai"
+version = "1.23.0"
+description = "Dynamic version generation"
+optional = false
+python-versions = ">=3.5"
+groups = ["dev"]
+files = [
+    {file = "dunamai-1.23.0-py3-none-any.whl", hash = 
"sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"},
+    {file = "dunamai-1.23.0.tar.gz", hash = 
"sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"},
+]
+
+[package.dependencies]
+packaging = ">=20.9"
+
 [[package]]
 name = "easydict"
 version = "1.13"
@@ -733,7 +748,7 @@ files = [
 [package.extras]
 docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints 
(>=3)"]
 testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover 
(>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov 
(>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv 
(>=20.28.1)"]
-typing = ["typing-extensions (>=4.12.2)"]
+typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""]
 
 [[package]]
 name = "flask"
@@ -1039,7 +1054,7 @@ httpcore = "==1.*"
 idna = "*"
 
 [package.extras]
-brotli = ["brotli", "brotlicffi"]
+brotli = ["brotli ; platform_python_implementation == \"CPython\"", 
"brotlicffi ; platform_python_implementation != \"CPython\""]
 cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
 http2 = ["h2 (>=3,<5)"]
 socks = ["socksio (==1.*)"]
@@ -1067,7 +1082,7 @@ wsproto = ">=0.14.0"
 docs = ["pydata_sphinx_theme", "sphinxcontrib_mermaid"]
 h3 = ["aioquic (>=0.9.0,<1.0)"]
 trio = ["trio (>=0.22.0)"]
-uvloop = ["uvloop (>=0.18)"]
+uvloop = ["uvloop (>=0.18) ; platform_system != \"Windows\""]
 
 [[package]]
 name = "hyperframe"
@@ -1460,7 +1475,7 @@ version = "24.2"
 description = "Core utilities for Python packages"
 optional = false
 python-versions = ">=3.8"
-groups = ["test"]
+groups = ["dev", "test"]
 files = [
     {file = "packaging-24.2-py3-none-any.whl", hash = 
"sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
     {file = "packaging-24.2.tar.gz", hash = 
"sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
@@ -1682,7 +1697,7 @@ typing-extensions = ">=4.12.2"
 
 [package.extras]
 email = ["email-validator (>=2.0.0)"]
-timezone = ["tzdata"]
+timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == 
\"Windows\""]
 
 [[package]]
 name = "pydantic-core"
@@ -2353,7 +2368,7 @@ files = [
 ]
 
 [package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", 
"brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
 h2 = ["h2 (>=4,<5)"]
 socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
 zstd = ["zstandard (>=0.18.0)"]
@@ -2377,7 +2392,7 @@ platformdirs = ">=3.9.1,<5"
 
 [package.extras]
 docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", 
"sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier 
(>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", 
"coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", 
"pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", 
"pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", 
"setuptools (>=68)", "time-machine (>=2.10)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", 
"coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", 
"pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; 
platform_python_implementation == \"PyPy\" or platform_python_implementation == 
\"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", 
"pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", 
"setuptools (>=68)", "time-machine (>=2.10) ; platform_pyth [...]
 
 [[package]]
 name = "watchfiles"
@@ -2608,4 +2623,4 @@ propcache = ">=0.2.0"
 [metadata]
 lock-version = "2.1"
 python-versions = "~=3.13"
-content-hash = 
"94d8732ca90ceb922ee17bd18cc7edc3d2f511bc5106bcddc8822fc36c6be5ef"
+content-hash = 
"21ebba9a2dccfea54a36dc086b548fcfbbc0a33834efaeb7853bac36e1e79930"
diff --git a/pyproject.toml b/pyproject.toml
index 299cb7d..83825c1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,6 +32,7 @@ dev = [
   "pyright>=1.1.393",
   "ruff>=0.9.4",
   "types-aiofiles>=24.1.0.20241221,<25.0.0.0",
+  "dunamai>=1.23.0"
 ]
 test = [
   "pytest>=8.0",
@@ -64,6 +65,8 @@ pre-commit = ">=2.20.0"
 pyright = ">=1.1.393"
 ruff = ">=0.9.4"
 types-aiofiles = ">=24.1.0.20241221,<25.0.0.0"
+dunamai = ">=1.23.0"
+
 # UV specific configuration
 
 [tool.uv.sources]
diff --git a/scripts/build b/scripts/build
index 5661c2f..66b0329 100755
--- a/scripts/build
+++ b/scripts/build
@@ -1,3 +1,12 @@
 #!/bin/sh
 set -eu
-sudo docker build -t tooling-atr-experiments --build-arg BIND=0.0.0.0:443 
--build-arg VERSION="$(git log -1 --date=format:'%Y-%m-%d %H:%M' 
--pretty=format:'<a 
href=\"https://github.com/apache/tooling-atr-experiments/commit/%H\";>%cd 
%h</a>')" -f Dockerfile.alpine .
+
+COMMIT=$(dunamai from git --format "{commit}")
+DISTANCE=$(dunamai from git --format "{distance}")
+if [ "${DISTANCE}" = "0" ]; then
+    VERSION=$(dunamai from git --format "v{base}")
+else
+    VERSION=$(dunamai from git --format "v{base}+{distance}.{commit}")
+fi
+
+docker build -t tooling-atr-experiments --build-arg BIND=0.0.0.0:443 
--build-arg VERSION="${VERSION}" --build-arg COMMIT="${COMMIT}" -f 
Dockerfile.alpine .
diff --git a/uv.lock b/uv.lock
index eac2134..472fa55 100644
--- a/uv.lock
+++ b/uv.lock
@@ -259,7 +259,7 @@ name = "click"
 version = "8.1.8"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
-    { name = "colorama", marker = "sys_platform == 'win32'" },
+    { name = "colorama", marker = "platform_system == 'Windows'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz";,
 hash = 
"sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size 
= 226593 }
 wheels = [
@@ -357,6 +357,18 @@ wheels = [
     { url = 
"https://files.pythonhosted.org/packages/4b/67/f7aeea9be6fb3bd984487af8d0d80225a0b1e5f6f7126e3332d349fb13fe/djlint-1.36.4-py3-none-any.whl";,
 hash = 
"sha256:e9699b8ac3057a6ed04fb90835b89bee954ed1959c01541ce4f8f729c938afdd", size 
= 52290 },
 ]
 
+[[package]]
+name = "dunamai"
+version = "1.23.0"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "packaging" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/06/4e/a5c8c337a1d9ac0384298ade02d322741fb5998041a5ea74d1cd2a4a1d47/dunamai-1.23.0.tar.gz";,
 hash = 
"sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4", size 
= 44681 }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/21/4c/963169386309fec4f96fd61210ac0a0666887d0fb0a50205395674d20b71/dunamai-1.23.0-py3-none-any.whl";,
 hash = 
"sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041", size 
= 26342 },
+]
+
 [[package]]
 name = "easydict"
 version = "1.13"
@@ -1119,6 +1131,7 @@ dependencies = [
 [package.dev-dependencies]
 dev = [
     { name = "djlint" },
+    { name = "dunamai" },
     { name = "mypy" },
     { name = "pre-commit" },
     { name = "pyright" },
@@ -1150,6 +1163,7 @@ requires-dist = [
 [package.metadata.requires-dev]
 dev = [
     { name = "djlint", specifier = ">=1.36.4" },
+    { name = "dunamai", specifier = ">=1.23.0" },
     { name = "mypy", specifier = ">=1.15.0" },
     { name = "pre-commit", specifier = ">=2.20.0" },
     { name = "pyright", specifier = ">=1.1.393" },
@@ -1166,7 +1180,7 @@ name = "tqdm"
 version = "4.67.1"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
-    { name = "colorama", marker = "sys_platform == 'win32'" },
+    { name = "colorama", marker = "platform_system == 'Windows'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz";,
 hash = 
"sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size 
= 169737 }
 wheels = [


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to