This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
dagger/plancontext/fs.go

99 lines
1.8 KiB
Go
Raw Normal View History

package plancontext
import (
"fmt"
"sync"
"cuelang.org/go/cue"
"github.com/google/uuid"
"github.com/moby/buildkit/client/llb"
bkgw "github.com/moby/buildkit/frontend/gateway/client"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/pkg"
)
var fsIDPath = cue.MakePath(
cue.Str("$dagger"),
cue.Str("fs"),
cue.Hid("_id", pkg.DaggerPackage),
)
func IsFSValue(v *compiler.Value) bool {
return v.LookupPath(fsIDPath).Exists()
}
type FS struct {
id string
result bkgw.Reference
}
func (fs *FS) Result() bkgw.Reference {
return fs.result
}
func (fs *FS) State() (llb.State, error) {
if fs.Result() == nil {
return llb.Scratch(), nil
}
return fs.Result().ToState()
}
func (fs *FS) MarshalCUE() *compiler.Value {
v := compiler.NewValue()
if fs.result == nil {
if err := v.FillPath(fsIDPath, nil); err != nil {
panic(err)
}
} else {
if err := v.FillPath(fsIDPath, fs.id); err != nil {
panic(err)
}
}
return v
}
type fsContext struct {
l sync.RWMutex
store map[string]*FS
}
func (c *fsContext) New(result bkgw.Reference) *FS {
c.l.Lock()
defer c.l.Unlock()
fs := &FS{
// FIXME: get a hash from result instead
id: uuid.New().String(),
result: result,
}
c.store[fs.id] = fs
return fs
}
func (c *fsContext) FromValue(v *compiler.Value) (*FS, error) {
c.l.RLock()
defer c.l.RUnlock()
if !v.LookupPath(fsIDPath).IsConcrete() {
return nil, fmt.Errorf("invalid FS at path %q: FS is not set", v.Path())
}
// This is #Scratch, so we'll return an empty FS
if v.LookupPath(fsIDPath).Kind() == cue.NullKind {
return &FS{}, nil
}
id, err := v.LookupPath(fsIDPath).String()
if err != nil {
return nil, fmt.Errorf("invalid FS at path %q: %w", v.Path(), err)
}
fs, ok := c.store[id]
if !ok {
return nil, fmt.Errorf("fs %q not found", id)
}
return fs, nil
}