github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 "github.com/pkg/errors" 8 "go.starlark.net/starlark" 9 10 "github.com/tilt-dev/tilt/internal/tiltfile/io" 11 "github.com/tilt-dev/tilt/internal/tiltfile/starkit" 12 "github.com/tilt-dev/tilt/pkg/model" 13 ) 14 15 const UserConfigFileName = "tilt_config.json" 16 17 type Settings struct { 18 disableAll bool 19 enabledResources []model.ManifestName 20 configDef ConfigDef 21 22 configParseCalled bool 23 24 // if parse has been called, the directory containing the Tiltfile that called it 25 seenWorkingDirectory string 26 } 27 28 type Plugin struct { 29 tiltSubcommand model.TiltSubcommand 30 } 31 32 func NewPlugin(tiltSubcommand model.TiltSubcommand) *Plugin { 33 return &Plugin{tiltSubcommand: tiltSubcommand} 34 } 35 36 func (e *Plugin) NewState() interface{} { 37 return Settings{ 38 configDef: ConfigDef{configSettings: make(map[string]configSetting)}, 39 } 40 } 41 42 var _ starkit.StatefulPlugin = &Plugin{} 43 44 func MustState(model starkit.Model) Settings { 45 state, err := GetState(model) 46 if err != nil { 47 panic(err) 48 } 49 return state 50 } 51 52 func GetState(m starkit.Model) (Settings, error) { 53 var state Settings 54 err := m.Load(&state) 55 return state, err 56 } 57 58 func (e *Plugin) OnStart(env *starkit.Environment) error { 59 for _, b := range []struct { 60 name string 61 f starkit.Function 62 }{ 63 {"config.set_enabled_resources", setEnabledResources}, 64 {"config.clear_enabled_resources", clearEnabledResources}, 65 {"config.parse", e.parse}, 66 {"config.define_string_list", configSettingDefinitionBuiltin(func() configValue { 67 return &stringList{} 68 })}, 69 {"config.define_string", configSettingDefinitionBuiltin(func() configValue { 70 return &stringSetting{} 71 })}, 72 {"config.define_bool", configSettingDefinitionBuiltin(func() configValue { 73 return &boolSetting{} 74 })}, 75 {"config.define_object", configSettingDefinitionBuiltin(func() configValue { 76 return &objectSetting{} 77 })}, 78 } { 79 err := env.AddBuiltin(b.name, b.f) 80 if err != nil { 81 return errors.Wrap(err, b.name) 82 } 83 } 84 85 err := env.AddValue("config.tilt_subcommand", starlark.String(e.tiltSubcommand)) 86 if err != nil { 87 return err 88 } 89 90 startPath := env.StartTiltfile().Spec.Path 91 err = env.AddValue("config.main_path", starlark.String(startPath)) 92 if err != nil { 93 return err 94 } 95 96 err = env.AddValue("config.main_dir", starlark.String(filepath.Dir(startPath))) 97 if err != nil { 98 return err 99 } 100 101 return err 102 } 103 104 func (e *Plugin) parse(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 105 err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs) 106 if err != nil { 107 return starlark.None, err 108 } 109 110 wd := starkit.AbsWorkingDir(thread) 111 112 err = starkit.SetState(thread, func(settings Settings) (Settings, error) { 113 if settings.seenWorkingDirectory != "" && settings.seenWorkingDirectory != wd { 114 return settings, fmt.Errorf( 115 "%s can only be called from one Tiltfile working directory per run. It was called from %s and %s", 116 fn.Name(), 117 settings.seenWorkingDirectory, 118 wd) 119 } 120 settings.seenWorkingDirectory = wd 121 settings.configParseCalled = true 122 return settings, nil 123 }) 124 if err != nil { 125 return starlark.None, err 126 } 127 128 tf, err := starkit.StartTiltfileFromThread(thread) 129 if err != nil { 130 return starlark.None, err 131 } 132 m, err := starkit.ModelFromThread(thread) 133 if err != nil { 134 return starlark.None, err 135 } 136 settings, err := GetState(m) 137 if err != nil { 138 return starlark.None, err 139 } 140 141 userConfigPath := filepath.Join(wd, UserConfigFileName) 142 143 err = io.RecordReadPath(thread, io.WatchFileOnly, userConfigPath) 144 if err != nil { 145 return starlark.None, err 146 } 147 148 ret, out, err := settings.configDef.parse(userConfigPath, tf.Spec.Args) 149 if out != "" { 150 thread.Print(thread, out) 151 } 152 if err != nil { 153 return starlark.None, err 154 } 155 156 return ret, nil 157 }