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  }