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/dagger/component.go
Solomon Hykes 612a25fb9f Simplify code by moving polyfill cue compiler to sub-package cc
Signed-off-by: Solomon Hykes <sh.github.6811@hykes.org>
2021-02-08 15:10:32 -08:00

102 lines
2.4 KiB
Go

package dagger
import (
"context"
"os"
"dagger.cloud/go/dagger/cc"
"github.com/pkg/errors"
)
type Component struct {
// Source value for the component, without spec merged
// eg. `{ string, #dagger: compute: [{do:"fetch-container", ...}]}`
v *cc.Value
}
func NewComponent(v *cc.Value) (*Component, error) {
if !v.Exists() {
// Component value does not exist
return nil, ErrNotExist
}
if !v.Get("#dagger").Exists() {
// Component value exists but has no `#dagger` definition
return nil, ErrNotExist
}
// Validate & merge with spec
final, err := v.Finalize(spec.Get("#Component"))
if err != nil {
return nil, errors.Wrap(err, "invalid component")
}
return &Component{
v: final,
}, nil
}
func (c *Component) Value() *cc.Value {
return c.v
}
// Return the contents of the "#dagger" annotation.
func (c *Component) Config() *cc.Value {
return c.Value().Get("#dagger")
}
// Return this component's compute script.
func (c *Component) ComputeScript() (*Script, error) {
return newScript(c.Config().Get("compute"))
}
// Return a list of local dirs required to compute this component.
// (Scanned from the arg `dir` of operations `do: "local"` in the
// compute script.
func (c *Component) LocalDirs(ctx context.Context) (map[string]string, error) {
s, err := c.ComputeScript()
if err != nil {
return nil, err
}
return s.LocalDirs(ctx)
}
// Compute the configuration for this component.
//
// Difference with Execute:
//
// 1. Always start with an empty fs state (Execute may receive any state as input)
// 2. Always solve at the end (Execute is lazy)
//
func (c *Component) Compute(ctx context.Context, s Solver, out *Fillable) (FS, error) {
fs, err := c.Execute(ctx, s.Scratch(), out)
if err != nil {
return fs, err
}
// Force a `Solve()` in case it hasn't been called earlier.
// If the FS is already solved, this is a noop.
_, err = fs.Solve(ctx)
return fs, err
}
// A component implements the Executable interface by returning its
// compute script.
// See cc.Value.Executable().
func (c *Component) Execute(ctx context.Context, fs FS, out *Fillable) (FS, error) {
script, err := c.ComputeScript()
if err != nil {
// If the component has no script, then do not fail.
if os.IsNotExist(err) {
return fs, nil
}
return fs, err
}
return script.Execute(ctx, fs, out)
}
func (c *Component) Walk(ctx context.Context, fn func(*Op) error) error {
script, err := c.ComputeScript()
if err != nil {
return err
}
return script.Walk(ctx, fn)
}