2021-01-30 02:16:22 +01:00
|
|
|
package dagger
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2021-04-03 02:14:01 +02:00
|
|
|
"path/filepath"
|
2021-02-07 08:36:21 +01:00
|
|
|
|
2021-02-17 22:13:39 +01:00
|
|
|
"dagger.io/go/dagger/compiler"
|
2021-01-30 02:16:22 +01:00
|
|
|
)
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
// An input is a value or artifact supplied by the user.
|
|
|
|
//
|
|
|
|
// - A value is any structured data which can be encoded as cue.
|
|
|
|
//
|
|
|
|
// - An artifact is a piece of data, like a source code checkout,
|
|
|
|
// binary bundle, docker image, database backup etc.
|
|
|
|
//
|
|
|
|
// Artifacts can be passed as inputs, generated dynamically from
|
|
|
|
// other inputs, and received as outputs.
|
|
|
|
// Under the hood, an artifact is encoded as a LLB pipeline, and
|
|
|
|
// attached to the cue configuration as a
|
|
|
|
//
|
2021-03-26 22:11:54 +01:00
|
|
|
type InputType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
InputTypeDir InputType = "dir"
|
|
|
|
InputTypeGit InputType = "git"
|
|
|
|
InputTypeDocker InputType = "docker"
|
|
|
|
InputTypeText InputType = "text"
|
|
|
|
InputTypeJSON InputType = "json"
|
|
|
|
InputTypeYAML InputType = "yaml"
|
2021-04-02 01:45:58 +02:00
|
|
|
InputTypeEmpty InputType = ""
|
2021-03-26 22:11:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Input struct {
|
|
|
|
Type InputType `json:"type,omitempty"`
|
|
|
|
|
|
|
|
Dir *dirInput `json:"dir,omitempty"`
|
|
|
|
Git *gitInput `json:"git,omitempty"`
|
|
|
|
Docker *dockerInput `json:"docker,omitempty"`
|
|
|
|
Text *textInput `json:"text,omitempty"`
|
|
|
|
JSON *jsonInput `json:"json,omitempty"`
|
|
|
|
YAML *yamlInput `json:"yaml,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i Input) Compile() (*compiler.Value, error) {
|
|
|
|
switch i.Type {
|
|
|
|
case InputTypeDir:
|
|
|
|
return i.Dir.Compile()
|
|
|
|
case InputTypeGit:
|
|
|
|
return i.Git.Compile()
|
|
|
|
case InputTypeDocker:
|
|
|
|
return i.Docker.Compile()
|
|
|
|
case InputTypeText:
|
|
|
|
return i.Text.Compile()
|
|
|
|
case InputTypeJSON:
|
|
|
|
return i.JSON.Compile()
|
|
|
|
case InputTypeYAML:
|
|
|
|
return i.YAML.Compile()
|
|
|
|
case "":
|
|
|
|
return nil, fmt.Errorf("input has not been set")
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported input type: %s", i.Type)
|
|
|
|
}
|
2021-03-24 18:37:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// An input artifact loaded from a local directory
|
|
|
|
func DirInput(path string, include []string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeDir,
|
|
|
|
Dir: &dirInput{
|
|
|
|
Path: path,
|
|
|
|
Include: include,
|
|
|
|
},
|
2021-03-24 18:37:50 +01:00
|
|
|
}
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
type dirInput struct {
|
2021-03-25 01:55:21 +01:00
|
|
|
Path string `json:"path,omitempty"`
|
|
|
|
Include []string `json:"include,omitempty"`
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (dir dirInput) Compile() (*compiler.Value, error) {
|
|
|
|
// FIXME: serialize an intermediate struct, instead of generating cue source
|
2021-04-02 08:08:26 +02:00
|
|
|
|
2021-04-03 02:14:01 +02:00
|
|
|
// resolve absolute path
|
|
|
|
path, err := filepath.Abs(dir.Path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
dir.Path = path
|
|
|
|
|
2021-04-02 08:08:26 +02:00
|
|
|
// json.Marshal([]string{}) returns []byte("null"), which wreaks havoc
|
|
|
|
// in Cue because `null` is not a `[...string]`
|
|
|
|
includeLLB := []byte("[]")
|
|
|
|
if len(dir.Include) > 0 {
|
|
|
|
var err error
|
|
|
|
includeLLB, err = json.Marshal(dir.Include)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
2021-03-24 18:37:50 +01:00
|
|
|
llb := fmt.Sprintf(
|
2021-04-02 23:58:12 +02:00
|
|
|
`#up: [{do:"local",dir:"%s", include:%s}]`,
|
2021-03-24 18:37:50 +01:00
|
|
|
dir.Path,
|
|
|
|
includeLLB,
|
|
|
|
)
|
|
|
|
return compiler.Compile("", llb)
|
|
|
|
}
|
|
|
|
|
|
|
|
// An input artifact loaded from a git repository
|
|
|
|
type gitInput struct {
|
2021-03-25 01:55:21 +01:00
|
|
|
Remote string `json:"remote,omitempty"`
|
|
|
|
Ref string `json:"ref,omitempty"`
|
|
|
|
Dir string `json:"dir,omitempty"`
|
2021-03-24 18:37:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func GitInput(remote, ref, dir string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeGit,
|
|
|
|
Git: &gitInput{
|
|
|
|
Remote: remote,
|
|
|
|
Ref: ref,
|
|
|
|
Dir: dir,
|
|
|
|
},
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (git gitInput) Compile() (*compiler.Value, error) {
|
2021-04-02 01:45:58 +02:00
|
|
|
ref := "HEAD"
|
|
|
|
if git.Ref != "" {
|
|
|
|
ref = git.Ref
|
|
|
|
}
|
|
|
|
|
|
|
|
return compiler.Compile("", fmt.Sprintf(
|
2021-04-02 23:58:12 +02:00
|
|
|
`#up: [{do:"fetch-git", remote:"%s", ref:"%s"}]`,
|
2021-04-02 01:45:58 +02:00
|
|
|
git.Remote,
|
|
|
|
ref,
|
|
|
|
))
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
// An input artifact loaded from a docker container
|
|
|
|
func DockerInput(ref string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeDocker,
|
|
|
|
Docker: &dockerInput{
|
|
|
|
Ref: ref,
|
|
|
|
},
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
type dockerInput struct {
|
2021-03-26 22:11:54 +01:00
|
|
|
Ref string `json:"ref,omitempty"`
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (i dockerInput) Compile() (*compiler.Value, error) {
|
|
|
|
panic("NOT IMPLEMENTED")
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
// An input value encoded as text
|
|
|
|
func TextInput(data string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeText,
|
|
|
|
Text: &textInput{
|
|
|
|
Data: data,
|
|
|
|
},
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
type textInput struct {
|
2021-03-25 01:55:21 +01:00
|
|
|
Data string `json:"data,omitempty"`
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (i textInput) Compile() (*compiler.Value, error) {
|
2021-03-25 01:55:21 +01:00
|
|
|
return compiler.Compile("", fmt.Sprintf("%q", i.Data))
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
// An input value encoded as JSON
|
|
|
|
func JSONInput(data string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeJSON,
|
|
|
|
JSON: &jsonInput{
|
|
|
|
Data: data,
|
|
|
|
},
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
type jsonInput struct {
|
|
|
|
// Marshalled JSON data
|
2021-03-25 01:55:21 +01:00
|
|
|
Data string `json:"data,omitempty"`
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (i jsonInput) Compile() (*compiler.Value, error) {
|
2021-03-25 01:55:21 +01:00
|
|
|
return compiler.DecodeJSON("", []byte(i.Data))
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
// An input value encoded as YAML
|
|
|
|
func YAMLInput(data string) Input {
|
2021-03-26 22:11:54 +01:00
|
|
|
return Input{
|
|
|
|
Type: InputTypeYAML,
|
|
|
|
YAML: &yamlInput{
|
|
|
|
Data: data,
|
|
|
|
},
|
2021-03-18 23:03:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
type yamlInput struct {
|
|
|
|
// Marshalled YAML data
|
2021-03-25 01:55:21 +01:00
|
|
|
Data string `json:"data,omitempty"`
|
2021-03-18 23:03:45 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 18:37:50 +01:00
|
|
|
func (i yamlInput) Compile() (*compiler.Value, error) {
|
2021-03-25 01:55:21 +01:00
|
|
|
return compiler.DecodeYAML("", []byte(i.Data))
|
2021-01-30 02:16:22 +01:00
|
|
|
}
|