Learn how to use the MultiLoader to handle different types of command files with type-based dispatch
The MultiLoader provides a flexible way to load commands from different file types by dispatching to appropriate loaders based on a type field or file content. This guide explains how to use and configure the MultiLoader for your applications.
The MultiLoader works by first checking a file's type field (if present) and then dispatching to the appropriate registered loader. Here's how a typical command file with a type field looks:
type: sqleton
name: query-users
short: Query the users table
flags:
- name: limit
type: int
help: Maximum number of users to return
Create and configure a MultiLoader with specific type handlers:
// Create a new MultiLoader
loader := loaders.NewMultiLoader()
// Register loaders for different types
loader.RegisterLoader("sql", sqlLoader)
loader.RegisterLoader("http", httpLoader)
loader.RegisterLoader("shell", shellLoader)
// Set a default loader for files without a type field
loader.SetDefaultLoader(defaultLoader)
Use the configured MultiLoader like any other CommandLoader:
commands, err := loader.LoadCommands(fs, "commands/query.yaml", options, aliasOptions)
if err != nil {
// Handle error
}
The MultiLoader follows this process to select the appropriate loader:
type fieldRegister loaders for specific command types:
// SQL command loader
loader.RegisterLoader("sql", &SQLCommandLoader{})
// HTTP command loader
loader.RegisterLoader("http", &HTTPCommandLoader{})
Set a fallback loader for files without a type field:
loader.SetDefaultLoader(&YAMLCommandLoader{})
The MultiLoader can automatically detect the right loader even without a type field:
// Will try each registered loader's IsFileSupported method
commands, err := loader.LoadCommands(fs, "commands/unknown.txt", options, aliasOptions)
type: sqleton
name: list-users
short: List all users from database
flags:
- name: order-by
type: string
help: Column to sort by
default: id
type: http
name: get-weather
short: Get weather information
flags:
- name: city
type: string
help: City name
required: true
# No type field - will use default loader
name: simple-command
short: A simple command
flags:
- name: verbose
type: bool
help: Enable verbose output
func RegisterLoaders(ml *loaders.MultiLoader) {
ml.RegisterLoader("sql", NewSQLLoader())
ml.RegisterLoader("http", NewHTTPLoader())
ml.RegisterLoader("shell", NewShellLoader())
// Set default loader last
ml.SetDefaultLoader(NewYAMLLoader())
}
func LoadCommandsWithMultiLoader(fs fs.FS, path string) ([]cmds.Command, error) {
loader := loaders.NewMultiLoader()
// Register loaders based on configuration
if config.SQLEnabled {
loader.RegisterLoader("sql", NewSQLLoader())
}
if config.HTTPEnabled {
loader.RegisterLoader("http", NewHTTPLoader())
}
return loader.LoadCommands(fs, path, nil, nil)
}
The MultiLoader provides a flexible and extensible way to handle different types of command files in your application. By following these guidelines and patterns, you can create a robust command loading system that supports multiple file formats and command types while maintaining clean, maintainable code.