implement .daggerignore

Signed-off-by: Tony Worm <tony@hofstadter.io>
This commit is contained in:
Tony Worm 2021-03-17 19:55:28 -04:00
parent 11e4c69011
commit a1ba7aa59c
3 changed files with 71 additions and 6 deletions

3
.daggerignore Normal file
View File

@ -0,0 +1,3 @@
vendor
hack
cmd/dagger/dagger

View File

@ -1,6 +1,7 @@
package dagger package dagger
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
@ -14,12 +15,17 @@ import (
dockerfilebuilder "github.com/moby/buildkit/frontend/dockerfile/builder" dockerfilebuilder "github.com/moby/buildkit/frontend/dockerfile/builder"
bkgw "github.com/moby/buildkit/frontend/gateway/client" bkgw "github.com/moby/buildkit/frontend/gateway/client"
bkpb "github.com/moby/buildkit/solver/pb" bkpb "github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/frontend/dockerfile/dockerignore"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"dagger.io/go/dagger/compiler" "dagger.io/go/dagger/compiler"
) )
const (
daggerignoreFilename = ".daggerignore"
)
// An execution pipeline // An execution pipeline
type Pipeline struct { type Pipeline struct {
name string name string
@ -257,12 +263,46 @@ func (p *Pipeline) Local(ctx context.Context, op *compiler.Value, st llb.State)
if err != nil { if err != nil {
return st, err return st, err
} }
var include []string
if inc := op.Get("include"); inc.Exists() { // daggerignore processing
if err := inc.Decode(&include); err != nil { // buildkit related setup
daggerignoreState := llb.Local(
dir,
llb.SessionID(p.s.SessionID()),
llb.FollowPaths([]string{daggerignoreFilename}),
llb.SharedKeyHint(dir+"-"+daggerignoreFilename),
llb.WithCustomName(p.vertexNamef("Load %s", daggerignoreFilename)),
)
var daggerignore []byte
def, err := p.s.Marshal(ctx, daggerignoreState)
if err != nil {
return st, err return st, err
} }
ref, err := p.s.SolveRequest(ctx, bkgw.SolveRequest{
Definition: def,
})
if err != nil {
return st, err
} }
// try to read file
daggerignore, err = ref.ReadFile(ctx, bkgw.ReadRequest{
Filename: daggerignoreFilename,
})
// hack for string introspection because !errors.Is(err, os.ErrNotExist) does not work, same for fs
if err != nil && !strings.Contains(err.Error(), ".daggerignore: no such file or directory") {
return st, err
}
// parse out excludes, works even if file does not exist
var excludes []string
excludes, err = dockerignore.ReadAll(bytes.NewBuffer(daggerignore))
if err != nil {
return st, fmt.Errorf("%w failed to parse daggerignore", err)
}
// FIXME: Remove the `Copy` and use `Local` directly. // FIXME: Remove the `Copy` and use `Local` directly.
// //
// Copy'ing is a costly operation which should be unnecessary. // Copy'ing is a costly operation which should be unnecessary.
@ -275,7 +315,8 @@ func (p *Pipeline) Local(ctx context.Context, op *compiler.Value, st llb.State)
llb.Copy( llb.Copy(
llb.Local( llb.Local(
dir, dir,
llb.FollowPaths(include), // llb.FollowPaths(include),
llb.ExcludePatterns(excludes),
llb.WithCustomName(p.vertexNamef("Local %s [transfer]", dir)), llb.WithCustomName(p.vertexNamef("Local %s [transfer]", dir)),
// Without hint, multiple `llb.Local` operations on the // Without hint, multiple `llb.Local` operations on the

21
tests/ignore/main.cue Normal file
View File

@ -0,0 +1,21 @@
package main
import (
"dagger.io/dagger"
"dagger.io/llb"
)
dir: dagger.#Artifact
ignore: {
string
#compute: [
llb.#FetchContainer & { ref: "debian:buster" },
llb.#Exec & {
args: ["bash", "-c", "ls -lh /src > /out.txt"]
mount: "/src": { from: dir }
},
llb.#Export & { source: "/out.txt" },
]
}