Learn how to integrate the reusable profile management commands provided by the `clay/pkg/cmds/profiles` package into your Cobra-based command-line applications
This document explains how to integrate the reusable profile management commands provided by the clay/pkg/cmds/profiles package into your Cobra-based command-line applications.
Many applications benefit from using configuration profiles to manage different settings for various environments or use cases (e.g., development vs. production databases, different API keys, specific model parameters). The clay library provides a standardized set of commands (profiles list, get, set, delete, init, edit, duplicate) built on top of clay/pkg/yaml-editor to manage these profiles stored in a YAML file.
By using this package, you get consistent profile management across different tools with minimal boilerplate code.
The profiles are stored in a standard location within the user's configuration directory:
~/.config/<appName>/profiles.yaml
Where <appName> is the name you provide when initializing the commands.
The profiles.yaml file is expected to have a simple, hierarchical structure:
<profileName1>:
<layerName1>:
<settingKey1>: <settingValue1>
<settingKey2>: <settingValue2>
<layerName2>:
<settingKey3>: <settingValue3>
<profileName2>:
<layerName1>: # Layers can be reused across profiles
<settingKey1>: <overrideValue1>
# settingKey2 uses default if not overridden
<layerName3>:
<settingKey4>: <settingValue4>
production-db, anyscale-mixtral).sql-connection, openai-chat). Layers group related settings. Your application code will typically look for settings within specific layer names.Integrating the profile commands into your application involves two main steps:
profiles.yaml file when the profiles init command is run. This content should ideally include comments explaining the profile structure and some examples relevant to your application.main.go or a cmd/root.go), call the profiles.NewProfilesCommand factory function and add the resulting command group to your root command.Create a function that returns a string. This string will be written to profiles.yaml when a user runs your-app profiles init for the first time.
Example (pinocchio/cmd/pinocchio/main.go):
// pinocchioInitialProfilesContent provides the default YAML content for a new pinocchio profiles file.
func pinocchioInitialProfilesContent() string {
return `# Pinocchio Profiles Configuration
#
# This file contains profile configurations for Pinocchio.
# Each profile can override layer parameters for different components (like AI models).
# ... (rest of the example content) ...
#
# You can manage this file using the 'pinocchio profiles' commands:
# - list: List all profiles
# - get <profile> [layer] [key]: Get profile settings
# - set <profile> <layer> <key> <value>: Set a profile setting
# - delete <profile> [layer] [key]: Delete a profile, layer, or setting
# - edit: Open this file in your editor
# - init: Create this file if it doesn't exist
# - duplicate <source> <new>: Copy an existing profile
`
}
Import the clay/pkg/cmds/profiles package (e.g., clay_profiles "github.com/go-go-golems/clay/pkg/cmds/profiles").
Call clay_profiles.NewProfilesCommand, passing your application's name and the initial content provider function you just defined.
Add the returned command to your Cobra root command.
Example (pinocchio/cmd/pinocchio/main.go within initAllCommands or similar):
import (
// ... other imports
clay_profiles "github.com/go-go-golems/clay/pkg/cmds/profiles"
)
func initAllCommands(helpSystem *help.HelpSystem) error {
// ... other command initializations ...
// Add profiles command from clay
// "pinocchio" is the appName, used for ~/.config/pinocchio/profiles.yaml
profilesCmd, err := clay_profiles.NewProfilesCommand("pinocchio", pinocchioInitialProfilesContent)
if err != nil {
return fmt.Errorf("error initializing profiles command: %w", err)
}
rootCmd.AddCommand(profilesCmd)
// ... add other commands ...
return nil
}
Once integrated, your application will have the following subcommands under profiles:
your-app profiles list [-c | --concise]: Lists all defined profile names. With -c, only names are shown; otherwise, full content is displayed.your-app profiles get <profile> [layer] [key]: Retrieves and displays settings. Shows all layers for a profile, all settings for a layer, or a specific setting's value.your-app profiles set <profile> <layer> <key> <value>: Sets a specific setting's value. Creates the profile and/or layer if they don't exist.your-app profiles delete <profile> [layer] [key]: Deletes an entire profile, a specific layer within a profile, or a single setting within a layer.your-app profiles init: Creates the profiles.yaml file in ~/.config/<appName>/ with the default content, but only if it doesn't already exist.your-app profiles edit: Opens the profiles.yaml file in the default system editor ($EDITOR, fallback to vim). Creates the directory and an empty file if they don't exist.your-app profiles duplicate <source-profile> <new-profile>: Creates a new profile by copying all layers and settings from an existing source profile.While this package provides the commands to manage the profiles file, your application logic needs to read and apply these profiles. This typically involves:
--profile <name> flag (often using glazed/pkg/cmds/schema or similar section mechanisms).profiles.yaml file corresponding to your application name.The pinocchio, sqleton, and escuse-me applications provide examples of how profiles are loaded and applied to override default layer parameters.