Skip to main content

Chaining

Dagger Functions can return custom objects, which in turn can define new functions. This allows for "chaining" of functions in the same style as the core Dagger API.

So long as your object can be JSON-serialized, its state will be preserved and passed to the next function in the chain.

Here is an example module with support for function chaining:

// A Dagger module for saying hello world!

package main

import (
"context"
"fmt"
)

type MyModule struct {
Greeting string
Name string
}

func (hello *MyModule) WithGreeting(ctx context.Context, greeting string) (*MyModule, error) {
hello.Greeting = greeting
return hello, nil
}

func (hello *MyModule) WithName(ctx context.Context, name string) (*MyModule, error) {
hello.Name = name
return hello, nil
}

func (hello *MyModule) Message(ctx context.Context) (string, error) {
var (
greeting = hello.Greeting
name = hello.Name
)
if greeting == "" {
greeting = "Hello"
}
if name == "" {
name = "World"
}
return fmt.Sprintf("%s, %s!", greeting, name), nil
}

And here is an example call for this module:

dagger call with-name --name=Monde with-greeting --greeting=Bonjour message

The result will be:

Bonjour, Monde!