#Note that it's a limitation of the

1 messages ยท Page 1 of 1 (latest)

cerulean rapids
#

As it turns out, I do have questions here.

tl;dr:

Is there any clever way that I could get a hold of the functions that the official Go SDK generates code for? I can't import them directly since they're in package main

long-form:

I previously had my own CLI that used the docker daemon to do this. you'd run something like:

forge use actions/setup-go@v5 --with go-version=1.24

I wanted to make this into a usable dagger module that can still be used as a CLI as before.

I've got it modified this into a dagger module that can be used like so in the dagger shell like so with equivalent results:

use actions/setup-go@v5 --with go-version=1.24 | main

And now I want to be able to write my own CLI again that pretty much does the same thing that the dagger CLI does, but just for my module

obsidian quest
#

@cerulean rapids if I understand correctly, you're looking for a module introspection API? A way to load a dagger module (written in Go or any other language), and discover all its types, functions, etc?

#

Or, more simply: you want to write a custom CLI that wraps your dagger module?

cerulean rapids
#

Yes to the simplified version. I think I lack enough foundational understanding of dagger to fully comprehend your first response

obsidian quest
#

Sorry, I was overthinking it ๐Ÿ™‚

#

So, probably what you want is a generated Go client for your module

cerulean rapids
#

I'd like this in any directory:

forge use actions/setup-go@v5 --with go-version=1.24

To operate identically to the way this does when in the directory of my module:

dagger -c 'use actions/setup-go@v5 --with go-version=1.24 | main'
obsidian quest
#

So that you can call your module's code from an external client (your custom CLI) with the same comfortable type-safe experience that you get when calling it from another module

#

(note: modules can depend on other modules, and Dagger takes care of generating bindings for that)

#

So, here's roughly how to do that:

  1. Initialize a dagger module in the source code of your custom CLI, but don't select a SDK. cd ./source/code/of/your/cli; dagger init. I'll call this the "upstream module".

  2. Install your actual module as a dependency. dagger install path/to/your/existing/module. This is the "downstream module"

  3. Generate a go client in your CLI in your upstream module: dagger client install go -> this will generate a client library in ./dagger.

  4. Import ./dagger from your CLI.

cerulean rapids
#

Wow, that's nice. Is there any work I'd need to do to load my module into the engine, or does the generated client do that?

obsidian quest
#

The generated client does it. But if the module is on your local filesystem, you need to be mindful of your current directory when you run your client

#

if you reference downstream modules by remote git ref, it should all be done magically

#

cc @silk rock who developed the generated client feature

#

NOTE: dagger client is experimental and may have a few rough edges. Everything else (module dependency system etc) is very mature

#

@cerulean rapids as a fun example, let's say I want to write a custom CLI that just runs the Dagger docs server locally. There's a dagger function available for that, so I can just import it:

dagger init dagger-docs
cd dagger-docs
dagger init
dagger install github.com/dagger/dagger/docs@main
dagger client install go

Then I'll write my minimal CLI:

package main

import (
    "dagger-docs/dagger"
    "context"
)

func main() {
    ctx := context.Background()
    dag, err := dagger.Connect(ctx)
    if err != nil {
        panic(err)
    }
    dag.Docs().Server().Up(ctx)
}

Then to run my docs server:

go run main.go

This ๐Ÿ‘† by default will output nothing (default client config for non-invasive embedding). But I can wrap it in dagger run to get the same fancy terminal output:

dagger run go run main.go