github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/starkit/model.go (about)

     1  package starkit
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"go.starlark.net/starlark"
     9  
    10  	"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
    11  )
    12  
    13  type Model struct {
    14  	state map[reflect.Type]interface{}
    15  
    16  	BuiltinCalls []BuiltinCall
    17  }
    18  
    19  func NewModel(plugins ...Plugin) (Model, error) {
    20  	m := Model{
    21  		state: make(map[reflect.Type]interface{}),
    22  	}
    23  	for _, ext := range plugins {
    24  		sExt, isStateful := ext.(StatefulPlugin)
    25  		if isStateful {
    26  			err := m.createInitState(sExt)
    27  			if err != nil {
    28  				return Model{}, err
    29  			}
    30  		}
    31  	}
    32  	return m, nil
    33  }
    34  
    35  func (m Model) createInitState(ext StatefulPlugin) error {
    36  	v := ext.NewState()
    37  	t := reflect.TypeOf(v)
    38  	_, exists := m.state[t]
    39  	if exists {
    40  		return fmt.Errorf("Initializing plugin %T: model type conflict: %T", ext, v)
    41  	}
    42  	m.state[t] = v
    43  	return nil
    44  }
    45  
    46  func (m Model) Load(ptr interface{}) error {
    47  	ptrVal := reflect.ValueOf(ptr)
    48  	if ptrVal.Kind() != reflect.Ptr {
    49  		return fmt.Errorf("Cannot load %T", ptr)
    50  	}
    51  	val := ptrVal.Elem()
    52  	typ := val.Type()
    53  	data, ok := m.state[typ]
    54  	if !ok {
    55  		return fmt.Errorf("Cannot load %T", ptr)
    56  	}
    57  
    58  	val.Set(reflect.ValueOf(data))
    59  	return nil
    60  }
    61  
    62  func ModelFromThread(t *starlark.Thread) (Model, error) {
    63  	model, ok := t.Local(modelKey).(Model)
    64  	if !ok {
    65  		return Model{}, fmt.Errorf("Internal error: Starlark not initialized correctly: starkit.Model not found")
    66  	}
    67  	return model, nil
    68  }
    69  
    70  func ContextFromThread(t *starlark.Thread) (context.Context, error) {
    71  	ctx, ok := t.Local(ctxKey).(context.Context)
    72  	if !ok {
    73  		return nil, fmt.Errorf("Internal error Starlark not initialized correctly: starkit.Ctx not found")
    74  	}
    75  
    76  	return ctx, nil
    77  }
    78  
    79  func StartTiltfileFromThread(t *starlark.Thread) (*v1alpha1.Tiltfile, error) {
    80  	tf, ok := t.Local(startTfKey).(*v1alpha1.Tiltfile)
    81  	if !ok {
    82  		return nil, fmt.Errorf("Internal error Starlark not initialized correctly: start tiltfile not found")
    83  	}
    84  
    85  	return tf, nil
    86  }