diff --git a/cmd/dagger/cmd/input/list.go b/cmd/dagger/cmd/input/list.go index e66aac28..dd7cc07d 100644 --- a/cmd/dagger/cmd/input/list.go +++ b/cmd/dagger/cmd/input/list.go @@ -60,6 +60,21 @@ var listCmd = &cobra.Command{ isConcrete := (inp.IsConcreteR() == nil) _, hasDefault := inp.Default() + switch { + case env.Context().Secrets.Contains(inp): + if _, err := env.Context().Secrets.FromValue(inp); err != nil { + isConcrete = false + } + case env.Context().FS.Contains(inp): + if _, err := env.Context().FS.FromValue(inp); err != nil { + isConcrete = false + } + case env.Context().Services.Contains(inp): + if _, err := env.Context().Services.FromValue(inp); err != nil { + isConcrete = false + } + } + if !viper.GetBool("all") { // skip input that is not overridable if !hasDefault && isConcrete { diff --git a/cmd/dagger/cmd/up.go b/cmd/dagger/cmd/up.go index 519e39b8..1dc859b7 100644 --- a/cmd/dagger/cmd/up.go +++ b/cmd/dagger/cmd/up.go @@ -140,7 +140,23 @@ func checkInputs(ctx context.Context, env *environment.Environment) error { } for _, i := range inputs { - if i.IsConcreteR(cue.Optional(true)) != nil { + isConcrete := (i.IsConcreteR(cue.Optional(true)) == nil) + switch { + case env.Context().Secrets.Contains(i): + if _, err := env.Context().Secrets.FromValue(i); err != nil { + isConcrete = false + } + case env.Context().FS.Contains(i): + if _, err := env.Context().FS.FromValue(i); err != nil { + isConcrete = false + } + case env.Context().Services.Contains(i): + if _, err := env.Context().Services.FromValue(i); err != nil { + isConcrete = false + } + } + + if !isConcrete { notConcreteInputs = append(notConcreteInputs, i) } } diff --git a/compiler/value.go b/compiler/value.go index 372070ad..30fdac18 100644 --- a/compiler/value.go +++ b/compiler/value.go @@ -157,6 +157,7 @@ func (v *Value) IsConcrete() bool { // Recursive concreteness check. func (v *Value) IsConcreteR(opts ...cue.Option) error { o := []cue.Option{ + cue.All(), cue.Concrete(true), cue.Hidden(true), } diff --git a/environment/pipeline.go b/environment/pipeline.go index 65647097..76beef79 100644 --- a/environment/pipeline.go +++ b/environment/pipeline.go @@ -40,13 +40,6 @@ const ( StateCompleted = State("completed") ) -var ( - fsIDPath = cue.MakePath( - cue.Hid("_fs", "alpha.dagger.io/dagger"), - cue.Str("id"), - ) -) - // An execution pipeline type Pipeline struct { code *compiler.Value @@ -102,90 +95,40 @@ func IsComponent(v *compiler.Value) bool { return v.Lookup("#up").Exists() } -func isFS(v *compiler.Value) bool { - return v.LookupPath(fsIDPath).Exists() -} - -func ops(code *compiler.Value) ([]*compiler.Value, error) { +func (p *Pipeline) ops() ([]*compiler.Value, error) { ops := []*compiler.Value{} // dagger.#FS forward compat // FIXME: remove this - if isFS(code) { - ops = append(ops, code) + if p.pctx.FS.Contains(p.code) { + ops = append(ops, p.code) } // 1. attachment array - if IsComponent(code) { - xops, err := code.Lookup("#up").List() + if IsComponent(p.code) { + xops, err := p.code.Lookup("#up").List() if err != nil { return nil, err } // 'from' has an executable attached ops = append(ops, xops...) // 2. individual op - } else if _, err := code.Lookup("do").String(); err == nil { - ops = append(ops, code) + } else if _, err := p.code.Lookup("do").String(); err == nil { + ops = append(ops, p.code) // 3. op array - } else if xops, err := code.List(); err == nil { + } else if xops, err := p.code.List(); err == nil { ops = append(ops, xops...) } else { // 4. error - source, err := code.Source() + source, err := p.code.Source() if err != nil { panic(err) } - return nil, fmt.Errorf("not executable: %s (%s)", source, code.Path().String()) + return nil, fmt.Errorf("not executable: %s (%s)", source, p.code.Path().String()) } return ops, nil } -func Analyze(fn func(*compiler.Value) error, code *compiler.Value) error { - ops, err := ops(code) - if err != nil { - // Ignore CUE errors when analyzing. This might be because the value is - // not concrete since static analysis runs before pipelines are executed. - return nil - } - for _, op := range ops { - if err := analyzeOp(fn, op); err != nil { - return err - } - } - return nil -} - -func analyzeOp(fn func(*compiler.Value) error, op *compiler.Value) error { - // dagger.#FS forward compat - // FIXME: remove this - if isFS(op) { - return nil - } - - if err := fn(op); err != nil { - return err - } - do, err := op.Lookup("do").String() - if err != nil { - return err - } - switch do { - case "load", "copy": - return Analyze(fn, op.Lookup("from")) - case "exec": - fields, err := op.Lookup("mount").Fields() - if err != nil { - return err - } - for _, mnt := range fields { - if from := mnt.Value.Lookup("from"); from.Exists() { - return Analyze(fn, from) - } - } - } - return nil -} - func (p *Pipeline) Run(ctx context.Context) error { lg := log. Ctx(ctx). @@ -230,7 +173,7 @@ func (p *Pipeline) Run(ctx context.Context) error { } func (p *Pipeline) run(ctx context.Context) error { - ops, err := ops(p.code) + ops, err := p.ops() if err != nil { return err } @@ -269,7 +212,7 @@ func (p *Pipeline) run(ctx context.Context) error { func (p *Pipeline) doOp(ctx context.Context, op *compiler.Value, st llb.State) (llb.State, error) { // dagger.#FS forward compat // FIXME: remove this - if isFS(op) { + if p.pctx.FS.Contains(op) { fs, err := p.pctx.FS.FromValue(op) if err != nil { return st, nil diff --git a/plancontext/fs.go b/plancontext/fs.go index f0b012f2..208a9827 100644 --- a/plancontext/fs.go +++ b/plancontext/fs.go @@ -54,6 +54,10 @@ func (c *fsContext) New(result bkgw.Reference) *FS { return fs } +func (c *fsContext) Contains(v *compiler.Value) bool { + return v.LookupPath(fsIDPath).Exists() +} + func (c *fsContext) FromValue(v *compiler.Value) (*FS, error) { c.l.RLock() defer c.l.RUnlock() diff --git a/plancontext/secret.go b/plancontext/secret.go index a03b2739..8ff97dd1 100644 --- a/plancontext/secret.go +++ b/plancontext/secret.go @@ -55,6 +55,10 @@ func (c *secretContext) New(plaintext string) *Secret { return secret } +func (c *secretContext) Contains(v *compiler.Value) bool { + return v.LookupPath(secretIDPath).Exists() +} + func (c *secretContext) FromValue(v *compiler.Value) (*Secret, error) { c.l.RLock() defer c.l.RUnlock() diff --git a/plancontext/service.go b/plancontext/service.go index a8079099..4b4c7f9c 100644 --- a/plancontext/service.go +++ b/plancontext/service.go @@ -62,6 +62,10 @@ func (c *serviceContext) New(unix, npipe string) *Service { return s } +func (c *serviceContext) Contains(v *compiler.Value) bool { + return v.LookupPath(serviceIDPath).Exists() +} + func (c *serviceContext) FromValue(v *compiler.Value) (*Service, error) { c.l.RLock() defer c.l.RUnlock()