seatgen: a client may import its contracts module's domain SDK (-domain-sdk; ADR 0634 §2; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -15,6 +15,7 @@ func main() {
|
||||
check := flag.Bool("check", false, "compare instead of writing: name every path out of step")
|
||||
goModule := flag.String("go-module", "", "the generated Go tree's module path, such as git.novox.be/novox/mesh-contracts/<folder>/go (there is no root module)")
|
||||
tsPackage := flag.String("ts-package", "", "the generated TypeScript package's name, such as @novox/mesh-contracts-<folder>")
|
||||
domainSDK := flag.String("domain-sdk", "", "the Go module of the contracts module's domain SDK, which a client may import (ADR 0634 §2); empty when it has none")
|
||||
flag.Parse()
|
||||
dir := flag.Arg(0)
|
||||
m, err := seatgen.Load(dir, *goModule, *tsPackage)
|
||||
@@ -22,6 +23,7 @@ func main() {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
m.DomainSDK = *domainSDK
|
||||
files, err := seatgen.Generate(m)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
|
||||
@@ -33,7 +33,7 @@ var toolAddress = re.MustCompile(`^[a-z][a-z0-9-]*\.[a-z0-9]+_[a-z0-9_]+$`)
|
||||
|
||||
// CheckClients is ADR 0627 §3's catalog check of the clients, and ADR 0625 §5's rule for the files beside them: every
|
||||
// directory under ClientRoot is the client of one seat defined whole, a Go module of its own at ClientGoModule; it
|
||||
// imports only the standard library, its own seat's contract module and mesh-sdk's runtime (never another seat's
|
||||
// imports only the standard library, its own seat's contract module, mesh-sdk's runtime and its domain's SDK (never another seat's
|
||||
// contract or client); and no string in it names a module's subject (`mesh.mod.`), a module's tool, or another seat
|
||||
// (its name, its subjects, its `seat:` call). Each problem is named once, sorted.
|
||||
func CheckClients(dir string, m *Module) ([]string, error) {
|
||||
@@ -111,6 +111,8 @@ func checkClient(dir, at, seat string, m *Module) ([]string, error) {
|
||||
switch {
|
||||
case !strings.Contains(strings.SplitN(path, "/", 2)[0], "."):
|
||||
case path == own:
|
||||
case m.DomainSDK != "" && (path == m.DomainSDK || strings.HasPrefix(path, m.DomainSDK+"/")):
|
||||
// the domain's SDK (ADR 0634 §2)
|
||||
case path == RuntimeModule || strings.HasPrefix(path, RuntimeModule+"/"):
|
||||
case path == ClientGoModule(m.GoModule, seat) || strings.HasPrefix(path, ClientGoModule(m.GoModule, seat)+"/"):
|
||||
// the client's own packages: a client may be several packages of its module
|
||||
|
||||
@@ -14,6 +14,7 @@ func TestAClientUsesOnlyItsSeatAndTheRuntime(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m.DomainSDK = "example.org/domain/sdk"
|
||||
files, err := Generate(m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -68,6 +69,16 @@ import "example.org/contracts/go/clients/aregistryclient/provider"
|
||||
var _ = provider.X
|
||||
`,
|
||||
}, artifacts(clientArtifact), nil},
|
||||
{"a client importing its domain's SDK, which another module's is not", map[string]string{
|
||||
"go/clients/aregistryclient/go.mod": "module example.org/contracts/go/clients/aregistryclient\n",
|
||||
"go/clients/aregistryclient/client.go": `package aregistryclient
|
||||
|
||||
import (
|
||||
"example.org/domain/sdk/reference"
|
||||
"example.org/other/sdk/reference"
|
||||
)
|
||||
`,
|
||||
}, artifacts(clientArtifact), []string{`client.go: imports example.org/other/sdk/reference: a client uses only`}},
|
||||
{"a client of no seat defined whole, and one not a module of its own", map[string]string{
|
||||
"go/clients/onestoreclient/x.go": "package onestoreclient\n",
|
||||
"go/clients/aregistryclient/go.mod": "module example.org/contracts/go\n",
|
||||
|
||||
@@ -21,6 +21,9 @@ type Module struct {
|
||||
GoModule string
|
||||
// TSPackage is the npm package's name.
|
||||
TSPackage string
|
||||
// DomainSDK is the Go module path of the contracts module's domain SDK (ADR 0634 §2), which a seat's client may
|
||||
// import beside its contract and mesh-sdk's runtime; empty when the domain has none.
|
||||
DomainSDK string
|
||||
// Order is every seat's name, sorted: a contracts module has no seat list and no reading order (ADR 0635 §1).
|
||||
Order []string
|
||||
// Seats are every definition, resolved, by name.
|
||||
|
||||
Reference in New Issue
Block a user