11// Package builder implements the generic Python Builder gRPC service.
2- // Its job on the generic layer is minimal: Load/Init plumbing, a no-op
3- // Build (uv sync happens at Runtime.Init), a no-op Sync (no protos) .
2+ // Its job on the generic layer is minimal: Load/Init plumbing and Configure.
3+ // Shared successful no-op phases come from services.DefaultBuilder .
44// Specializations override Build (to produce container images) and Sync
55// (to generate protos / adapters / migrations).
66package builder
@@ -20,34 +20,25 @@ import (
2020// Builder is the generic Python builder server. Embedded by specializations
2121// so they inherit Load/Init and only add what their layer needs.
2222type Builder struct {
23- services.BuilderServer
23+ * services.DefaultBuilder
2424 * pythonservice.Service
2525}
2626
2727// New builds a generic Python Builder bound to the shared Service.
2828func New (svc * pythonservice.Service ) * Builder {
29- return & Builder {Service : svc }
29+ return & Builder {
30+ DefaultBuilder : services .NewDefaultBuilder (svc .Builder ),
31+ Service : svc ,
32+ }
3033}
3134
3235// Load reads the identity and settings. Specializations override to wire
3336// endpoints and compute layer-specific paths, but should call this first.
3437func (s * Builder ) Load (ctx context.Context , req * builderv0.LoadRequest ) (* builderv0.LoadResponse , error ) {
3538 defer s .Wool .Catch ()
36- ctx = s .Wool .Inject (ctx )
37-
38- if err := s .Builder .Load (ctx , req .Identity , s .Service .Settings ); err != nil {
39- return s .Builder .LoadError (err )
40- }
41-
39+ response , err := s .Builder .LoadService (ctx , req , services.BuilderLoad {Settings : s .Service .Settings })
4240 s .Service .SourceLocation = s .Location
43-
44- if req .CreationMode != nil {
45- s .Builder .CreationMode = req .CreationMode
46- return s .Builder .LoadResponse ()
47- }
48-
49- s .Endpoints , _ = s .Base .Service .LoadEndpoints (ctx )
50- return s .Builder .LoadResponse ()
41+ return response , err
5142}
5243
5344// Init records dependency endpoints.
@@ -59,46 +50,21 @@ func (s *Builder) Init(ctx context.Context, req *builderv0.InitRequest) (*builde
5950 return s .Builder .InitResponse ()
6051}
6152
62- // Update is a no-op on the generic layer.
63- func (s * Builder ) Update (ctx context.Context , _ * builderv0.UpdateRequest ) (* builderv0.UpdateResponse , error ) {
64- defer s .Wool .Catch ()
65- ctx = s .Wool .Inject (ctx )
66- return & builderv0.UpdateResponse {}, nil
67- }
68-
69- // Sync is a no-op on the generic layer — Python has no protos to generate.
70- // Specializations (python-fastapi, python-grpc) override to regenerate
71- // their protocol artifacts.
72- func (s * Builder ) Sync (ctx context.Context , _ * builderv0.SyncRequest ) (* builderv0.SyncResponse , error ) {
73- defer s .Wool .Catch ()
74- ctx = s .Wool .Inject (ctx )
75- return s .Builder .SyncResponse ()
76- }
77-
78- // Build is a no-op on the generic layer — uv sync at Runtime.Init handles
79- // Python dep resolution; there's no artifact to produce. Specializations
80- // override to build container images.
81- func (s * Builder ) Build (ctx context.Context , _ * builderv0.BuildRequest ) (* builderv0.BuildResponse , error ) {
82- defer s .Wool .Catch ()
83- ctx = s .Wool .Inject (ctx )
84- return s .Builder .BuildResponse ()
85- }
86-
87- // Deploy is a no-op on the generic layer. Specializations override to
88- // render k8s manifests or push images.
53+ // Deploy fails explicitly on the generic layer. Returning a success response
54+ // without producing a workload made the CLI report a deployment that did not
55+ // exist. Deployable specializations override this method.
8956func (s * Builder ) Deploy (ctx context.Context , _ * builderv0.DeploymentRequest ) (* builderv0.DeploymentResponse , error ) {
9057 defer s .Wool .Catch ()
9158 ctx = s .Wool .Inject (ctx )
92- return s .Builder .DeployResponse ( )
59+ return s .Builder .DeployError ( fmt . Errorf ( "generic Python services do not define a deployable workload; use a deployable specialization such as python-fastapi" ) )
9360}
9461
95- // Create is a no-op on the generic layer. A generic "python service" has
96- // no inherent template — it's an abstract starting point. Specializations
97- // ship their own templates/factory/ tree and override Create to apply it.
62+ // Create likewise fails explicitly because the generic layer has no project
63+ // template. Specializations provide their own factory tree.
9864func (s * Builder ) Create (ctx context.Context , _ * builderv0.CreateRequest ) (* builderv0.CreateResponse , error ) {
9965 defer s .Wool .Catch ()
10066 ctx = s .Wool .Inject (ctx )
101- return s .Builder .CreateResponse ( ctx , s . Service . Settings )
67+ return s .Builder .CreateError ( fmt . Errorf ( "generic Python services do not define a project template; use a concrete specialization" ) )
10268}
10369
10470// Configure applies structured config changes to the service's test formula and
0 commit comments