context

package
v0.1.0-preview.1.rc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2025 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Command = &cli.Command{
	Name:  "context",
	Usage: "Views or manages context-specific configuration (stored in config/contexts directory)",
	Subcommands: []*cli.Command{
		CreateContextCommand,
	},
	Flags: append([]cli.Flag{
		&cli.StringFlag{
			Name:  "context",
			Usage: "Select the context to work over",
		},
		&cli.BoolFlag{
			Name:  "list",
			Usage: "Display all current context settings",
		},
		&cli.BoolFlag{
			Name:  "edit",
			Usage: "Open selected context file in a text editor for manual editing",
		},
		&cli.StringSliceFlag{
			Name:  "set",
			Usage: "Set a value into the current context settings (--set project.name=value)",
		},
	}, common.GlobalFlags...),
	Action: func(cCtx *cli.Context) error {
		logger := common.LoggerFromContext(cCtx.Context)

		context := cCtx.String("context")

		contextDir := filepath.Join("config", "contexts")

		args := cCtx.Args().Slice()

		items := cCtx.StringSlice("set")

		if cCtx.String("context") == "" && (len(args) == 0 || len(items) > 0) {

			ctx, err := ListContexts(contextDir, cCtx.Bool("list"))
			if err != nil {
				return fmt.Errorf("failed to list contexts %w", err)
			}

			context = ctx[0]

			fmt.Println()
		} else if cCtx.String("context") == "" && len(cCtx.Args().Slice()) > 0 {

			last := len(args) - 1

			if !strings.Contains(args[last], "=") {
				context = args[last]
				args = args[:last]
			}
		}

		if context == "" {
			return fmt.Errorf("cannot proceed without a selected context")
		}

		contextPath := filepath.Join(contextDir, fmt.Sprintf("%s.yaml", context))

		if cCtx.Bool("edit") {
			logger.Info("Opening context file for editing...")
			return config.EditConfig(cCtx, contextPath, config.Context, context)
		}

		if len(items) > 0 {

			items = append(items, args...)

			rootDoc, err := common.LoadYAML(contextPath)
			if err != nil {
				return fmt.Errorf("read context YAML: %w", err)
			}
			root := rootDoc.Content[0]
			configNode := common.GetChildByKey(root, "context")
			if configNode == nil {
				configNode = &yaml.Node{Kind: yaml.MappingNode}
				root.Content = append(root.Content,
					&yaml.Node{Kind: yaml.ScalarNode, Value: "context"},
					configNode,
				)
			}
			for _, item := range items {

				idx := strings.LastIndex(item, "=")
				if idx < 0 {
					return fmt.Errorf("invalid --set syntax %q (want key=val)", item)
				}
				pathStr := item[:idx]
				val := item[idx+1:]

				path := strings.Split(pathStr, ".")

				configNode, err = common.WriteToPath(configNode, path, val)
				if err != nil {
					return fmt.Errorf("setting value %s failed: %w", item, err)
				}
				logger.Info("Set %s = %s", pathStr, val)
			}
			if err := common.WriteYAML(contextPath, rootDoc); err != nil {
				return fmt.Errorf("write context YAML: %w", err)
			}
			return nil
		}

		if !cCtx.Bool("list") {

			if _, err := os.Stat(contextPath); os.IsNotExist(err) {
				return fmt.Errorf("this context does not exist, create it with `devkit avs context create %s`", context)
			}
			cfgPath := filepath.Join("config", common.BaseConfig)

			items := []string{"project.context=" + context}
			doc, err := common.LoadYAML(cfgPath)
			if err != nil {
				return fmt.Errorf("read base config: %w", err)
			}
			root := doc.Content[0]
			cfgNode := common.GetChildByKey(root, "config")
			if cfgNode == nil {
				cfgNode = &yaml.Node{Kind: yaml.MappingNode}
				root.Content = append(
					root.Content,
					&yaml.Node{Kind: yaml.ScalarNode, Value: "config"},
					cfgNode,
				)
			}
			for _, it := range items {
				parts := strings.SplitN(it, "=", 2)
				cfgNode, err = common.WriteToPath(cfgNode, strings.Split(parts[0], "."), parts[1])
				if err != nil {
					return fmt.Errorf("failed to set %s: %w", it, err)
				}
			}

			if err := common.WriteYAML(cfgPath, doc); err != nil {
				return fmt.Errorf("write config: %w", err)
			}
			logger.Info("Global context successfully set to %s", context)
			return nil
		}

		contextPath = filepath.Join(contextDir, fmt.Sprintf("%s.yaml", context))
		err := common.ListYaml(contextPath, logger)
		if err != nil {
			return fmt.Errorf("this context does not exist, create it with `devkit avs context create %s`", context)
		}

		return nil
	},
}
View Source
var CreateContextCommand = &cli.Command{
	Name:  "create",
	Usage: "Create a new context",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:  "context",
			Usage: "Select the context to work over",
		},
		&cli.BoolFlag{
			Name:  "force",
			Usage: "Force context to be overwritten",
		},
	},
	Action: func(cCtx *cli.Context) error {
		logger := common.LoggerFromContext(cCtx.Context)

		ctxName := cCtx.String("context")
		if args := cCtx.Args().Slice(); len(args) > 0 {
			ctxName = args[0]
		}

		ctxPath := filepath.Join("config", "contexts", fmt.Sprintf("%s.yaml", ctxName))
		if err := os.MkdirAll(filepath.Dir(ctxPath), 0755); err != nil {
			return fmt.Errorf("failed to make contexts dir: %w", err)
		}

		if _, err := os.Stat(ctxPath); err != nil || cCtx.Bool("force") {
			logger.Info("Creating a new context for %s", ctxName)
			if err := CreateContext(ctxPath, ctxName); err != nil {
				return fmt.Errorf("failed to create new context: %w", err)
			}
		} else {
			return fmt.Errorf("context already exists, if you want to recreate try `devkit avs context create --force %s`", ctxName)
		}

		logger.Info("Context successfully created at %s", ctxPath)
		logger.Info("")
		logger.Info("  - To view your new context call: `devkit avs context --list %s`", ctxName)
		logger.Info("  - To edit your new context call: `devkit avs context --edit %s`", ctxName)
		logger.Info("")
		return nil
	},
}

CreateCommand defines the "create context" subcommand

View Source
var RunSelection = runSelection

RunSelection is a variable alias for runSelection, so it can be stubbed in tests.

Functions

func CreateContext

func CreateContext(contextPath, context string) error

func ListContexts

func ListContexts(contextDir string, isList bool) ([]string, error)

ListContexts reads YAML contexts and returns user's selection

func NewModel

func NewModel(label string, choices []string) model

NewModel creates a new bubbletea model with a label and options

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL