implements dagger do
Signed-off-by: Richard Jones <richard@dagger.io>
This commit is contained in:
parent
621edd6b2f
commit
6cdf13223c
140
cmd/dagger/cmd/do.go
Normal file
140
cmd/dagger/cmd/do.go
Normal file
@ -0,0 +1,140 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/plan"
|
||||
"go.dagger.io/dagger/solver"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var doCmd = &cobra.Command{
|
||||
Use: "do [OPTIONS] ACTION [SUBACTION...]",
|
||||
Short: "Execute a dagger action.",
|
||||
// Args: cobra.MinimumNArgs(1),
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
// Fix Viper bug for duplicate flags:
|
||||
// https://github.com/spf13/viper/issues/233
|
||||
if err := viper.BindPFlags(cmd.Flags()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) < 1 {
|
||||
doHelp(cmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
lg = logger.New()
|
||||
tty *logger.TTYOutput
|
||||
err error
|
||||
)
|
||||
|
||||
if f := viper.GetString("log-format"); f == "tty" || f == "auto" && term.IsTerminal(int(os.Stdout.Fd())) {
|
||||
tty, err = logger.NewTTYOutput(os.Stderr)
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to initialize TTY logger")
|
||||
}
|
||||
tty.Start()
|
||||
defer tty.Stop()
|
||||
|
||||
lg = lg.Output(tty)
|
||||
}
|
||||
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
cl := common.NewClient(ctx)
|
||||
|
||||
p, err := loadPlan(getTargetPath(args).String())
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to load plan")
|
||||
}
|
||||
|
||||
err = cl.Do(ctx, p.Context(), func(ctx context.Context, s solver.Solver) error {
|
||||
_, err := p.Up(ctx, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
// FIXME: rework telemetry
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to up environment")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func loadPlan(target string) (*plan.Plan, error) {
|
||||
project := viper.GetString("project")
|
||||
return plan.Load(context.Background(), plan.Config{
|
||||
Args: []string{project},
|
||||
With: viper.GetStringSlice("with"),
|
||||
Target: target,
|
||||
Vendor: !viper.GetBool("no-vendor"),
|
||||
})
|
||||
}
|
||||
|
||||
func getTargetPath(args []string) cue.Path {
|
||||
actionLookupArgs := []string{plan.ActionsPath}
|
||||
actionLookupArgs = append(actionLookupArgs, args...)
|
||||
actionLookupSelectors := []cue.Selector{}
|
||||
for _, a := range actionLookupArgs {
|
||||
actionLookupSelectors = append(actionLookupSelectors, cue.Str(a))
|
||||
}
|
||||
return cue.MakePath(actionLookupSelectors...)
|
||||
}
|
||||
|
||||
func doHelp(cmd *cobra.Command, _ []string) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.StripEscape)
|
||||
defer w.Flush()
|
||||
|
||||
p, err := loadPlan("")
|
||||
if err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
fmt.Fprintln(w, "failed to load plan")
|
||||
return
|
||||
}
|
||||
project := viper.GetString("project")
|
||||
actionLookupPath := getTargetPath(cmd.Flags().Args())
|
||||
actions := p.Action().FindByPath(actionLookupPath).Children
|
||||
|
||||
fmt.Printf(`Execute a dagger action.
|
||||
|
||||
%s
|
||||
|
||||
Plan loaded from %s:
|
||||
%s
|
||||
`, cmd.UsageString(), project, "\n"+actionLookupPath.String()+":")
|
||||
|
||||
// fmt.Fprintln(w, "Actions\tDescription\tPackage")
|
||||
// fmt.Fprintln(w, "\t\t")
|
||||
for _, a := range actions {
|
||||
if !a.Hidden {
|
||||
lineParts := []string{"", a.Name, strings.TrimSpace(a.Comment)}
|
||||
fmt.Fprintln(w, strings.Join(lineParts, "\t"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
doCmd.Flags().StringArrayP("with", "w", []string{}, "")
|
||||
doCmd.Flags().Bool("no-vendor", false, "Force up, disable inputs check")
|
||||
|
||||
doCmd.SetHelpFunc(doHelp)
|
||||
|
||||
if err := viper.BindPFlags(doCmd.Flags()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringArray("cache-from", []string{},
|
||||
"External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
|
||||
|
||||
rootCmd.PersistentFlags().String("project", "", "Specify a project directory (defaults to current)")
|
||||
rootCmd.PersistentFlags().StringP("project", "p", "./", "Specify a project directory (defaults to current)")
|
||||
|
||||
rootCmd.PersistentPreRun = func(cmd *cobra.Command, _ []string) {
|
||||
go checkVersion()
|
||||
@ -45,6 +45,7 @@ func init() {
|
||||
versionCmd,
|
||||
docCmd,
|
||||
mod.Cmd,
|
||||
doCmd,
|
||||
)
|
||||
|
||||
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
|
||||
|
34
plan/action.go
Normal file
34
plan/action.go
Normal file
@ -0,0 +1,34 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"cuelang.org/go/cue"
|
||||
)
|
||||
|
||||
type Action struct {
|
||||
Name string
|
||||
Hidden bool
|
||||
Path cue.Path
|
||||
Comment string
|
||||
Children []*Action
|
||||
// pkg string
|
||||
}
|
||||
|
||||
func (a *Action) AddChild(c *Action) {
|
||||
a.Children = append(a.Children, c)
|
||||
}
|
||||
|
||||
func (a *Action) FindByPath(path cue.Path) *Action {
|
||||
queue := []*Action{a}
|
||||
|
||||
for len(queue) > 0 {
|
||||
nextUp := queue[0]
|
||||
queue = queue[1:]
|
||||
if nextUp.Path.String() == path.String() {
|
||||
return nextUp
|
||||
}
|
||||
if len(nextUp.Children) > 0 {
|
||||
queue = append(queue, nextUp.Children...)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
83
plan/plan.go
83
plan/plan.go
@ -17,11 +17,16 @@ import (
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
const (
|
||||
ActionsPath = "actions"
|
||||
)
|
||||
|
||||
type Plan struct {
|
||||
config Config
|
||||
|
||||
context *plancontext.Context
|
||||
source *compiler.Value
|
||||
action *Action
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@ -66,6 +71,8 @@ func Load(ctx context.Context, cfg Config) (*Plan, error) {
|
||||
source: v,
|
||||
}
|
||||
|
||||
p.fillAction()
|
||||
|
||||
if err := p.configPlatform(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -85,6 +92,10 @@ func (p *Plan) Source() *compiler.Value {
|
||||
return p.source
|
||||
}
|
||||
|
||||
func (p *Plan) Action() *Action {
|
||||
return p.action
|
||||
}
|
||||
|
||||
// configPlatform load the platform specified in the context
|
||||
// Buildkit will then run every operation using that platform
|
||||
// If platform is not define, context keep default platform
|
||||
@ -186,6 +197,78 @@ func (p *Plan) Up(ctx context.Context, s solver.Solver) (*compiler.Value, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plan) fillAction() {
|
||||
cfg := &cueflow.Config{
|
||||
FindHiddenTasks: true,
|
||||
Root: cue.ParsePath(ActionsPath),
|
||||
}
|
||||
|
||||
flow := cueflow.New(
|
||||
cfg,
|
||||
p.source.Cue(),
|
||||
noOpRunner,
|
||||
)
|
||||
|
||||
actions := p.source.Lookup(ActionsPath)
|
||||
actionsComment := ""
|
||||
for _, cg := range actions.Doc() {
|
||||
actionsComment += cg.Text()
|
||||
}
|
||||
p.action = &Action{
|
||||
ActionsPath,
|
||||
false,
|
||||
actions.Path(),
|
||||
actionsComment,
|
||||
[]*Action{},
|
||||
}
|
||||
|
||||
tasks := flow.Tasks()
|
||||
|
||||
for _, t := range tasks {
|
||||
var q []cue.Selector
|
||||
prevAction := p.action
|
||||
for _, s := range t.Path().Selectors() {
|
||||
q = append(q, s)
|
||||
path := cue.MakePath(q...)
|
||||
a := prevAction.FindByPath(path)
|
||||
if a == nil {
|
||||
v := p.Source().LookupPath(path)
|
||||
childComment := ""
|
||||
for _, cg := range v.Doc() {
|
||||
childComment += cg.Text()
|
||||
}
|
||||
|
||||
a = &Action{
|
||||
s.String(),
|
||||
s.PkgPath() != "",
|
||||
path,
|
||||
childComment,
|
||||
[]*Action{},
|
||||
}
|
||||
prevAction.AddChild(a)
|
||||
}
|
||||
prevAction = a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func noOpRunner(flowVal cue.Value) (cueflow.Runner, error) {
|
||||
v := compiler.Wrap(flowVal)
|
||||
_, err := task.Lookup(v)
|
||||
if err != nil {
|
||||
// Not a task
|
||||
if err == task.ErrNotTask {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Wrapper around `task.Run` that handles logging, tracing, etc.
|
||||
return cueflow.RunnerFunc(func(t *cueflow.Task) error {
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func newRunner(pctx *plancontext.Context, s solver.Solver, computed *compiler.Value) cueflow.TaskFunc {
|
||||
return func(flowVal cue.Value) (cueflow.Runner, error) {
|
||||
v := compiler.Wrap(flowVal)
|
||||
|
115
tests/plan.bats
115
tests/plan.bats
@ -7,154 +7,77 @@ setup() {
|
||||
@test "plan/hello" {
|
||||
# Europa loader handles the cwd differently, therefore we need to CD into the tree at or below the parent of cue.mod
|
||||
cd "$TESTDIR"
|
||||
"$DAGGER" up ./plan/hello-europa
|
||||
"$DAGGER" "do" -p ./plan/hello-europa test
|
||||
}
|
||||
|
||||
@test "plan/proxy invalid schema" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/proxy/invalid_schema.cue
|
||||
run "$DAGGER" "do" -p ./plan/proxy/invalid_schema.cue verify
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "plan/proxy invalid value" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/proxy/invalid_value.cue
|
||||
run "$DAGGER" "do" -p ./plan/proxy/invalid_value.cue verify
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "plan/proxy incomplete unix" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/proxy/incomplete_unix.cue
|
||||
run "$DAGGER" "do" -p ./plan/proxy/incomplete_unix.cue verify
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "plan/proxy incomplete service" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/proxy/incomplete_service.cue
|
||||
run "$DAGGER" "do" -p ./plan/proxy/incomplete_service.cue verify
|
||||
assert_output --partial 'mount "docker" is not concrete'
|
||||
}
|
||||
|
||||
@test "plan/proxy unix" {
|
||||
cd "$TESTDIR"
|
||||
"$DAGGER" up ./plan/proxy/unix.cue
|
||||
"$DAGGER" "do" -p ./plan/proxy/unix.cue verify
|
||||
}
|
||||
|
||||
@test "plan/inputs/directories exists" {
|
||||
@test "plan/inputs/directories" {
|
||||
cd "$TESTDIR"
|
||||
"$DAGGER" up ./plan/inputs/directories/exists.cue
|
||||
}
|
||||
"$DAGGER" "do" -p ./plan/inputs/directories/valid exists
|
||||
|
||||
@test "plan/inputs/directories relative directories" {
|
||||
cd "$TESTDIR"
|
||||
cd "$TESTDIR"/plan/inputs
|
||||
|
||||
"$DAGGER" up ./directories/exists.cue
|
||||
}
|
||||
|
||||
@test "plan/inputs/directories not exists" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/inputs/directories/not_exists.cue
|
||||
run "$DAGGER" "do" -p ./plan/inputs/directories/invalid notExists
|
||||
assert_failure
|
||||
assert_output --partial 'fasdfsdfs" does not exist'
|
||||
}
|
||||
|
||||
@test "plan/inputs/directories conflicting values" {
|
||||
cd "$TESTDIR"
|
||||
run "$DAGGER" up ./plan/inputs/directories/conflicting_values.cue
|
||||
run "$DAGGER" "do" -p ./plan/inputs/directories/valid conflictingValues
|
||||
assert_failure
|
||||
assert_output --partial 'conflicting values "local directory" and "local dfsadf"'
|
||||
}
|
||||
|
||||
@test "plan/inputs/secrets" {
|
||||
cd "$TESTDIR"
|
||||
"$DAGGER" up ./plan/inputs/secrets/exec.cue
|
||||
"$DAGGER" up ./plan/inputs/secrets/exec_relative.cue
|
||||
"$DAGGER" "do" -p ./plan/inputs/secrets test valid
|
||||
"$DAGGER" "do" -p ./plan/inputs/secrets test relative
|
||||
|
||||
run "$DAGGER" up ./plan/inputs/secrets/invalid_command.cue
|
||||
run "$DAGGER" "do" -p ./plan/inputs/secrets test badCommand
|
||||
assert_failure
|
||||
assert_output --partial 'failed: exec: "rtyet": executable file not found'
|
||||
|
||||
run "$DAGGER" up ./plan/inputs/secrets/invalid_command_options.cue
|
||||
run "$DAGGER" "do" -p ./plan/inputs/secrets test badArgs
|
||||
assert_failure
|
||||
assert_output --partial 'option'
|
||||
}
|
||||
|
||||
@test "plan/with" {
|
||||
cd "$TESTDIR"
|
||||
"$DAGGER" up --with 'inputs: params: foo:"bar"' ./plan/with/params.cue
|
||||
"$DAGGER" up --with 'actions: verify: env: FOO: "bar"' ./plan/with/actions.cue
|
||||
"$DAGGER" "do" --with 'inputs: params: foo:"bar"' -p ./plan/with test params
|
||||
"$DAGGER" "do" --with 'actions: test: direct: env: FOO: "bar"' -p ./plan/with test direct
|
||||
|
||||
run "$DAGGER" up --with 'inputs: params: foo:1' ./plan/with/params.cue
|
||||
run "$DAGGER" "do" --with 'inputs: params: foo:1' -p ./plan/with test params
|
||||
assert_failure
|
||||
assert_output --partial "conflicting values string and 1"
|
||||
|
||||
run "$DAGGER" up ./plan/with/params.cue
|
||||
run "$DAGGER" "do" -p ./plan/with test params
|
||||
assert_failure
|
||||
assert_output --partial "actions.verify.env.FOO: non-concrete value string"
|
||||
}
|
||||
|
||||
@test "plan/outputs/directories" {
|
||||
cd "$TESTDIR"/plan/outputs/directories
|
||||
|
||||
"$DAGGER" up ./outputs.cue
|
||||
assert [ -f "./out/test_outputs" ]
|
||||
|
||||
rm -f "./out/test_outputs"
|
||||
}
|
||||
|
||||
@test "plan/outputs/directories relative paths" {
|
||||
cd "$TESTDIR"/plan
|
||||
|
||||
"$DAGGER" up ./outputs/directories/relative.cue
|
||||
assert [ -f "./outputs/directories/out/test_relative" ]
|
||||
|
||||
rm -f "./outputs/directories/out/test_relative"
|
||||
}
|
||||
|
||||
@test "plan/outputs/files normal usage" {
|
||||
cd "$TESTDIR"/plan/outputs/files
|
||||
|
||||
"$DAGGER" up ./usage.cue
|
||||
|
||||
run ./test_usage
|
||||
assert_output "Hello World!"
|
||||
|
||||
run ls -l "./test_usage"
|
||||
assert_output --partial "-rwxr-x---"
|
||||
|
||||
rm -f "./test_usage"
|
||||
}
|
||||
|
||||
@test "plan/outputs/files relative path" {
|
||||
cd "$TESTDIR"/plan
|
||||
|
||||
"$DAGGER" up ./outputs/files/relative.cue
|
||||
assert [ -f "./outputs/files/test_relative" ]
|
||||
|
||||
rm -f "./outputs/files/test_relative"
|
||||
}
|
||||
|
||||
@test "plan/outputs/files default permissions" {
|
||||
cd "$TESTDIR"/plan/outputs/files
|
||||
|
||||
"$DAGGER" up ./default_permissions.cue
|
||||
|
||||
run ls -l "./test_default_permissions"
|
||||
assert_output --partial "-rw-r--r--"
|
||||
|
||||
rm -f "./test_default_permissions"
|
||||
}
|
||||
|
||||
@test "plan/outputs/files no contents" {
|
||||
cd "$TESTDIR"/plan/outputs/files
|
||||
|
||||
run "$DAGGER" up ./no_contents.cue
|
||||
assert_failure
|
||||
assert_output --partial "contents is not set"
|
||||
|
||||
assert [ ! -f "./test_no_contents" ]
|
||||
|
||||
rm -f "./test_no_contents"
|
||||
assert_output --partial "actions.test.params.env.FOO: non-concrete value string"
|
||||
}
|
||||
|
||||
@test "plan/platform" {
|
||||
|
74
tests/plan/do/actions.cue
Normal file
74
tests/plan/do/actions.cue
Normal file
@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
"universe.dagger.io/yarn"
|
||||
"universe.dagger.io/docker"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
|
||||
// All the things!
|
||||
actions: {
|
||||
|
||||
// Run core integration tests
|
||||
"core-integration": _
|
||||
|
||||
// Format all cue files
|
||||
cuefmt: _
|
||||
|
||||
// Lint and format all cue files
|
||||
cuelint: _
|
||||
|
||||
// Build a debug version of the dev dagger binary
|
||||
"dagger-debug": _
|
||||
|
||||
// Test docs
|
||||
"doc-test": _
|
||||
|
||||
// Generate docs
|
||||
docs: _
|
||||
|
||||
// Generate & lint docs
|
||||
docslint: _
|
||||
|
||||
// Run Europa universe tests
|
||||
"europa-universe-test": _
|
||||
|
||||
// Go lint
|
||||
golint: _
|
||||
|
||||
// Show how to get started & what targets are available
|
||||
help: _
|
||||
|
||||
// Install a dev dagger binary
|
||||
install: _
|
||||
|
||||
// Run all integration tests
|
||||
integration: _
|
||||
|
||||
// Lint everything
|
||||
lint: _
|
||||
|
||||
// Run shellcheck
|
||||
shellcheck: _
|
||||
|
||||
// Run all tests
|
||||
test: _
|
||||
|
||||
// Find all TODO items
|
||||
todo: _
|
||||
|
||||
// Run universe tests
|
||||
"universe-test": _
|
||||
|
||||
// Build, test and deploy frontend web client
|
||||
frontend: {
|
||||
// Build via yarn
|
||||
build: yarn.#Build
|
||||
|
||||
// Test via headless browser
|
||||
test: docker.#Run
|
||||
}
|
||||
}
|
||||
}
|
@ -6,18 +6,18 @@ import (
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
actions: {
|
||||
image: dagger.#Pull & {
|
||||
actions: test: {
|
||||
_image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
exec: dagger.#Exec & {
|
||||
input: image.output
|
||||
_exec: dagger.#Exec & {
|
||||
input: _image.output
|
||||
args: ["sh", "-c", "echo -n Hello Europa > /out.txt"]
|
||||
}
|
||||
|
||||
verify: dagger.#ReadFile & {
|
||||
input: exec.output
|
||||
_verify: dagger.#ReadFile & {
|
||||
input: _exec.output
|
||||
path: "/out.txt"
|
||||
} & {
|
||||
// assert result
|
||||
|
@ -1,15 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: directories: test: path: "."
|
||||
actions: verify: dagger.#ReadFile & {
|
||||
input: inputs.directories.test.contents
|
||||
path: "test.txt"
|
||||
} & {
|
||||
contents: "local dfsadf" // should fail with conflicting values
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: directories: test: path: "."
|
||||
actions: verify: dagger.#ReadFile & {
|
||||
input: inputs.directories.test.contents
|
||||
path: "test.txt"
|
||||
} & {
|
||||
contents: "local directory"
|
||||
}
|
||||
}
|
3
tests/plan/inputs/directories/invalid/invalid.cue
Normal file
3
tests/plan/inputs/directories/invalid/invalid.cue
Normal file
@ -0,0 +1,3 @@
|
||||
package main
|
||||
|
||||
inputs: directories: test: path: "./fasdfsdfs"
|
31
tests/plan/inputs/directories/main.cue
Normal file
31
tests/plan/inputs/directories/main.cue
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: directories: test: path: string
|
||||
|
||||
actions: {
|
||||
_readFile: dagger.#ReadFile & {
|
||||
input: inputs.directories.test.contents
|
||||
path: "test.txt"
|
||||
}
|
||||
|
||||
// Test that file exists and contains correct content
|
||||
exists: _readFile & {
|
||||
contents: "local directory"
|
||||
}
|
||||
|
||||
// Test that file does NOT exist
|
||||
notExists: _readFile & {
|
||||
contents: "local directory"
|
||||
}
|
||||
|
||||
// Test that file exists and contains conflicting content
|
||||
conflictingValues: _readFile & {
|
||||
contents: "local dfsadf"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
// should fail because path does not exist locally
|
||||
inputs: directories: test: path: "./fasdfsdfs"
|
||||
actions: verify: dagger.#ReadFile & {
|
||||
input: inputs.directories.test.contents
|
||||
path: "test.txt"
|
||||
} & {
|
||||
contents: "local directory"
|
||||
}
|
||||
}
|
3
tests/plan/inputs/directories/valid/valid.cue
Normal file
3
tests/plan/inputs/directories/valid/valid.cue
Normal file
@ -0,0 +1,3 @@
|
||||
package main
|
||||
|
||||
inputs: directories: test: path: "."
|
@ -1,34 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: secrets: echo: command: {
|
||||
name: "echo"
|
||||
args: ["hello europa"]
|
||||
}
|
||||
|
||||
actions: {
|
||||
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/test"
|
||||
contents: inputs.secrets.echo.contents
|
||||
}
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$(cat /run/secrets/test)" = "hello europa"
|
||||
ls -l /run/secrets/test | grep -- "-r--------"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: secrets: echo: command: {
|
||||
name: "cat"
|
||||
args: ["./test.txt"]
|
||||
}
|
||||
|
||||
actions: {
|
||||
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/test"
|
||||
contents: inputs.secrets.echo.contents
|
||||
}
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$(cat /run/secrets/test)" = "test"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: secrets: echo: command: {
|
||||
name: "rtyet" // should fail because command doesn't exist
|
||||
args: ["hello europa"]
|
||||
}
|
||||
|
||||
actions: {
|
||||
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/test"
|
||||
contents: inputs.secrets.echo.contents
|
||||
}
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$(cat /run/secrets/test)" = "hello europa"
|
||||
ls -l /run/secrets/test | grep -- "-r--------"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: secrets: echo: command: {
|
||||
name: "cat"
|
||||
args: ["--sfgjkhf"] // // should fail because invalid option
|
||||
}
|
||||
|
||||
actions: {
|
||||
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/test"
|
||||
contents: inputs.secrets.echo.contents
|
||||
}
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$(cat /run/secrets/test)" = "hello europa"
|
||||
ls -l /run/secrets/test | grep -- "-r--------"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
59
tests/plan/inputs/secrets/secrets.cue
Normal file
59
tests/plan/inputs/secrets/secrets.cue
Normal file
@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: secrets: {
|
||||
echo: command: {
|
||||
name: "echo"
|
||||
args: ["hello europa"]
|
||||
}
|
||||
|
||||
relative: command: {
|
||||
name: "cat"
|
||||
args: ["./test.txt"]
|
||||
}
|
||||
|
||||
badCommand: command: {
|
||||
name: "rtyet" // should fail because command doesn't exist
|
||||
args: ["hello europa"]
|
||||
}
|
||||
|
||||
badArgs: command: {
|
||||
name: "cat"
|
||||
args: ["--sfgjkhf"] // // should fail because invalid option
|
||||
}
|
||||
}
|
||||
|
||||
actions: {
|
||||
|
||||
_image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
test: {
|
||||
|
||||
[string]: dagger.#Exec & {
|
||||
input: _image.output
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/test"
|
||||
// contents: inputs.secrets.echo.contents
|
||||
}
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$(cat /run/secrets/test)" = "hello europa"
|
||||
ls -l /run/secrets/test | grep -- "-r--------"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
|
||||
valid: mounts: secret: contents: inputs.secrets.echo.contents
|
||||
relative: mounts: secret: contents: inputs.secrets.relative.contents
|
||||
badCommand: mounts: secret: contents: inputs.secrets.badCommand.contents
|
||||
badArgs: mounts: secret: contents: inputs.secrets.badArgs.contents
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
test
|
||||
hello europa
|
@ -1,25 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
|
||||
actions: {
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
env: FOO: string
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test -n "$FOO"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: params: foo: string
|
||||
|
||||
actions: {
|
||||
image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
verify: dagger.#Exec & {
|
||||
input: image.output
|
||||
env: FOO: inputs.params.foo
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test "$FOO" = "bar"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
31
tests/plan/with/with.cue
Normal file
31
tests/plan/with/with.cue
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
dagger.#Plan & {
|
||||
inputs: params: foo: string
|
||||
|
||||
actions: {
|
||||
_image: dagger.#Pull & {
|
||||
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||
}
|
||||
|
||||
test: {
|
||||
[string]: dagger.#Exec & {
|
||||
input: _image.output
|
||||
env: FOO: string
|
||||
args: [
|
||||
"sh", "-c",
|
||||
#"""
|
||||
test -n "$FOO"
|
||||
"""#,
|
||||
]
|
||||
}
|
||||
|
||||
direct: {}
|
||||
params: env: FOO: inputs.params.foo
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user