Arguments
Dagger Functions, just like regular functions, can accept arguments. In addition to basic types (string, boolean, integer, arrays...), Dagger also defines powerful core types which Dagger Functions can use for their arguments, such as Directory
, Container
, Service
, Secret
, and many more.
When calling a Dagger Function from the CLI, its arguments are exposed as command-line flags. How the flag is interpreted depends on the argument type.
Dagger Functions execute in containers and thus do not have default access to your host environment (host files, directories, environment variables, etc.). Access to these host resources can only be granted by explicitly passing them as argument values to the Dagger Function.
- Files and directories: Dagger Functions can accept arguments of type
File
orDirectory
. Pass files and directories on your host by specifying their path as the value of the argument when usingdagger call
. - Environment variables: Pass environment variable values as argument values when invoking a function by just using the standard shell convention of using
$ENV_VAR_NAME
when usingdagger call
. - Local network services: Dagger Functions that accept an argument of type
Service
can be passed local network services in the formtcp://HOST:PORT
.
String arguments
To pass a string argument to a Dagger Function, add the corresponding flag to the dagger call
command, followed by the string value.
Here is an example of a Dagger Function that accepts a string argument:
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"fmt"
)
type MyModule struct{}
func (m *MyModule) GetUser(ctx context.Context, gender string) (string, error) {
return dag.Container().
From("alpine:latest").
WithExec([]string{"apk", "add", "curl"}).
WithExec([]string{"apk", "add", "jq"}).
WithExec([]string{"sh", "-c", fmt.Sprintf("curl https://randomuser.me/api/?gender=%s | jq .results[0].name", gender)}).
Stdout(ctx)
}
from dagger import dag, function, object_type
@object_type
class MyModule:
@function
async def get_user(self, gender: str) -> str:
return await (
dag.container()
.from_("alpine:latest")
.with_exec(["apk", "add", "curl"])
.with_exec(["apk", "add", "jq"])
.with_exec(
[
"sh",
"-c",
(
f"curl https://randomuser.me/api/?gender={gender}"
" | jq .results[0].name"
),
]
)
.stdout()
)
Even though the Python runtime doesn't enforce type annotations at runtime, it's important to define them with Dagger Functions. The Python SDK needs the typing information at runtime to correctly report to the API. It can't rely on type inference, which is only possible for external static type checkers.
If a function doesn't have a return type annotation, it'll be declared as None
,
which translates to the dagger.Void type in the API:
@function
def hello(self):
return "Hello world!"
# Error: cannot convert string to Void
It's fine however, when no value actually needs to be returned:
@function
def hello(self):
...
# no return
import { dag, object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
async getUser(gender: string): Promise<string> {
return await dag
.container()
.from("alpine:latest")
.withExec(["apk", "add", "curl"])
.withExec(["apk", "add", "jq"])
.withExec([
"sh",
"-c",
`curl https://randomuser.me/api/?gender=${gender} | jq .results[0].name`,
])
.stdout()
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction};
use function Dagger\dag;
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function getUser(string $gender): string
{
return dag()
->container()
->from("alpine:latest")
->withExec(["apk", "add", "curl"])
->withExec(["apk", "add", "jq"])
->withExec([
"sh",
"-c",
"curl https://randomuser.me/api/?gender={$gender} | jq .results[0].name",
])
->stdout();
}
}
Even though PHP doesn't enforce type annotations at runtime, it's important to define them with Dagger Functions. The PHP SDK needs the typing information at runtime to correctly report to the API.
Here is an example call for this Dagger Function:
dagger call get-user --gender=male
The result will look something like this:
{
"title": "Mr",
"first": "Hans-Werner",
"last": "Thielen"
}
To pass host environment variables as arguments when invoking a Dagger Function, use the standard shell convention of $ENV_VAR_NAME
when using dagger call
.
Here is an example of passing a host environment variable containing a string value to a Dagger Function:
export GREETING=bonjour
dagger -m github.com/shykes/daggerverse/hello@v0.3.0 call hello --greeting=$GREETING
Boolean arguments
To pass a Boolean argument to a Dagger Function, simply add the corresponding flag, like so:
- To set the argument to true:
--foo=true
, or simply--foo
- To set the argument to false:
--foo=false
Here is an example of a Dagger Function that accepts a Boolean argument:
- Go
- Python
- TypeScript
- PHP
package main
import (
"strings"
)
type MyModule struct{}
func (m *MyModule) Hello(shout bool) string {
message := "Hello, world"
if shout {
return strings.ToUpper(message)
}
return message
}
from dagger import function, object_type
@object_type
class MyModule:
@function
def hello(self, shout: bool) -> str:
message = "Hello, world"
if shout:
return message.upper()
return message
import { object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
hello(shout: boolean): string {
const message = "Hello, world"
if (shout) {
return message.toUpperCase()
}
return message
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function hello(bool $shout): string
{
$message = 'Hello, world';
if ($shout) {
return strtoupper($message);
}
return $message;
}
}
Here is an example call for this Dagger Function:
dagger call hello --shout=true
The result will look like this:
HELLO, WORLD
Integer arguments
To pass an integer argument to a Dagger function, add the corresponding flag to the dagger call
command, followed by the integer value.
Here is an example of a Dagger function that accepts an integer argument:
- Go
- Python
- TypeScript
- PHP
package main
type MyModule struct{}
func (m *MyModule) AddInteger(a int, b int) int {
return a + b
}
from dagger import function, object_type
@object_type
class MyModule:
@function
async def add_integer(self, a: int, b: int) -> int:
return a + b
import { object, func } from "@dagger.io/dagger"
@object()
export class MyModule {
@func()
addInteger(a: number, b: number): number {
return a + b
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function addInteger(int $a, int $b): int
{
return $a + $b;
}
}
Here is an example call for this Dagger Function:
dagger call add-integer --a 1 --b 2
The result will look like this:
3
Floating-point number arguments
To pass a floating-point number as argument to a Dagger function, add the corresponding flag to the dagger call
command, followed by the value.
Here is an example of a Dagger function that accepts a floating-point number as argument:
- Go
- Python
- TypeScript
- PHP
package main
type MyModule struct{}
func (m *MyModule) AddFloat(a float64, b float64) float64 {
return a + b
}
from dagger import function, object_type
@object_type
class MyModule:
@function
async def add_float(self, a: float, b: float) -> float:
return a + b
There's no float
type keyword in TypeScript because the type keyword number
already supports floating point numbers.
To declare a float
argument on the function signature, import float
from @dagger.io/dagger
and use it as an argument's type.
The imported float
type is a number
underneath, so you can use it as you would use a number
inside your function.
import type { float } from "@dagger.io/dagger"
import { object, func } from "@dagger.io/dagger"
@object()
export class MyModule {
@func()
addFloat(a: float, b: float): float {
return a + b
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function addFloat(float $a, float $b): float
{
return $a + $b;
}
}
Here is an example call for this Dagger Function:
dagger call add-float --a 1.4 --b 2.7
The result will look like this:
4.1
Array arguments
To pass an array argument to a Dagger Function, add the corresponding flag, followed by a comma-separated list of values.
- Go
- Python
- TypeScript
- PHP
package main
import (
"strings"
)
type MyModule struct{}
func (m *MyModule) Hello(names []string) string {
message := "Hello"
if len(names) > 0 {
message += " " + strings.Join(names, ", ")
}
return message
}
from dagger import function, object_type
@object_type
class MyModule:
@function
def hello(self, names: list[str]) -> str:
message = "Hello"
for name in names:
message += f", {name}"
return message
import { object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
hello(names: string[]): string {
let message = "Hello"
for (const name of names) {
message += ` ${name}`
}
return message
}
}
Lists must have their subtype specified by adding the #[ListOfType]
attribute to the relevant function argument.
The PHP SDK needs the typing information at runtime to correctly report to the API.
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction, ListOfType};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function hello(#[ListOfType('string')]array $names): string
{
$message = 'Hello';
if (!empty($names)) {
$message .= " " . implode(', ', $names);
}
return $message;
}
}
Here is an example call for this Dagger Function:
dagger call hello --names=John,Jane
The result will look like this:
Hello John, Jane
Directory arguments
You can also pass a directory argument from the command-line. To do so, add the corresponding flag, followed by a local filesystem path or a remote Git reference. In both cases, the CLI will convert it to an object referencing the contents of that filesystem path or Git repository location, and pass the resulting Directory
object as argument to the Dagger Function.
Dagger Functions do not have access to the filesystem of the host you invoke the Dagger Function from (i.e. the host you execute a CLI command like dagger call
from). Instead, host directories need to be explicitly passed as arguments to Dagger Functions.
Here's an example of a Dagger Function that accepts a Directory
as argument. The Dagger Function returns a tree representation of the files and directories at that path.
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"main/internal/dagger"
)
type MyModule struct{}
func (m *MyModule) Tree(ctx context.Context, src *dagger.Directory, depth string) (string, error) {
return dag.Container().
From("alpine:latest").
WithMountedDirectory("/mnt", src).
WithWorkdir("/mnt").
WithExec([]string{"apk", "add", "tree"}).
WithExec([]string{"tree", "-L", depth}).
Stdout(ctx)
}
import dagger
from dagger import dag, function, object_type
@object_type
class MyModule:
@function
async def tree(self, src: dagger.Directory, depth: str) -> str:
return await (
dag.container()
.from_("alpine:latest")
.with_mounted_directory("/mnt", src)
.with_workdir("/mnt")
.with_exec(["apk", "add", "tree"])
.with_exec(["tree", "-L", depth])
.stdout()
)
import { dag, Directory, object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
async tree(src: Directory, depth: string): Promise<string> {
return await dag
.container()
.from("alpine:latest")
.withMountedDirectory("/mnt", src)
.withWorkdir("/mnt")
.withExec(["apk", "add", "tree"])
.withExec(["tree", "-L", depth])
.stdout()
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction, ListOfType};
use Dagger\Directory;
use function Dagger\dag;
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function tree(Directory $src, string $depth): string
{
return dag()
->container()
->from('alpine:latest')
->withMountedDirectory('/mnt', $src)
->withWorkdir('/mnt')
->withExec(['apk', 'add', 'tree'])
->withExec(['tree', '-L', $depth])
->stdout();
}
}
Here is an example of passing a local directory to this Dagger Function as argument:
mkdir -p mydir/mysubdir
touch mydir/a mydir/b mydir/c mydir/mysubdir/y mydir/mysubdir/z
dagger call tree --src=mydir --depth=2
The result will look like this:
.
├── a
├── b
├── c
└── mysubdir
├── y
└── z
2 directories, 5 files
Here is an example of passing a remote repository (Dagger's open-source repository) over HTTPS as a Directory
argument:
dagger core container \
from --address=alpine:latest \
with-directory --path=/src --directory=https://github.com/dagger/dagger \
with-exec --args="ls","/src" \
stdout
The same repository can also be accessed using SSH. Note that this requires SSH authentication to be properly configured on your Dagger host. Here is the same example, this time using SSH:
dagger core container \
from --address=alpine:latest \
with-directory --path=/src --directory=ssh://git@github.com/dagger/dagger \
with-exec --args="ls","/src" \
stdout
For more information about remote repository access, refer to the documentation on reference schemes and authentication methods.
File arguments
File arguments work in the same way as directory arguments. To pass a file to a Dagger Function as an argument, add the corresponding flag, followed by a local filesystem path or a remote Git reference. In both cases, the CLI will convert it to an object referencing that filesystem path or Git repository location, and pass the resulting File
object as argument to the Dagger Function.
Here's an example of a Dagger Function that accepts a File
as argument, reads it, and returns its contents:
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"dagger/my-module/internal/dagger"
)
type MyModule struct{}
func (m *MyModule) ReadFile(ctx context.Context, source *dagger.File) (string, error) {
contents, err := dag.Container().
From("alpine:latest").
WithFile("/src/myfile", source).
WithExec([]string{"cat", "/src/myfile"}).
Stdout(ctx)
if err != nil {
return "", err
}
return contents, nil
}
import dagger
from dagger import dag, function, object_type
@object_type
class MyModule:
@function
async def read_file(self, source: dagger.File) -> str:
return await (
dag.container()
.from_("alpine:latest")
.with_file("/src/myfile", source)
.with_exec(["cat", "/src/myfile"])
.stdout()
)
import { dag, object, func, File } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
async readFile(source: File): Promise<string> {
return await dag
.container()
.from("alpine:latest")
.withFile("/src/myfile", source)
.withExec(["cat", "/src/myfile"])
.stdout()
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction, ListOfType};
use Dagger\File;
use function Dagger\dag;
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function readFile(File $source): string
{
return dag()
->container()
->from('alpine:latest')
->withFile('/src/myfile', $source)
->withExec(['cat', '/src/myfile'])
->stdout();
}
}
Here is an example of passing a local file to this Dagger Function as argument:
dagger call read-file --source=/my/file/path/README.md
And here is an example of passing a file from a remote Git repository as argument:
dagger call read-file --source=https://github.com/dagger/dagger.git#main:README.md
For more information about remote repository access, refer to the documentation on reference schemes and authentication methods.
Container arguments
Just like directories, you can pass a container to a Dagger Function from the command-line. To do so, add the corresponding flag, followed by the address of an OCI image. The CLI will dynamically pull the image, and pass the resulting Container
object as argument to the Dagger Function.
Here is an example of a Dagger Function that accepts a container image reference as an argument. The Dagger Function returns operating system information for the container.
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"main/internal/dagger"
)
type MyModule struct{}
func (m *MyModule) OsInfo(ctx context.Context, ctr *dagger.Container) (string, error) {
return ctr.
WithExec([]string{"uname", "-a"}).
Stdout(ctx)
}
import dagger
from dagger import function, object_type
@object_type
class MyModule:
@function
async def os_info(self, ctr: dagger.Container) -> str:
return await ctr.with_exec(["uname", "-a"]).stdout()
import { Container, object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
async osInfo(ctr: Container): Promise<string> {
return ctr.withExec(["uname", "-a"]).stdout()
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerObject, DaggerFunction};
use Dagger\Container;
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function osInfo(Container $ctr): string
{
return $ctr->withExec(['uname', '-a'])->stdout();
}
}
Here is an example of passing a container image reference to this Dagger Function as an argument.
dagger call os-info --ctr=ubuntu:latest
The result will look like this:
Linux buildkitsandbox 6.1.0-22-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.94-1 (2024-06-21) x86_64 x86_64 x86_64 GNU/Linux
Here is another example of passing a container image reference to a Dagger Function as an argument. The Dagger Function scans the container using Trivy and reports any vulnerabilities found.
dagger -m github.com/jpadams/daggerverse/trivy@v0.3.0 call scan-container --ctr=index.docker.io/alpine:latest
Secret arguments
Dagger allows you to utilize confidential information, such as passwords, API keys, SSH keys and so on, in your Dagger modules and Dagger Functions, without exposing those secrets in plaintext logs, writing them into the filesystem of containers you're building, or inserting them into the cache.
Secrets can be passed to Dagger Functions as arguments using the Secret
core type. Here is an example of a Dagger Function which accepts a GitHub personal access token as a secret, and uses the token to authorize a request to the GitHub API:
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"main/internal/dagger"
)
type MyModule struct{}
// Query the GitHub API
func (m *MyModule) GithubApi(
ctx context.Context,
// GitHub API token
token *dagger.Secret,
) (string, error) {
return dag.Container().
From("alpine:3.17").
WithSecretVariable("GITHUB_API_TOKEN", token).
WithExec([]string{"apk", "add", "curl"}).
WithExec([]string{"sh", "-c", `curl "https://api.github.com/repos/dagger/dagger/issues" --header "Accept: application/vnd.github+json" --header "Authorization: Bearer $GITHUB_API_TOKEN"`}).
Stdout(ctx)
}
from typing import Annotated
import dagger
from dagger import Doc, dag, function, object_type
@object_type
class MyModule:
@function
async def github_api(
self,
token: Annotated[dagger.Secret, Doc("GitHub API token")],
) -> str:
"""Query the GitHub API"""
return await (
dag.container(platform=dagger.Platform("linux/amd64"))
.from_("alpine:3.17")
.with_secret_variable("GITHUB_API_TOKEN", token)
.with_exec(["apk", "add", "curl"])
.with_exec(
[
"sh",
"-c",
(
'curl "https://api.github.com/repos/dagger/dagger/issues"'
' --header "Authorization: Bearer $GITHUB_API_TOKEN"'
' --header "Accept: application/vnd.github+json"'
),
]
)
.stdout()
)
import { dag, object, func, Secret } from "@dagger.io/dagger"
@object()
class MyModule {
/**
* Query the GitHub API
*/
@func()
async githubApi(
/**
* GitHub API token
*/
token: Secret,
): Promise<string> {
return await dag
.container()
.from("alpine:3.17")
.withSecretVariable("GITHUB_API_TOKEN", token)
.withExec(["apk", "add", "curl"])
.withExec([
"sh",
"-c",
`curl "https://api.github.com/repos/dagger/dagger/issues" --header "Accept: application/vnd.github+json" --header "Authorization: Bearer $GITHUB_API_TOKEN"`,
])
.stdout()
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerFunction, DaggerObject, Doc};
use Dagger\Secret;
use function Dagger\dag;
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
#[Doc('Query the Github API')]
public function githubApi(Secret $token): string
{
return dag()
->container()
->from('alpine:3.17')
->withSecretVariable('GITHUB_API_TOKEN', $token)
->withExec(['apk', 'add', 'curl'])
->withExec([
'sh',
'-c',
'curl "https://api.github.com/repos/dagger/dagger/issues"'
. ' --header "Authorization: Bearer $GITHUB_API_TOKEN"'
. ' --header "Accept: application/vnd.github+json"',
])
->stdout();
}
}
The result will be a JSON-formatted list of issues from Dagger's repository.
When invoking the Dagger Function using the Dagger CLI, secrets can be sourced from multiple providers. Dagger can read secrets from the host environment, the host filesystem, and the result of host command execution, as well as from external secret managers 1Password and Vault.
Host secret providers
Here is an example call for this Dagger Function, with the secret sourced from a host environment variable named GITHUB_API_TOKEN
via the env
provider:
dagger call github-api --token=env://GITHUB_API_TOKEN
Secrets can also be passed from a host file using the file
provider:
dagger call github-api --token=file://./github.txt
...or as the result of executing a command on the host using the cmd
provider:
dagger call github-api --token=cmd://"gh auth token"
External secret providers
Secrets can also be sourced from external secret managers. Currently, Dagger supports 1Password and Vault.
1Password requires creating a service account and then setting the OP_SERVICE_ACCOUNT_TOKEN
environment variable. Alternatively, if no OP_SERVICE_ACCOUNT_TOKEN
is provided, the integration will attempt to execute the (official) op
CLI if installed in the system.
1Password secret references, in the format op://VAULT-NAME/ITEM-NAME/[SECTION-NAME/]FIELD-NAME
are supported. Here is an example:
OP_SERVICE_ACCOUNT_TOKEN="mytoken" dagger call github-api --token=op://infra/github/credential
Vault can be authenticated with either token or AppRole methods. The Vault host can be specified by setting the environment variable VAULT_ADDR
. For token authentication, set the environment variable VAULT_TOKEN
. For AppRole authentication, set the environment variables VAULT_APPROLE_ROLE_ID
and VAULT_APPROLE_SECRET_ID
. Additional client configuration can be specified by the default environment variables accepted by Vault.
Vault KvV2 secrets are accessed with the scheme vault://PATH/TO/SECRET.ITEM
. If your KvV2 is not mounted at /secret
, specify the mount location with the environment variable VAULT_PATH_PREFIX
. Here is an example:
VAULT_ADDR='https://example.com:8200' VAULT_TOKEN=abcd_1234 dagger call github-api --token=vault://infra/github.credential
```shell
dagger call github-api --token=vault://credentials.github
Service arguments
Host network services or sockets can be passed to Dagger Functions as arguments. To do so, add the corresponding flag, followed by a service or socket reference.
TCP and UDP services
To pass host TCP or UDP network services as arguments when invoking a Dagger Function, specify them in the form tcp://HOST:PORT
or udp://HOST:PORT
.
Assume that you have a PostgresQL database running locally on port 5432, as with:
docker run -d -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres
Here is an example of passing this host service as argument to a PostgreSQL client Dagger Function, which drops you to a prompt from where you can execute SQL queries:
dagger -m github.com/kpenfound/dagger-modules/postgres@v0.1.0 call client --db=postgres --user=postgres --password=postgres --server=tcp://localhost:5432
Unix sockets
Similar to host TCP/UDP services, Dagger Functions can also be granted access to host Unix sockets when the client is running on Linux or MacOS.
To pass host Unix sockets as arguments when invoking a Dagger Function, specify them by their path on the host.
For example, assuming you have Docker on your host with the Docker daemon listening on a Unix socket at /var/run/docker.sock
, you can pass this socket to a Docker client Dagger Function as follows:
dagger -m github.com/sipsma/daggerverse/docker-client@v0.0.1 call --sock=/var/run/docker.sock version
Optional arguments
Function arguments can be marked as optional. In this case, the Dagger CLI will not display an error if the argument is omitted in the function call.
Here's an example of a Dagger Function with an optional argument:
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"fmt"
)
type MyModule struct{}
func (m *MyModule) Hello(
ctx context.Context,
// +optional
name string,
) (string, error) {
if name != "" {
return fmt.Sprintf("Hello, %s", name), nil
} else {
return "Hello, world", nil
}
}
from dagger import function, object_type
@object_type
class MyModule:
@function
def hello(self, name: str | None) -> str:
if name is None:
name = "world"
return f"Hello, {name}"
import { object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
hello(name?: string): string {
if (name) {
return `Hello, ${name}`
}
return "Hello, world"
}
}
The definition of optional varies between Dagger and PHP.
An optional argument to PHP is one that has a default value.
An optional argument to Dagger can be omitted entirely. It is truly optional.
To specify a function argument as optional, simply make it nullable. When using the Dagger CLI, if the argument is omitted; the PHP SDK will treat this as receiving the value null
.
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerFunction, DaggerObject};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function hello(?string $name): string
{
if (isset($name)) {
return "Hello, {$name}";
}
return 'Hello, world';
}
}
Here is an example call for this Dagger Function, with the optional argument:
dagger call hello --name=John
The result will look like this:
Hello, John
Here is an example call for this Dagger Function, without the optional argument:
dagger call hello
The result will look like this:
Hello, world
Default values
Function arguments can define a default value if no value is supplied for them.
Here's an example of a Dagger Function with a default value for a string argument:
- Go
- Python
- TypeScript
- PHP
package main
import (
"context"
"fmt"
)
type MyModule struct{}
func (m *MyModule) Hello(
ctx context.Context,
// +optional
// +default="world"
name string,
) (string, error) {
return fmt.Sprintf("Hello, %s", name), nil
}
from dagger import function, object_type
@object_type
class MyModule:
@function
def hello(self, name: str = "world") -> str:
return f"Hello, {name}"
import { object, func } from "@dagger.io/dagger"
@object()
class MyModule {
@func()
hello(name = "world"): string {
return `Hello, ${name}`
}
}
<?php
declare(strict_types=1);
namespace DaggerModule;
use Dagger\Attribute\{DaggerFunction, DaggerObject};
#[DaggerObject]
class MyModule
{
#[DaggerFunction]
public function hello(string $name = 'world'): string
{
return "Hello, {$name}";
}
}
Here is an example call for this Dagger Function, without the required argument:
dagger call hello
The result will look like this:
Hello, world
Passing null to an optional argument signals that no default value should be used.
Reference schemes for remote repositories
Dagger supports the use of HTTP and SSH protocols for accessing files and directories in remote repositories, compatible with all major Git hosting platforms such as GitHub, GitLab, BitBucket, Azure DevOps, Codeberg, and Sourcehut. Dagger supports authentication via both HTTPS (using Git credential managers) and SSH (using a unified authentication approach).
Dagger supports the following reference schemes for file and directory arguments:
Protocol | Scheme | Authentication | Example |
---|---|---|---|
HTTP(S) | Git HTTP | Git credential manager | https://github.com/username/repo.git[#version[:subpath]] |
SSH | Explicit | SSH keys | ssh://git@github.com/username/repo.git[#version[:subpath]] |
SSH | SCP-like | SSH keys | git@github.com:username/repo.git[#version[:subpath]] |
Dagger provides additional flexibility in referencing file and directory arguments through the following options:
- Version specification: Add
#version
to target a particular version of the repository. This can be a tag, branch name, or full commit hash. If omitted, the default branch is used. - Monorepo support: Append
:subpath
after the version specification to access a specific subdirectory within the repository. Note that specifying a version is mandatory when including a subpath.
When referencing a specific subdirectory (subpath) within a repository, you must always include a version specification. The format is always #version:subpath
.