Add outputs.files task to plan

Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
This commit is contained in:
Helder Correia 2022-01-30 23:08:16 -01:00
parent 025ce14ed3
commit 813a476e06
No known key found for this signature in database
GPG Key ID: C6490D872EF1DCA7
8 changed files with 169 additions and 12 deletions

View File

@ -17,8 +17,10 @@ package engine
// Send outputs to the client // Send outputs to the client
outputs: { outputs: {
@dagger(notimplemented) // Export an #FS to the client
directories: [name=string]: _#outputDirectory directories: [name=string]: _#outputDirectory
// Export a string to a file
files: [name=string]: _#outputFile
} }
// Forward network services to and from the client // Forward network services to and from the client
@ -110,6 +112,19 @@ _#outputDirectory: {
dest: string dest: string
} }
_#outputFile: {
$dagger: task: _name: "OutputFile"
// File contents to export
contents: string
// Export to this path ON THE CLIENT MACHINE
dest: string
// Permissions of the file (defaults to 0o644)
permissions?: int
}
// Forward a network endpoint to and from the client // Forward a network endpoint to and from the client
_#proxyEndpoint: { _#proxyEndpoint: {
$dagger: task: _name: "ProxyEndpoint" $dagger: task: _name: "ProxyEndpoint"

63
plan/task/outputfile.go Normal file
View File

@ -0,0 +1,63 @@
package task
import (
"context"
"fmt"
"io/fs"
"os"
"cuelang.org/go/cue"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("OutputFile", func() Task { return &outputFileTask{} })
}
type outputFileTask struct {
}
func (c outputFileTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
var contents []byte
var err error
switch kind := v.Lookup("contents").Kind(); kind {
case cue.StringKind:
var str string
str, err = v.Lookup("contents").String()
if err == nil {
contents = []byte(str)
}
case cue.BottomKind:
err = fmt.Errorf("contents is not set")
default:
err = fmt.Errorf("unhandled data type in contents: %s", kind)
}
if err != nil {
return nil, err
}
dest, err := v.Lookup("dest").AbsPath()
if err != nil {
return nil, err
}
perm := fs.FileMode(0644) // default permission
if v.Lookup("permissions").Exists() {
permissions, err := v.Lookup("permissions").Int64()
if err != nil {
return nil, err
}
perm = fs.FileMode(permissions)
}
err = os.WriteFile(dest, contents, perm)
if err != nil {
return nil, err
}
return compiler.NewValue(), nil
}

View File

@ -69,11 +69,11 @@ setup() {
cd "$TESTDIR" cd "$TESTDIR"
"$DAGGER" --europa up ./plan/inputs/secrets/exec.cue "$DAGGER" --europa up ./plan/inputs/secrets/exec.cue
"$DAGGER" --europa up ./plan/inputs/secrets/exec_relative.cue "$DAGGER" --europa up ./plan/inputs/secrets/exec_relative.cue
run "$DAGGER" --europa up ./plan/inputs/secrets/invalid_command.cue run "$DAGGER" --europa up ./plan/inputs/secrets/invalid_command.cue
assert_failure assert_failure
assert_output --partial 'failed: exec: "rtyet": executable file not found' assert_output --partial 'failed: exec: "rtyet": executable file not found'
run "$DAGGER" --europa up ./plan/inputs/secrets/invalid_command_options.cue run "$DAGGER" --europa up ./plan/inputs/secrets/invalid_command_options.cue
assert_failure assert_failure
assert_output --partial 'option' assert_output --partial 'option'
@ -83,30 +83,74 @@ setup() {
cd "$TESTDIR" cd "$TESTDIR"
"$DAGGER" --europa up --with 'inputs: params: foo:"bar"' ./plan/with/params.cue "$DAGGER" --europa up --with 'inputs: params: foo:"bar"' ./plan/with/params.cue
"$DAGGER" --europa up --with 'actions: verify: env: FOO: "bar"' ./plan/with/actions.cue "$DAGGER" --europa up --with 'actions: verify: env: FOO: "bar"' ./plan/with/actions.cue
run "$DAGGER" --europa up --with 'inputs: params: foo:1' ./plan/with/params.cue run "$DAGGER" --europa up --with 'inputs: params: foo:1' ./plan/with/params.cue
assert_failure assert_failure
assert_output --partial "conflicting values string and 1" assert_output --partial "conflicting values string and 1"
run "$DAGGER" --europa up ./plan/with/params.cue run "$DAGGER" --europa up ./plan/with/params.cue
assert_failure assert_failure
assert_output --partial "actions.verify.env.FOO: non-concrete value string" assert_output --partial "actions.verify.env.FOO: non-concrete value string"
} }
@test "plan/outputs" { @test "plan/outputs/directories" {
cd "$TESTDIR"/plan/outputs cd "$TESTDIR"/plan/outputs/directories
rm -f "./out/test" rm -f "./out/test"
"$DAGGER" --europa up ./outputs.cue "$DAGGER" --europa up ./outputs.cue
assert [ -f "./out/test" ] assert [ -f "./out/test" ]
} }
@test "plan/outputs relative paths" { @test "plan/outputs/directories relative paths" {
cd "$TESTDIR"/plan cd "$TESTDIR"/plan
rm -f "./outputs/out/test" rm -f "./outputs/directories/out/test"
"$DAGGER" --europa up ./outputs/outputs.cue "$DAGGER" --europa up ./outputs/directories/outputs.cue
assert [ -f "./outputs/out/test" ] assert [ -f "./outputs/directories/out/test" ]
}
@test "plan/outputs/files normal usage" {
cd "$TESTDIR"/plan/outputs/files
"$DAGGER" --europa up ./usage.cue
run ./test.sh
assert_output "Hello World!"
run ls -l "./test.sh"
assert_output --partial "-rwxr-x---"
rm -f "./test.sh"
}
@test "plan/outputs/files relative path" {
cd "$TESTDIR"/plan
"$DAGGER" --europa up ./outputs/files/usage.cue
assert [ -f "./outputs/files/test.sh" ]
rm -f "./outputs/files/test.sh"
}
@test "plan/outputs/files default permissions" {
cd "$TESTDIR"/plan/outputs/files
"$DAGGER" --europa up ./default_permissions.cue
run ls -l "./test"
assert_output --partial "-rw-r--r--"
rm -f "./test"
}
@test "plan/outputs/files no contents" {
cd "$TESTDIR"/plan/outputs/files
run "$DAGGER" --europa up ./no_contents.cue
assert_failure
assert_output --partial "contents is not set"
assert [ ! -f "./test" ]
} }
@test "plan/platform" { @test "plan/platform" {
@ -121,4 +165,4 @@ setup() {
# Run with invalid platform # Run with invalid platform
run "$DAGGER" --europa up ./plan/platform/config_platform_failure_invalid_platform.cue run "$DAGGER" --europa up ./plan/platform/config_platform_failure_invalid_platform.cue
assert_failure assert_failure
} }

View File

@ -0,0 +1,10 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: test: {
contents: "foobar"
dest: "./test"
}
}

View File

@ -0,0 +1,7 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: test: dest: "./test"
}

View File

@ -0,0 +1,18 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: {
[path=string]: dest: path
"test.sh": {
contents: """
#!/bin/bash
set -euo pipefail
echo "Hello World!"
"""
permissions: 0o750
}
}
}