MCPcopy Index your code
hub / github.com/Masterminds/cookoo

github.com/Masterminds/cookoo @v1.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.0 ↗ · + Follow
401 symbols 1,355 edges 48 files 255 documented · 64%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Cookoo

A chain-of-command framework written in Go

Build Status GoDoc

Usage

$ cd $GOPATH
$ go get github.com/Masterminds/cookoo

Use it as follows (from example/example.go):

package main

import (
    // This is the path to Cookoo
    "fmt"
    "github.com/Masterminds/cookoo"
)

func main() {

    // Build a new Cookoo app.
    registry, router, context := cookoo.Cookoo()

    // Fill the registry.
    registry.AddRoutes(
        cookoo.Route{
            Name: "TEST",
            Help: "A test route",
            Does: cookoo.Tasks{
                cookoo.Cmd{
                    Name: "hi",
                    Fn:   HelloWorld,
                },
            },
        },
    )

    // Execute the route.
    router.HandleRequest("TEST", context, false)
}

func HelloWorld(cxt cookoo.Context, params *cookoo.Params) (interface{}, cookoo.Interrupt) {
    fmt.Println("Hello World")
    return true, nil
}

Documentation

A Real Example

For a real example of Cookoo, take a look at Skunk.

Here's what Skunk's registry looks like:

    registry.
    Route("scaffold", "Scaffold a new app.").
        Does(LoadSettings, "settings").
            Using("file").WithDefault(homedir + "/settings.json").From("cxt:SettingsFile").
        Does(MakeDirectories, "dirs").
            Using("basedir").From("cxt:basedir").
            Using("directories").From("cxt:directories").
        Does(RenderTemplates, "template").
            Using("tpldir").From("cxt:homedir").
            Using("basedir").From("cxt:basedir").
            Using("templates").From("cxt:templates").
    Route("help", "Print help").
        Does(Usage, "Testing")

This has two routes:

  • scaffold
  • help

The help route just runs the command Usage, which looks like this:

func Usage(cxt cookoo.Context, params *cookoo.Params) interface{} {
    fmt.Println("Usage: skunk PROJECTNAME")
    return true
}

That is a good example of a basic command.

The scaffold route is more complex. It performs the following commands (in order):

  • LoadSettings: Load a settings.json file into the context.
  • MakeDirectories: Make a bunch of directories.
  • RenderTemplates: Perform template conversions on some files.

The MakeDirectories command is an example of a more complex command. It takes two parameters (declared with Using().From()):

  1. basedir: The base directory where the new subdirectories will be created. This comes from the cxt:basedir source, which means Cookoo looks in the Context object for a value named basedir.
  2. directoies: An array of directory names that this command will create. These come from cxt:directories, which means that the Context object is queried for the value of directories. In this case, that value is actually loaded from the settings.json file into the context by the LoadSettings command.`

With that in mind, let's look at the command:

// The MakeDirectories command.
// All commands take a Context and a Params object, and return an
// interface{}
func MakeDirectories(cxt cookoo.Context, params *cookoo.Params) interface{} {

    // This is how we get something out of the Params object. This is the
    // value that was passed in by `Using('basedir').From('cxt:basedir')
    basedir := params.Get("basedir", ".").(string)

    // This is another way to get a parameter value. This form allows us
    // to conveniently check that the parameter exists.
    d, ok := params.Has("directories")
    if !ok {
        // Did nothing. But we don't want to raise an error.
        return false
    }

    // We do have to do an explicit type conversion.
    directories := d.([]interface{})

    // Here we do the work of creating directories.
    for _, dir := range directories {
        dname := path.Join(basedir, dir.(string))
        os.MkdirAll(dname, 0755)
    }

    // We don't really have anything special to return, so we just
    // indicate that the command was successful.
    return true
}

This is a basic example of working with Cookoo. But far more sophisticated workflows can be built inexpensively and quickly, and in a style that encourages building small and re-usable chunks of code.

Extension points exported contracts — how you extend this code

Getter (Interface)
Getter can get values in two ways. A Get() can be given a default value, in which case it will return either the value [6 …
getter.go
KeyValueDatasource (Interface)
KeyValueDatasource is a datasource that can retrieve values by (string) keys. Datsources can be just about anything. But [7 …
context.go
CommandDefinition (Interface)
CommandDefinition defines what a command objects looks like. Fields on a command struct may be annotated with tags. A t [4 …
mapper.go
RequestResolver (Interface)
RequestResolver is the interface for the request resolver. A request resolver is responsible for transforming a request [3 …
router.go
Task (Interface)
A Task can be either an Include or a Cmd. This is a very lame way of making this behavior private. [3 implementers]
registry.go
Logger (Interface)
Captures the log portion of a cookoo.Context. [2 implementers]
safely/safely.go
StmtCache (Interface)
A StmtCache caches SQL prepared statements. It's intended use is as a datsource for a long-running SQL-backed applicati [1 …
database/sql/datasource.go
Command (FuncType)
Command executes a command and returns a result. A Cookoo app has a registry, which has zero or more routes. Each route
cookoo.go

Core symbols most depended-on inside this repo

Error
called by 187
router.go
Get
called by 92
getter.go
Using
called by 72
registry.go
Route
called by 62
registry.go
WithDefault
called by 62
registry.go
Does
called by 57
registry.go
HandleRequest
called by 47
router.go
Has
called by 39
getter.go

Shape

Method 168
Function 163
Struct 48
Interface 17
TypeAlias 3
FuncType 2

Languages

Go100%

Modules by API surface

context.go44 symbols
registry.go38 symbols
getter.go29 symbols
router_test.go25 symbols
router.go24 symbols
log/log.go21 symbols
sync_context.go19 symbols
web/datasources.go18 symbols
params.go12 symbols
cookoo.go11 symbols
registry_test.go10 symbols
database/active/record.go10 symbols

For agents

$ claude mcp add cookoo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact