
Security News
The Next Open Source Security Race: Triage at Machine Speed
Claude Opus 4.6 has uncovered more than 500 open source vulnerabilities, raising new considerations for disclosure, triage, and patching at scale.
proxy-git.cwkhome.fun/lispyclouds/climate
Advanced tools
Read the detailed blogpost!
Go is a fantastic language to build CLI tooling, specially the ones for interacting with an API server. <your tool>ctl anyone?
But if you're tired of building bespoke CLIs everytime or think that the swagger codegen isn't just good enough or don't quite subscribe to the idea of codegen in general (like me!), look no further.
What if you can influence the CLI behaviour from the server? This enables you to bootstrap your cobra CLI tooling from an OpenAPI spec. Checkout Wendy as an example of a full CLI project made using climate.
climate allows the server to influence the CLI behaviour by using OpenAPI's extensions. It encourages spec-first practices thereby keeping both users and maintenance manageable. It does just enough to handle the spec and nothing more.
Overall, the way it works:
climate-data unless specified via x-cli-name. All subject to changeInfluenced by some of the ideas behind restish it uses the following extensions as of now:
x-cli-aliases: A list of strings which would be used as the alternate names for an operationx-cli-group: A string to allow grouping subcommands together. All operations in the same group would become subcommands in that group namex-cli-hidden: A boolean to hide the operation from the CLI menu. Same behaviour as a cobra command hide: it's present and expects a handlerx-cli-ignored: A boolean to tell climate to omit the operation completelyx-cli-name: A string to specify a different name. Applies to operations and request bodies as of nowapplication/json@payload.json etc.go get github.com/lispyclouds/climate
Given an OpenAPI spec like api.yaml
Load the spec:
model, err := climate.LoadFileV3("api.yaml") // or climate.LoadV3 with []byte
Define a cobra root command:
rootCmd := &cobra.Command{
Use: "calc",
Short: "My Calc",
Long: "My Calc powered by OpenAPI",
}
Define one or more handler functions of the following signature:
func handler(opts *cobra.Command, args []string, data climate.HandlerData) error {
slog.Info("called!", "data", fmt.Sprintf("%+v", data))
err := doSomethingUseful(data)
return err
}
(Feedback welcome to make this better!)
As of now, each handler is called with the cobra command it was invoked with, the args and an extra climate.HandlerData, more info here
This can be used to query the params from the command mostly in a type safe manner:
// to get all the int path params
for _, param := range data.PathParams {
if param.Type == climate.Integer {
value, _ := opts.Flags().GetInt(param.Name)
}
}
Define the handlers for the necessary operations. These map to the operationId field of each operation:
handlers := map[string]Handler{
"AddGet": handler,
"AddPost": handler,
"HealthCheck": handler,
"GetInfo": handler,
}
Bootstrap the root command:
err := climate.BootstrapV3(rootCmd, *model, handlers)
Continue adding more commands and/or execute:
// add more commands not from the spec
rootCmd.Execute()
Sample output:
$ go run main.go --help
My Calc powered by OpenAPI
Usage:
calc [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
info Operations on info
ops Operations on ops
ping Returns Ok if all is well
Flags:
-h, --help help for calc
Use "calc [command] --help" for more information about a command.
$ go run main.go ops --help
Operations on ops
Usage:
calc ops [command]
Available Commands:
add-get Adds two numbers
add-post Adds two numbers via POST
Flags:
-h, --help help for ops
Use "calc ops [command] --help" for more information about a command.
$ go run main.go ops add-get --help
Adds two numbers
Usage:
calc ops add-get [flags]
Aliases:
add-get, ag
Flags:
-h, --help help for add-get
--n1 int The first number
--n2 int The second number
$ go run main.go ops add-get --n1 1 --n2 foo
Error: invalid argument "foo" for "--n2" flag: strconv.ParseInt: parsing "foo": invalid syntax
Usage:
calc ops add-get [flags]
Aliases:
add-get, ag
Flags:
-h, --help help for add-get
--n1 int The first number
--n2 int The second number
$ go run main.go ops add-get --n1 1 --n2 2
2024/12/14 12:53:32 INFO called! data="{Method:get Path:/add/{n1}/{n2}}"
Copyright © 2024- Rahul De
Distributed under the MIT License. See LICENSE.
FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Claude Opus 4.6 has uncovered more than 500 open source vulnerabilities, raising new considerations for disclosure, triage, and patching at scale.

Research
/Security News
Malicious dYdX client packages were published to npm and PyPI after a maintainer compromise, enabling wallet credential theft and remote code execution.

Security News
gem.coop is testing registry-level dependency cooldowns to limit exposure during the brief window when malicious gems are most likely to spread.