Skip to content

Commit

Permalink
feat: add basic go integration
Browse files Browse the repository at this point in the history
Signed-off-by: Vasek - Tom C <[email protected]>
  • Loading branch information
TomChv committed Dec 20, 2024
1 parent 81e9ee4 commit 19261b4
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions magicsdk/magic_sdk/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
go.opentelemetry.io/otel/trace v1.27.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.20.0
golang.org/x/net v0.29.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions magicsdk/magic_sdk/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
Expand Down
117 changes: 117 additions & 0 deletions magicsdk/magic_sdk/integration/go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package integration

import (
"context"
"encoding/json"
"fmt"

"dagger.io/dagger"
"dagger.io/dagger/dag"
"dagger.io/magicsdk/codebase"
"dagger.io/magicsdk/invocation"
"dagger.io/magicsdk/utils"
"golang.org/x/mod/modfile"
)

type Go struct {
Dir *dagger.Directory

version string
supported bool
}

func GoIntegration(code *codebase.Codebase) (Integration, error) {
gomod, err, exist := code.LookupFile("go.mod")
if err != nil {
return nil, fmt.Errorf("failed to lookup go.mod: %w", err)
}

if !exist {
return &Go{supported: false}, nil
}

stat, err := gomod.Stat()
if err != nil {
return nil, fmt.Errorf("failed to get stat on go.mod file")
}

gomodContent := make([]byte, stat.Size())
_, err = gomod.Read(gomodContent)
if err != nil {
return nil, fmt.Errorf("failed to read go.mod: %w", err)
}

modfile, err := modfile.Parse("go.mod", gomodContent, nil)
if err != nil {
return nil, fmt.Errorf("failed to parse go.mod: %w", err)
}

return &Go{
version: modfile.Go.Version,
supported: true,
}, nil
}

func (g *Go) Description() string {
return fmt.Sprintf("Access function to manage your Go project (version %s)", g.version)
}

func (g *Go) Exist() bool {
return g.supported
}

func (g *Go) TypeDef() *dagger.TypeDef {
return dag.
TypeDef().
WithObject("Go").
WithFunction(
dag.Function("Container", dag.TypeDef().WithObject("Container")).
WithDescription("Create a Golang development container for your project"),
)
}

func (g *Go) New(invocation *invocation.Invocation) Integration {
// Workaround to parse argument since `UnmarshalJSON` isn't generated for Dagger type in
// the client library.
// This should be fixed later to integrate a real MagicSDK
var dir *dagger.Directory

if invocation.InputArgs["dir"] != nil {
dir = utils.LoadDirectoryFromID([]byte(invocation.InputArgs["dir"]))
}

return &Go{
Dir: dir,
}
}

func (g *Go) Container() (*dagger.Container, error) {
return dag.
Container().
From(fmt.Sprintf("golang:%s-alpine", g.version)).
WithDirectory("/src", g.Dir).
WithWorkdir("/src"), nil
}

func (g *Go) Invoke(ctx context.Context, invocation *invocation.Invocation) (_ any, err error) {
switch invocation.FnName {
case "Container":
// Workaround to parse argument since `UnmarshalJSON` isn't generated for Dagger type in
// the client library.
// This should be fixed later to integrate a real MagicSDK
var parentMap map[string]interface{}
err = json.Unmarshal(invocation.ParentJSON, &parentMap)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal parent object: %w", err)
}

parent := Go{
Dir: dag.LoadDirectoryFromID(dagger.DirectoryID(parentMap["Dir"].(string))),
version: g.version,
}

return (*Go).Container(&parent)
default:
return nil, fmt.Errorf("unknown function %s", invocation.FnName)
}
}
6 changes: 6 additions & 0 deletions magicsdk/magic_sdk/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,25 @@ type Integrations map[string]Integration
type Integration interface {
Exist() bool

// Description of the integration.
Description() string

// New creates a new instance of the integration based on the caller context.
New(invocation *invocation.Invocation) Integration

// TypeDef returns the type definition for the integration with
// all functions and fields it provides.
TypeDef() *dagger.TypeDef

// Invoke the function of the integration called by the caller.
Invoke(ctx context.Context, invocation *invocation.Invocation) (_ any, err error)
}

type integrationFunc func(code *codebase.Codebase) (Integration, error)

var integrationsFuncs = map[string]integrationFunc{
"Docker": DockerIntegration,
"Go": GoIntegration,
}

func LoadIntegrations(code *codebase.Codebase) (Integrations, error) {
Expand Down

0 comments on commit 19261b4

Please sign in to comment.