From 4b4c7e0e0dcd4591c39b37e0b38e8cced340f635 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 28 Sep 2026 15:44:18 +0200 Subject: [PATCH] A module's name may contain a dot, so the derived step adds none MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A resource's id is `.` and a module's name may itself contain a dot — novox.be is one — so the owner of a resource is everything before the *last* dot. The preparation step's id used a dot, which made its owner unreadable by that rule; it uses a hyphen, and the id says what it belongs to whichever way a reader splits it. --- internal/catalogue/declaration.go | 5 ++++- internal/catalogue/prepares_test.go | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/internal/catalogue/declaration.go b/internal/catalogue/declaration.go index afd1087..a592599 100644 --- a/internal/catalogue/declaration.go +++ b/internal/catalogue/declaration.go @@ -1685,7 +1685,10 @@ func prepared(from map[string]any) map[string]any { for k, v := range from { step[k] = v } - step["id"] = fmt.Sprint(from["id"]) + ".prepare" + // **A hyphen, not a dot.** A resource's id is `.`, and a module's name may + // itself contain a dot (`novox.be`), so the module is everything before the *last* dot — which + // only works if what the mesh derives adds no dot of its own. + step["id"] = fmt.Sprint(from["id"]) + "-prepare" step["name"] = fmt.Sprint(from["name"]) + "-prepare" step["run-once"] = true step["args"] = []any{PreparationArgument} diff --git a/internal/catalogue/prepares_test.go b/internal/catalogue/prepares_test.go index dd414c8..eaae43b 100644 --- a/internal/catalogue/prepares_test.go +++ b/internal/catalogue/prepares_test.go @@ -3,6 +3,7 @@ package catalogue import ( "encoding/json" "fmt" + "strings" "testing" ) @@ -57,13 +58,18 @@ func TestThePreparationRunsTheModulesOwnCodeAndComesRightBeforeIt(t *testing.T) ids := idsOf(out) at := -1 for i, id := range ids { - if id == "gitea.runtime.prepare" { + if id == "gitea.runtime-prepare" { at = i } } if at < 0 { t.Fatalf("nothing prepares this module's state: %v", ids) } + // A module's name may contain a dot, so a resource's module is everything before the last one — + // which the derived id must not add to, or a machine reads the wrong owner from it. + if strings.Count("gitea.runtime-prepare", ".") != 1 { + t.Fatal("the derived id adds a dot, so what owns it cannot be read from it") + } if ids[at+1] != "gitea.runtime" { t.Fatalf("the preparation is not immediately before the module's own code: %v", ids) } @@ -79,7 +85,7 @@ func TestThePreparationRunsTheModulesOwnCodeAndComesRightBeforeIt(t *testing.T) func TestThePreparationIsGivenWhatTheModuleIsGiven(t *testing.T) { out := declaredFor(t, aPreparingModule()) declared := byID(out) - step, workload := declared["gitea.runtime.prepare"], declared["gitea.runtime"] + step, workload := declared["gitea.runtime-prepare"], declared["gitea.runtime"] if step == nil || workload == nil { t.Fatalf("expected both, got %v", idsOf(out)) } @@ -108,7 +114,7 @@ func TestAModuleThatPreparesNothingGetsNoStep(t *testing.T) { m := aPreparingModule() m.Prepares = false for _, id := range idsOf(declaredFor(t, m)) { - if id == "gitea.runtime.prepare" { + if id == "gitea.runtime-prepare" { t.Fatal("a module that prepares nothing was given a preparation") } }