diff --git a/plan/task/copy.go b/plan/task/copy.go new file mode 100644 index 00000000..ff79e3c2 --- /dev/null +++ b/plan/task/copy.go @@ -0,0 +1,92 @@ +package task + +import ( + "context" + "fmt" + + "cuelang.org/go/cue" + "github.com/moby/buildkit/client/llb" + "go.dagger.io/dagger/compiler" + "go.dagger.io/dagger/plancontext" + "go.dagger.io/dagger/solver" +) + +func init() { + Register("Copy", func() Task { return ©Task{} }) +} + +type copyTask struct { +} + +func (t *copyTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) { + var err error + + input, err := pctx.FS.FromValue(v.Lookup("input")) + + if err != nil { + return nil, err + } + + inputState, err := input.Result().ToState() + + if err != nil { + return nil, err + } + + sourceRoot, err := pctx.FS.FromValue(v.Lookup("source.root")) + + if err != nil { + return nil, err + } + + sourceState, err := sourceRoot.Result().ToState() + + if err != nil { + return nil, err + } + + sourcePath, err := v.Lookup("source.path").String() + fmt.Println(sourcePath) + + if err != nil { + return nil, err + } + + destPath, err := v.Lookup("dest").String() + + if err != nil { + return nil, err + } + + outputState := inputState.File( + llb.Copy( + sourceState, + sourcePath, + destPath, + // FIXME: allow more configurable llb options + // For now we define the following convenience presets: + &llb.CopyInfo{ + CopyDirContentsOnly: true, + CreateDestPath: true, + AllowWildcard: true, + }, + ), + withCustomName(v, "Copy %s %s", sourcePath, destPath), + ) + + result, err := s.Solve(ctx, outputState, pctx.Platform.Get()) + + if err != nil { + return nil, err + } + + fs := pctx.FS.New(result) + + output := compiler.NewValue() + + if err := output.FillPath(cue.ParsePath("output"), fs.MarshalCUE()); err != nil { + return nil, err + } + + return output, nil +} diff --git a/stdlib/europa/dagger/engine/fs.cue b/stdlib/europa/dagger/engine/fs.cue index 0b68d09d..ee5fd875 100644 --- a/stdlib/europa/dagger/engine/fs.cue +++ b/stdlib/europa/dagger/engine/fs.cue @@ -84,3 +84,19 @@ package engine layers: [...#CopyInfo] output: #FS } + +#Copy: { + _type: "Copy" + + input: #FS + #CopyInfo + output: #FS +} + +#CopyInfo: { + source: { + root: #FS + path: string | *"/" + } + dest: string +} diff --git a/tests/tasks.bats b/tests/tasks.bats index e6a8c398..93f74820 100644 --- a/tests/tasks.bats +++ b/tests/tasks.bats @@ -46,3 +46,12 @@ setup() { "$DAGGER" --europa up ./user.cue "$DAGGER" --europa up ./workdir.cue } + +@test "task: #Copy" { + cd "$TESTDIR"/tasks/copy + "$DAGGER" --europa up ./copy_exec.cue + "$DAGGER" --europa up ./copy_file.cue + + run "$DAGGER" --europa up ./copy_exec_invalid.cue + assert_failure +} diff --git a/tests/tasks/copy/copy_exec.cue b/tests/tasks/copy/copy_exec.cue new file mode 100644 index 00000000..ed0d8468 --- /dev/null +++ b/tests/tasks/copy/copy_exec.cue @@ -0,0 +1,47 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" +) + +engine.#Plan & { + actions: { + image: engine.#Pull & { + source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3" + } + + exec: engine.#Exec & { + input: image.output + args: [ + "sh", "-c", + #""" + echo -n hello world > /output.txt + """#, + ] + } + + verify_file: engine.#ReadFile & { + input: exec.output + path: "/output.txt" + } & { + // assert result + contents: "hello world" + } + + copy: engine.#Copy & { + input: image.output + source: { + root: exec.output + path: "/output.txt" + } + dest: "/output.txt" + } + verify_copy: engine.#ReadFile & { + input: copy.output + path: "/output.txt" + } & { + // assert result + contents: "hello world" + } + } +} diff --git a/tests/tasks/copy/copy_exec_invalid.cue b/tests/tasks/copy/copy_exec_invalid.cue new file mode 100644 index 00000000..1ad17fe3 --- /dev/null +++ b/tests/tasks/copy/copy_exec_invalid.cue @@ -0,0 +1,47 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" +) + +engine.#Plan & { + actions: { + image: engine.#Pull & { + source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3" + } + + exec: engine.#Exec & { + input: image.output + args: [ + "sh", "-c", + #""" + echo -n hello world from dagger > /output.txt + """#, + ] + } + + verify_file: engine.#ReadFile & { + input: exec.output + path: "/output.txt" + } & { + // assert result + contents: "hello world from dagger" + } + + copy: engine.#Copy & { + input: image.output + source: { + root: exec.output + path: "/output.txt" + } + dest: "/output.txt" + } + verify_copy: engine.#ReadFile & { + input: copy.output + path: "/output.txt" + } & { + // assert result + contents: "hello world" + } + } +} diff --git a/tests/tasks/copy/copy_file.cue b/tests/tasks/copy/copy_file.cue new file mode 100644 index 00000000..b860caa3 --- /dev/null +++ b/tests/tasks/copy/copy_file.cue @@ -0,0 +1,42 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" +) + +engine.#Plan & { + actions: { + alpine3_15_0: engine.#Pull & { + source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3" + } + + busybox1_34_1: engine.#Pull & { + source: "busybox:1.34.1-glibc@sha256:ec98391b8f0911db08be2ee6c46813eeac17b9625b402ea1ce45dcfcd05d78d6" + } + + verify_alpine_3_15_0: engine.#ReadFile & { + input: alpine3_15_0.output + path: "/etc/alpine-release" + } & { + // assert result + contents: "3.15.0\n" + } + + copy: engine.#Copy & { + input: busybox1_34_1.output + source: { + root: alpine3_15_0.output + path: "/etc/alpine-release" + } + dest: "/alpine3_15_0_release" + } + + verify_copy: engine.#ReadFile & { + input: copy.output + path: "/alpine3_15_0_release" + } & { + // assert result + contents: "3.15.0\n" + } + } +} diff --git a/tests/tasks/copy/cue.mod/module.cue b/tests/tasks/copy/cue.mod/module.cue new file mode 100644 index 00000000..f8af9cef --- /dev/null +++ b/tests/tasks/copy/cue.mod/module.cue @@ -0,0 +1 @@ +module: "" diff --git a/tests/tasks/copy/cue.mod/pkg/.gitignore b/tests/tasks/copy/cue.mod/pkg/.gitignore new file mode 100644 index 00000000..2d4dc1ae --- /dev/null +++ b/tests/tasks/copy/cue.mod/pkg/.gitignore @@ -0,0 +1,3 @@ +# generated by dagger +alpha.dagger.io +dagger.lock