From de551c9bbd591e6c9c53712fdb21f41f7fc0e661 Mon Sep 17 00:00:00 2001
From: Lance Edgar <lance@wuttaproject.org>
Date: Tue, 3 Dec 2024 09:31:43 -0600
Subject: [PATCH 1/4] docs: cleanup quickstart a bit, add some links

---
 docs/narr/install/quickstart.rst | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/docs/narr/install/quickstart.rst b/docs/narr/install/quickstart.rst
index 0fea804..84a491d 100644
--- a/docs/narr/install/quickstart.rst
+++ b/docs/narr/install/quickstart.rst
@@ -22,35 +22,39 @@ Make a parent folder for all source code:
 
    mkdir -p ~/src
 
-Make a :term:`virtual environment` for your project:
+Make and activate a new :term:`virtual environment` for your project:
 
 .. code-block:: sh
 
    cd /path/to/envs
    python3 -m venv poser
+   source poser/bin/activate
 
 Make a new e.g. ``poser`` database in PostgreSQL (or MySQL).
 
-Install and run cookiecutter with wuttaweb template:
+Install and run `cookiecutter <https://cookiecutter.readthedocs.io/>`_
+with `wuttaweb template
+<https://forgejo.wuttaproject.org/wutta/cookiecutter-wuttaweb>`_:
 
 .. code-block:: sh
 
-   cd /path/to/envs/poser
-   bin/pip install cookiecutter
-   bin/cookiecutter -o ~/src git+https://forgejo.wuttaproject.org/wutta/cookiecutter-wuttaweb
+   pip install cookiecutter
+   cookiecutter -o ~/src git+https://forgejo.wuttaproject.org/wutta/cookiecutter-wuttaweb
 
 Assuming you now have project code at ``~/src/poser`` then install
-that and run the app installer:
+that and run the app installer.  Note the 2nd command name will depend
+on your project:
 
 .. code-block:: sh
 
-   bin/pip install -e ~/src/poser
-   bin/poser install
+   pip install -e ~/src/poser
+   poser install
 
 If all goes well, you can run the web app with:
 
 .. code-block:: sh
 
+   cd /path/to/envs/poser
    bin/pserve --reload file+ini:app/web.conf
 
 And browse it at http://localhost:9080

From c3aa97ed2713cf6ffcf607c0645073505401feaa Mon Sep 17 00:00:00 2001
From: Lance Edgar <lance@wuttaproject.org>
Date: Tue, 3 Dec 2024 21:33:32 -0600
Subject: [PATCH 2/4] build: update project metadata

---
 pyproject.toml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/pyproject.toml b/pyproject.toml
index 96ce552..b60fdcc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ name = "WuttJamaican"
 version = "0.16.0"
 description = "Base package for Wutta Framework"
 readme = "README.md"
-authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
+authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
 license = {text = "GNU GPL v3+"}
 classifiers = [
         "Development Status :: 4 - Beta",
@@ -49,6 +49,7 @@ wutta = "wuttjamaican.cli:wutta_typer"
 [project.urls]
 Homepage = "https://wuttaproject.org/"
 Repository = "https://forgejo.wuttaproject.org/wutta/wuttjamaican"
+Issues = "https://forgejo.wuttaproject.org/wutta/wuttjamaican/issues"
 Changelog = "https://forgejo.wuttaproject.org/wutta/wuttjamaican/src/branch/master/CHANGELOG.md"
 
 

From d95b101dbf0c4411e44eb8c036bf073421356ec8 Mon Sep 17 00:00:00 2001
From: Lance Edgar <lance@wuttaproject.org>
Date: Tue, 3 Dec 2024 21:53:30 -0600
Subject: [PATCH 3/4] fix: add `db.util.make_topo_sortkey()` function

---
 src/wuttjamaican/db/util.py | 24 ++++++++++++++++++++++++
 tests/db/test_util.py       | 15 +++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/src/wuttjamaican/db/util.py b/src/wuttjamaican/db/util.py
index 0df0e68..643e267 100644
--- a/src/wuttjamaican/db/util.py
+++ b/src/wuttjamaican/db/util.py
@@ -27,6 +27,7 @@ Database Utilities
 import uuid as _uuid
 
 import sqlalchemy as sa
+from sqlalchemy import orm
 from sqlalchemy.dialects.postgresql import UUID as PGUUID
 
 from wuttjamaican.util import make_uuid
@@ -127,3 +128,26 @@ def uuid_fk_column(target_column, *args, **kwargs):
     if not args:
         args = (sa.String(length=32), sa.ForeignKey(target_column))
     return sa.Column(*args, **kwargs)
+
+
+def make_topo_sortkey(model):
+    """
+    Returns a function suitable for use as a ``key`` kwarg to a
+    standard Python sorting call.  This key function will expect a
+    single class mapper and return a sequence number associated with
+    that model.  The sequence is determined by SQLAlchemy's
+    topological table sorting.
+
+    :param model: Usually the :term:`app model`, but can be any module
+       containing model classes.
+    """
+    metadata = model.Base.metadata
+    tables = dict([(table.name, i)
+                   for i, table in enumerate(metadata.sorted_tables, 1)])
+
+    def sortkey(name):
+        cls = getattr(model, name)
+        mapper = orm.class_mapper(cls)
+        return tuple(tables[t.name] for t in mapper.tables)
+
+    return sortkey
diff --git a/tests/db/test_util.py b/tests/db/test_util.py
index 2f0c9ed..8ffef76 100644
--- a/tests/db/test_util.py
+++ b/tests/db/test_util.py
@@ -11,6 +11,7 @@ try:
     from wuttjamaican.db import util as mod
     from wuttjamaican.db.model.base import Setting
     from wuttjamaican.util import make_true_uuid
+    from wuttjamaican.testing import DataTestCase
 except ImportError:
     pass
 else:
@@ -124,3 +125,17 @@ else:
             self.assertIsInstance(column, sa.Column)
             self.assertIsInstance(column.type, sa.String)
             self.assertEqual(column.type.length, 32)
+
+
+    class TestMakeTopoSortkey(DataTestCase):
+
+        def test_basic(self):
+            model = self.app.model
+            sortkey = mod.make_topo_sortkey(model)
+            original = ['User', 'Person', 'UserRole', 'Role']
+
+            # models are sorted so dependants come later
+            result = sorted(original, key=sortkey)
+            self.assertTrue(result.index('Role') < result.index('UserRole'))
+            self.assertTrue(result.index('User') < result.index('UserRole'))
+            self.assertTrue(result.index('Person') < result.index('User'))

From 3a1ea22e9b0daf526626a61657c3e26014d069b8 Mon Sep 17 00:00:00 2001
From: Lance Edgar <lance@wuttaproject.org>
Date: Thu, 5 Dec 2024 08:04:55 -0600
Subject: [PATCH 4/4] =?UTF-8?q?bump:=20version=200.16.0=20=E2=86=92=200.16?=
 =?UTF-8?q?.1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md   | 9 +++++++++
 pyproject.toml | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee32008..8c4f50d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,15 @@ All notable changes to WuttJamaican will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## v0.16.1 (2024-12-05)
+
+### Fix
+
+- add `db.util.make_topo_sortkey()` function
+- use true UUID type for Upgrades table primary key
+- let caller set data type for `uuid_column()` and `uuid_fk_column()`
+- avoid error when loading installer templates
+
 ## v0.16.0 (2024-11-30)
 
 ### Feat
diff --git a/pyproject.toml b/pyproject.toml
index b60fdcc..d9c0ce8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
 
 [project]
 name = "WuttJamaican"
-version = "0.16.0"
+version = "0.16.1"
 description = "Base package for Wutta Framework"
 readme = "README.md"
 authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]