From d1b49c8ef3877abbb1e318929c33d170ee997a10 Mon Sep 17 00:00:00 2001 From: mahbub570 Date: Fri, 16 Aug 2024 18:43:40 +0600 Subject: [PATCH 01/21] feat: add cli for health status Signed-off-by: mahbub570 Signed-off-by: axif --- cmd/harbor/root/cmd.go | 1 + cmd/harbor/root/health.go | 24 ++++++++++++++++++++ pkg/api/health_handler.go | 27 +++++++++++++++++++++++ pkg/views/health/view.go | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 cmd/harbor/root/health.go create mode 100644 pkg/api/health_handler.go create mode 100644 pkg/views/health/view.go diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index 7a3fbf3d..94c4f8a3 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -109,6 +109,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), + HealthCommand(), ) return root diff --git a/cmd/harbor/root/health.go b/cmd/harbor/root/health.go new file mode 100644 index 00000000..9baf4dfa --- /dev/null +++ b/cmd/harbor/root/health.go @@ -0,0 +1,24 @@ +package root + +import ( + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/spf13/cobra" + "github.com/goharbor/harbor-cli/pkg/views/health" +) + +func HealthCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "health", + Short: "Get the health status of Harbor components", + RunE: func(cmd *cobra.Command, args []string) error { + status, err := api.GetHealth() + if err != nil { + return err + } + health.PrintHealthStatus(status) + return nil + }, + } + + return cmd +} diff --git a/pkg/api/health_handler.go b/pkg/api/health_handler.go new file mode 100644 index 00000000..e0893ad0 --- /dev/null +++ b/pkg/api/health_handler.go @@ -0,0 +1,27 @@ +package api + +import ( + "context" + "fmt" + + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" + "github.com/goharbor/harbor-cli/pkg/utils" + "github.com/spf13/viper" +) + +func GetHealth() (*health.GetHealthOK, error) { + credentialName := viper.GetString("current-credential-name") + client := utils.GetClientByCredentialName(credentialName) + + ctx := context.Background() + params := health.NewGetHealthParams().WithContext(ctx) + + response, err := client.Health.GetHealth(ctx, params) + if err != nil { + return nil, fmt.Errorf("error getting health status: %w", err) + } + + return response, nil +} + + \ No newline at end of file diff --git a/pkg/views/health/view.go b/pkg/views/health/view.go new file mode 100644 index 00000000..087d848c --- /dev/null +++ b/pkg/views/health/view.go @@ -0,0 +1,46 @@ +package health + +import ( + "fmt" + "github.com/charmbracelet/bubbles/table" + "github.com/charmbracelet/bubbletea" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" + "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" +) + +var columns = []table.Column{ + {Title: "Component", Width: 20}, + {Title: "Status", Width: 20}, +} + +type HealthModel struct { + tableModel tablelist.Model +} + +func NewHealthModel(status *health.GetHealthOK) HealthModel { + var rows []table.Row + + rows = append(rows, table.Row{"Overall", status.Payload.Status}) + + for _, component := range status.Payload.Components { + rows = append(rows, table.Row{ + component.Name, + component.Status, + }) + } + + tbl := tablelist.NewModel(columns, rows, len(rows)+1) // +1 for header + return HealthModel{tableModel: tbl} +} + +func PrintHealthStatus(status *health.GetHealthOK) { + m := NewHealthModel(status) + fmt.Println("Harbor Health Status:") + fmt.Printf("Status: %s\n", status.Payload.Status) + + p := tea.NewProgram(m.tableModel) + if _, err := p.Run(); err != nil { + fmt.Println("Error running program:", err) + return + } +} \ No newline at end of file From f95bc8cf2646f6fcd5eea81f2e29b9fc36b9299d Mon Sep 17 00:00:00 2001 From: mahbub570 Date: Fri, 16 Aug 2024 21:57:03 +0600 Subject: [PATCH 02/21] add style Signed-off-by: mahbub570 Signed-off-by: axif --- pkg/views/health/view.go | 18 +++++++++++------- pkg/views/styles.go | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/views/health/view.go b/pkg/views/health/view.go index 087d848c..f2ad15d1 100644 --- a/pkg/views/health/view.go +++ b/pkg/views/health/view.go @@ -5,27 +5,32 @@ import ( "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" + "github.com/goharbor/harbor-cli/pkg/views" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "Component", Width: 20}, - {Title: "Status", Width: 20}, + {Title: "Status", Width: 30}, } type HealthModel struct { tableModel tablelist.Model } +func styleStatus(status string) string { + if status == "healthy" { + return views.GreenStyle.Render(status) + } + return views.RedStyle.Render(status) +} + func NewHealthModel(status *health.GetHealthOK) HealthModel { var rows []table.Row - - rows = append(rows, table.Row{"Overall", status.Payload.Status}) - for _, component := range status.Payload.Components { rows = append(rows, table.Row{ component.Name, - component.Status, + styleStatus(component.Status), }) } @@ -35,8 +40,7 @@ func NewHealthModel(status *health.GetHealthOK) HealthModel { func PrintHealthStatus(status *health.GetHealthOK) { m := NewHealthModel(status) - fmt.Println("Harbor Health Status:") - fmt.Printf("Status: %s\n", status.Payload.Status) + fmt.Printf("Harbor Health Status:: %s\n", styleStatus(status.Payload.Status)) p := tea.NewProgram(m.tableModel) if _, err := p.Run(); err != nil { diff --git a/pkg/views/styles.go b/pkg/views/styles.go index 89efa04e..b00c92be 100644 --- a/pkg/views/styles.go +++ b/pkg/views/styles.go @@ -11,6 +11,8 @@ var ( SelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170")) PaginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4) HelpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1) + RedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF0000")) + GreenStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) ) var BaseStyle = lipgloss.NewStyle(). From 3fc7b3306da0d39c291e520677efd833b483629f Mon Sep 17 00:00:00 2001 From: mahbub570 Date: Sun, 18 Aug 2024 19:43:32 +0600 Subject: [PATCH 03/21] Update pkg/api/health_handler.go Co-authored-by: Prasanth B <89722848+bupd@users.noreply.github.com> Signed-off-by: mahbub570 Signed-off-by: axif --- pkg/api/health_handler.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/api/health_handler.go b/pkg/api/health_handler.go index e0893ad0..805e194d 100644 --- a/pkg/api/health_handler.go +++ b/pkg/api/health_handler.go @@ -10,10 +10,10 @@ import ( ) func GetHealth() (*health.GetHealthOK, error) { - credentialName := viper.GetString("current-credential-name") - client := utils.GetClientByCredentialName(credentialName) - - ctx := context.Background() + ctx, client, err := utils.ContextWithClient() + if err != nil { + return err + } params := health.NewGetHealthParams().WithContext(ctx) response, err := client.Health.GetHealth(ctx, params) From 8b6dac50af28d77de8610484291adbd5f063c1c0 Mon Sep 17 00:00:00 2001 From: axif Date: Wed, 11 Sep 2024 22:31:29 +0600 Subject: [PATCH 04/21] Altaf suggetion`s Signed-off-by: axif --- pkg/api/health_handler.go | 9 ++------- pkg/views/health/view.go | 40 ++++++++++++++++----------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/pkg/api/health_handler.go b/pkg/api/health_handler.go index 805e194d..d8eceb37 100644 --- a/pkg/api/health_handler.go +++ b/pkg/api/health_handler.go @@ -1,27 +1,22 @@ package api import ( - "context" "fmt" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" "github.com/goharbor/harbor-cli/pkg/utils" - "github.com/spf13/viper" ) func GetHealth() (*health.GetHealthOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { - return err + return nil, err } - params := health.NewGetHealthParams().WithContext(ctx) - response, err := client.Health.GetHealth(ctx, params) + response, err := client.Health.GetHealth(ctx,&health.GetHealthParams{}) if err != nil { return nil, fmt.Errorf("error getting health status: %w", err) } return response, nil } - - \ No newline at end of file diff --git a/pkg/views/health/view.go b/pkg/views/health/view.go index f2ad15d1..31813d15 100644 --- a/pkg/views/health/view.go +++ b/pkg/views/health/view.go @@ -2,6 +2,8 @@ package health import ( "fmt" + "os" + "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" @@ -10,41 +12,31 @@ import ( ) var columns = []table.Column{ - {Title: "Component", Width: 20}, - {Title: "Status", Width: 30}, -} - -type HealthModel struct { - tableModel tablelist.Model + {Title: "Component", Width: 18}, + {Title: "Status", Width: 26}, } -func styleStatus(status string) string { - if status == "healthy" { - return views.GreenStyle.Render(status) - } - return views.RedStyle.Render(status) -} - -func NewHealthModel(status *health.GetHealthOK) HealthModel { +func PrintHealthStatus(status *health.GetHealthOK) { var rows []table.Row + fmt.Printf("Harbor Health Status:: %s\n", styleStatus(status.Payload.Status)) for _, component := range status.Payload.Components { rows = append(rows, table.Row{ component.Name, styleStatus(component.Status), }) } - - tbl := tablelist.NewModel(columns, rows, len(rows)+1) // +1 for header - return HealthModel{tableModel: tbl} -} -func PrintHealthStatus(status *health.GetHealthOK) { - m := NewHealthModel(status) - fmt.Printf("Harbor Health Status:: %s\n", styleStatus(status.Payload.Status)) + m := tablelist.NewModel(columns, rows, len(rows)) - p := tea.NewProgram(m.tableModel) - if _, err := p.Run(); err != nil { + if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) - return + os.Exit(1) } +} + +func styleStatus(status string) string { + if status == "healthy" { + return views.GreenStyle.Render(status) + } + return views.RedStyle.Render(status) } \ No newline at end of file From 5479920ec34c962828bf5ed03e5114b11e378214 Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Tue, 24 Sep 2024 14:42:29 +0800 Subject: [PATCH 05/21] Restrict the input for the login command Signed-off-by: JianMinTang --- pkg/utils/helper.go | 25 +++++++++++++++++++++++++ pkg/views/login/create.go | 25 ++++++++++++++++++------- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index 612f814f..9c4e1b14 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -1,7 +1,9 @@ package utils import ( + "errors" "fmt" + "regexp" "strings" "time" ) @@ -40,3 +42,26 @@ func FormatSize(size int64) string { mbSize := float64(size) / (1024 * 1024) return fmt.Sprintf("%.2fMiB", mbSize) } + +// check if the password format is vaild +func ValidatePassword(password string) (bool, error) { + if len(password) < 8 || len(password) > 256 { + return false, errors.New("worong! the password length must be at least 8 characters and at most 256 characters") + } + // checking the password has a minimum of one lower case letter + if done, _ := regexp.MatchString("([a-z])+", password); !done { + return false, errors.New("worong! the password doesn't have a lowercase letter") + } + + // checking the password has a minimmum of one upper case letter + if done, _ := regexp.MatchString("([A-Z])+", password); !done { + return false, errors.New("worong! the password doesn't have an upppercase letter") + } + + // checking if the password has a minimum of one digit + if done, _ := regexp.Match("([0-9])+", []byte(password)); !done { + return false, errors.New("worong! the password doesn't have a digit number") + } + + return true, errors.New("") +} diff --git a/pkg/views/login/create.go b/pkg/views/login/create.go index 70e283ca..7653e8b5 100644 --- a/pkg/views/login/create.go +++ b/pkg/views/login/create.go @@ -2,8 +2,11 @@ package login import ( "errors" + "net/url" + "strings" "github.com/charmbracelet/huh" + "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) @@ -22,8 +25,12 @@ func CreateView(loginView *LoginView) { Title("Server"). Value(&loginView.Server). Validate(func(str string) error { - if str == "" { - return errors.New("server cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("server cannot be empty or only spaces") + } + formattedUrl := utils.FormatUrl(str) + if _, err := url.ParseRequestURI(formattedUrl); err != nil { + return errors.New("enter the correct server format") } return nil }), @@ -31,27 +38,31 @@ func CreateView(loginView *LoginView) { Title("User Name"). Value(&loginView.Username). Validate(func(str string) error { - if str == "" { + if strings.TrimSpace(str) == "" { return errors.New("username cannot be empty") } return nil }), huh.NewInput(). Title("Password"). - EchoMode(huh.EchoModePassword). + EchoMode(huh.EchoModePassword). Value(&loginView.Password). Validate(func(str string) error { - if str == "" { + if strings.TrimSpace(str) == "" { return errors.New("password cannot be empty") } + isVaild, err := utils.ValidatePassword(str) + if !isVaild { + return err + } return nil }), huh.NewInput(). Title("Name of Credential"). Value(&loginView.Name). Validate(func(str string) error { - if str == "" { - return errors.New("credential name cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("credential name cannot be empty or only spaces") } return nil }), From 8a63619579d71a2700ee52f88b950570c23ff755 Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Tue, 24 Sep 2024 15:16:49 +0800 Subject: [PATCH 06/21] Restrict the input for tag name Signed-off-by: JianMinTang --- pkg/utils/helper.go | 9 +++++++++ pkg/views/artifact/tags/create/view.go | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index 9c4e1b14..3b6e392a 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -65,3 +65,12 @@ func ValidatePassword(password string) (bool, error) { return true, errors.New("") } + +// check if the tag name is valid +func VaildateTagName(tagname string) bool { + pattern := `^[\w][\w.-]{0,127}$` + + re := regexp.MustCompile(pattern) + + return re.MatchString(tagname) +} diff --git a/pkg/views/artifact/tags/create/view.go b/pkg/views/artifact/tags/create/view.go index dd7449e4..94c30655 100644 --- a/pkg/views/artifact/tags/create/view.go +++ b/pkg/views/artifact/tags/create/view.go @@ -2,8 +2,10 @@ package create import ( "errors" + "strings" "github.com/charmbracelet/huh" + "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) @@ -16,8 +18,11 @@ func CreateTagView(tagName *string) { Title("Tag Name"). Value(tagName). Validate(func(str string) error { - if str == "" { - return errors.New("project name cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("tag name cannot be empty or only spaces") + } + if isVaild := utils.VaildateTagName(str); !isVaild { + return errors.New("please enter the correct tag name format") } return nil }), From 3bcaf3de7536ec32b6d6ca156d2949032d8b51cb Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Tue, 24 Sep 2024 15:21:04 +0800 Subject: [PATCH 07/21] Rename the function Signed-off-by: JianMinTang --- pkg/utils/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index 3b6e392a..e0fd71ea 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -67,7 +67,7 @@ func ValidatePassword(password string) (bool, error) { } // check if the tag name is valid -func VaildateTagName(tagname string) bool { +func ValidateTagName(tagname string) bool { pattern := `^[\w][\w.-]{0,127}$` re := regexp.MustCompile(pattern) From a8222a1ad88ddcaad813f25d3013f0d359e8bd33 Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Tue, 24 Sep 2024 16:06:37 +0800 Subject: [PATCH 08/21] Restrict the input for creating the project Signed-off-by: JianMinTang --- pkg/utils/helper.go | 26 ++++++++++++++++++++++++-- pkg/views/artifact/tags/create/view.go | 2 +- pkg/views/project/create/view.go | 14 ++++++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index e0fd71ea..eb9619c7 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "regexp" + "strconv" "strings" "time" ) @@ -67,10 +68,31 @@ func ValidatePassword(password string) (bool, error) { } // check if the tag name is valid -func ValidateTagName(tagname string) bool { +func ValidateTagName(tagName string) bool { pattern := `^[\w][\w.-]{0,127}$` re := regexp.MustCompile(pattern) - return re.MatchString(tagname) + return re.MatchString(tagName) +} + +// check if the project name is valid +func ValidateProjectName(projectName string) bool { + pattern := `^[a-z0-9][a-z0-9._-]{0,254}$$` + + re := regexp.MustCompile(pattern) + + return re.MatchString(projectName) +} + +func ValidateStorageLimit(sl string) error { + storageLimit, err := strconv.Atoi(sl) + if err != nil { + return errors.New("the storage limit only takes integer values") + } + + if storageLimit < -1 || (storageLimit > -1 && storageLimit < 0) || storageLimit > 1024 { + return errors.New("the maximum value for the storage cannot exceed 1024 terabytes and -1 for no limit") + } + return nil } diff --git a/pkg/views/artifact/tags/create/view.go b/pkg/views/artifact/tags/create/view.go index 94c30655..011024df 100644 --- a/pkg/views/artifact/tags/create/view.go +++ b/pkg/views/artifact/tags/create/view.go @@ -21,7 +21,7 @@ func CreateTagView(tagName *string) { if strings.TrimSpace(str) == "" { return errors.New("tag name cannot be empty or only spaces") } - if isVaild := utils.VaildateTagName(str); !isVaild { + if isVaild := utils.ValidateTagName(str); !isVaild { return errors.New("please enter the correct tag name format") } return nil diff --git a/pkg/views/project/create/view.go b/pkg/views/project/create/view.go index 484c0a05..89ea0c79 100644 --- a/pkg/views/project/create/view.go +++ b/pkg/views/project/create/view.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "github.com/charmbracelet/huh" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/registry" @@ -55,8 +56,11 @@ func CreateProjectView(createView *CreateView) { Title("Project Name"). Value(&createView.ProjectName). Validate(func(str string) error { - if str == "" { - return errors.New("project name cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("project name cannot be empty or only spaces") + } + if isValid := utils.ValidateProjectName(str); !isValid { + return errors.New("please enter correct project name format") } return nil }), @@ -70,6 +74,12 @@ func CreateProjectView(createView *CreateView) { Value(&createView.StorageLimit). Validate(func(str string) error { // Assuming StorageLimit is an int64 + if strings.TrimSpace(str) == "" { + return errors.New("storage limit cannot be empty or only spaces") + } + if err := utils.ValidateStorageLimit(str); err != nil { + return err + } return nil }), From 76bd3bf828a9d95ae3767cc0b1701e141e22dabb Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Tue, 24 Sep 2024 16:37:34 +0800 Subject: [PATCH 09/21] Restrict the input for creating the registry Signed-off-by: JianMinTang --- pkg/utils/helper.go | 8 ++++++++ pkg/views/registry/create/view.go | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index eb9619c7..b7312ee4 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -96,3 +96,11 @@ func ValidateStorageLimit(sl string) error { } return nil } + +func ValidateRegistryName(rn string) bool { + pattern := `^[\w][\w.-]{0,63}$` + + re := regexp.MustCompile(pattern) + + return re.MatchString(rn) +} diff --git a/pkg/views/registry/create/view.go b/pkg/views/registry/create/view.go index 3bb6aed4..1fc2162b 100644 --- a/pkg/views/registry/create/view.go +++ b/pkg/views/registry/create/view.go @@ -2,10 +2,13 @@ package create import ( "errors" + "net/url" "strconv" + "strings" "github.com/charmbracelet/huh" "github.com/goharbor/harbor-cli/pkg/api" + "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) @@ -58,8 +61,11 @@ func CreateRegistryView(createView *api.CreateRegView) { Title("Name"). Value(&createView.Name). Validate(func(str string) error { - if str == "" { - return errors.New("name cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("name cannot be empty or only spaces") + } + if isVaild := utils.ValidateRegistryName(str); !isVaild { + return errors.New("enter the correct name format") } return nil }), @@ -70,8 +76,12 @@ func CreateRegistryView(createView *api.CreateRegView) { Title("URL"). Value(&createView.URL). Validate(func(str string) error { - if str == "" { - return errors.New("url cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("url cannot be empty or only spaces") + } + formattedUrl := utils.FormatUrl(str) + if _, err := url.ParseRequestURI(formattedUrl); err != nil { + return errors.New("enter the correct url format") } return nil }), From 301744fb8d3e14f0f8d36eb7784eda4af9ac6b70 Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Wed, 25 Sep 2024 09:56:29 +0800 Subject: [PATCH 10/21] Restrict the input for creating an user Signed-off-by: JianMinTang --- pkg/utils/helper.go | 32 +++++++++++++++++++++++++------- pkg/views/login/create.go | 3 +-- pkg/views/user/create/view.go | 28 +++++++++++++++++++++------- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index b7312ee4..f498d19a 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -44,27 +44,45 @@ func FormatSize(size int64) string { return fmt.Sprintf("%.2fMiB", mbSize) } +func VaildUserName(username string) bool { + pattern := `^[a-zA-Z0-9]{1,255}$` + re := regexp.MustCompile(pattern) + return re.MatchString(username) +} + +func VaildEmail(email string) bool { + pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` + re := regexp.MustCompile(pattern) + return re.MatchString(email) +} + +func VaildFL(name string) bool { + pattern := `^[A-Za-z]{1,20}\s[A-Za-z]{1,20}$` + re := regexp.MustCompile(pattern) + return re.MatchString(name) +} + // check if the password format is vaild -func ValidatePassword(password string) (bool, error) { +func ValidatePassword(password string) error { if len(password) < 8 || len(password) > 256 { - return false, errors.New("worong! the password length must be at least 8 characters and at most 256 characters") + return errors.New("worong! the password length must be at least 8 characters and at most 256 characters") } // checking the password has a minimum of one lower case letter if done, _ := regexp.MatchString("([a-z])+", password); !done { - return false, errors.New("worong! the password doesn't have a lowercase letter") + return errors.New("worong! the password doesn't have a lowercase letter") } // checking the password has a minimmum of one upper case letter if done, _ := regexp.MatchString("([A-Z])+", password); !done { - return false, errors.New("worong! the password doesn't have an upppercase letter") + return errors.New("worong! the password doesn't have an upppercase letter") } // checking if the password has a minimum of one digit if done, _ := regexp.Match("([0-9])+", []byte(password)); !done { - return false, errors.New("worong! the password doesn't have a digit number") + return errors.New("worong! the password doesn't have a digit number") } - return true, errors.New("") + return nil } // check if the tag name is valid @@ -78,7 +96,7 @@ func ValidateTagName(tagName string) bool { // check if the project name is valid func ValidateProjectName(projectName string) bool { - pattern := `^[a-z0-9][a-z0-9._-]{0,254}$$` + pattern := `^[a-z0-9][a-z0-9._-]{0,254}$` re := regexp.MustCompile(pattern) diff --git a/pkg/views/login/create.go b/pkg/views/login/create.go index 7653e8b5..c4e09d62 100644 --- a/pkg/views/login/create.go +++ b/pkg/views/login/create.go @@ -51,8 +51,7 @@ func CreateView(loginView *LoginView) { if strings.TrimSpace(str) == "" { return errors.New("password cannot be empty") } - isVaild, err := utils.ValidatePassword(str) - if !isVaild { + if err := utils.ValidatePassword(str); err != nil { return err } return nil diff --git a/pkg/views/user/create/view.go b/pkg/views/user/create/view.go index fef9ac11..8b1d78df 100644 --- a/pkg/views/user/create/view.go +++ b/pkg/views/user/create/view.go @@ -2,8 +2,10 @@ package create import ( "errors" + "strings" "github.com/charmbracelet/huh" + "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) @@ -23,17 +25,23 @@ func CreateUserView(createView *CreateView) { Title("User Name"). Value(&createView.Username). Validate(func(str string) error { - if str == "" { + if strings.TrimSpace(str) == "" { return errors.New("user name cannot be empty") } + if isVaild := utils.VaildUserName(str); !isVaild { + return errors.New("username cannot contain special characters") + } return nil }), huh.NewInput(). Title("Email"). Value(&createView.Email). Validate(func(str string) error { - if str == "" { - return errors.New("email cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("email cannot be empty or only spaces") + } + if isVaild := utils.VaildEmail(str); !isVaild { + return errors.New("please enter correct email format") } return nil }), @@ -42,18 +50,24 @@ func CreateUserView(createView *CreateView) { Title("First and Last Name"). Value(&createView.Realname). Validate(func(str string) error { - if str == "" { + if strings.TrimSpace(str) == "" { return errors.New("real name cannot be empty") } + if isValid := utils.VaildFL(str); !isValid { + return errors.New("please enter correct first and last name format, like John Cooper") + } return nil }), huh.NewInput(). Title("Password"). - EchoMode(huh.EchoModePassword). + EchoMode(huh.EchoModePassword). Value(&createView.Password). Validate(func(str string) error { - if str == "" { - return errors.New("password cannot be empty") + if strings.TrimSpace(str) == "" { + return errors.New("password cannot be empty or only space") + } + if err := utils.ValidatePassword(str); err != nil { + return err } return nil }), From a4b9865f5841f3fd41315b90e955325b4da39330 Mon Sep 17 00:00:00 2001 From: JianMinTang Date: Wed, 25 Sep 2024 10:11:49 +0800 Subject: [PATCH 11/21] Little fix about function and error informantion Signed-off-by: JianMinTang --- pkg/utils/helper.go | 6 +++--- pkg/views/login/create.go | 12 +++++++++--- pkg/views/registry/create/view.go | 4 ++-- pkg/views/user/create/view.go | 10 +++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pkg/utils/helper.go b/pkg/utils/helper.go index f498d19a..31f06c9b 100644 --- a/pkg/utils/helper.go +++ b/pkg/utils/helper.go @@ -44,19 +44,19 @@ func FormatSize(size int64) string { return fmt.Sprintf("%.2fMiB", mbSize) } -func VaildUserName(username string) bool { +func ValidateUserName(username string) bool { pattern := `^[a-zA-Z0-9]{1,255}$` re := regexp.MustCompile(pattern) return re.MatchString(username) } -func VaildEmail(email string) bool { +func ValidateEmail(email string) bool { pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` re := regexp.MustCompile(pattern) return re.MatchString(email) } -func VaildFL(name string) bool { +func ValidateFL(name string) bool { pattern := `^[A-Za-z]{1,20}\s[A-Za-z]{1,20}$` re := regexp.MustCompile(pattern) return re.MatchString(name) diff --git a/pkg/views/login/create.go b/pkg/views/login/create.go index c4e09d62..8a489cc8 100644 --- a/pkg/views/login/create.go +++ b/pkg/views/login/create.go @@ -30,7 +30,7 @@ func CreateView(loginView *LoginView) { } formattedUrl := utils.FormatUrl(str) if _, err := url.ParseRequestURI(formattedUrl); err != nil { - return errors.New("enter the correct server format") + return errors.New("please enter the correct server format") } return nil }), @@ -39,7 +39,10 @@ func CreateView(loginView *LoginView) { Value(&loginView.Username). Validate(func(str string) error { if strings.TrimSpace(str) == "" { - return errors.New("username cannot be empty") + return errors.New("username cannot be empty or only spaces") + } + if isValid := utils.ValidateUserName(str); !isValid { + return errors.New("please enter correct username format") } return nil }), @@ -49,7 +52,7 @@ func CreateView(loginView *LoginView) { Value(&loginView.Password). Validate(func(str string) error { if strings.TrimSpace(str) == "" { - return errors.New("password cannot be empty") + return errors.New("password cannot be empty or only spaces") } if err := utils.ValidatePassword(str); err != nil { return err @@ -63,6 +66,9 @@ func CreateView(loginView *LoginView) { if strings.TrimSpace(str) == "" { return errors.New("credential name cannot be empty or only spaces") } + if isValid := utils.ValidateUserName(str); !isValid { + return errors.New("please enter correct credential name format") + } return nil }), ), diff --git a/pkg/views/registry/create/view.go b/pkg/views/registry/create/view.go index 1fc2162b..ff090ec5 100644 --- a/pkg/views/registry/create/view.go +++ b/pkg/views/registry/create/view.go @@ -65,7 +65,7 @@ func CreateRegistryView(createView *api.CreateRegView) { return errors.New("name cannot be empty or only spaces") } if isVaild := utils.ValidateRegistryName(str); !isVaild { - return errors.New("enter the correct name format") + return errors.New("please enter the correct name format") } return nil }), @@ -81,7 +81,7 @@ func CreateRegistryView(createView *api.CreateRegView) { } formattedUrl := utils.FormatUrl(str) if _, err := url.ParseRequestURI(formattedUrl); err != nil { - return errors.New("enter the correct url format") + return errors.New("please enter the correct url format") } return nil }), diff --git a/pkg/views/user/create/view.go b/pkg/views/user/create/view.go index 8b1d78df..e52b3498 100644 --- a/pkg/views/user/create/view.go +++ b/pkg/views/user/create/view.go @@ -28,7 +28,7 @@ func CreateUserView(createView *CreateView) { if strings.TrimSpace(str) == "" { return errors.New("user name cannot be empty") } - if isVaild := utils.VaildUserName(str); !isVaild { + if isVaild := utils.ValidateUserName(str); !isVaild { return errors.New("username cannot contain special characters") } return nil @@ -40,7 +40,7 @@ func CreateUserView(createView *CreateView) { if strings.TrimSpace(str) == "" { return errors.New("email cannot be empty or only spaces") } - if isVaild := utils.VaildEmail(str); !isVaild { + if isVaild := utils.ValidateEmail(str); !isVaild { return errors.New("please enter correct email format") } return nil @@ -53,8 +53,8 @@ func CreateUserView(createView *CreateView) { if strings.TrimSpace(str) == "" { return errors.New("real name cannot be empty") } - if isValid := utils.VaildFL(str); !isValid { - return errors.New("please enter correct first and last name format, like John Cooper") + if isValid := utils.ValidateFL(str); !isValid { + return errors.New("please enter correct first and last name format, like `Bob Dylan`") } return nil }), @@ -64,7 +64,7 @@ func CreateUserView(createView *CreateView) { Value(&createView.Password). Validate(func(str string) error { if strings.TrimSpace(str) == "" { - return errors.New("password cannot be empty or only space") + return errors.New("password cannot be empty or only spaces") } if err := utils.ValidatePassword(str); err != nil { return err From 2a317692e59980ebd668931f48083e0155156744 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Fri, 4 Oct 2024 21:36:55 -0400 Subject: [PATCH 12/21] restructure dagger files Signed-off-by: Tyler Auerbeck --- dagger/.gitattributes | 4 +++ dagger/.gitignore | 4 +++ dagger/go.mod | 47 ++++++++++++++++++++++++++ dagger/go.sum | 77 +++++++++++++++++++++++++++++++++++++++++++ dagger/main.go | 37 +++++++++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 dagger/.gitattributes create mode 100644 dagger/.gitignore create mode 100644 dagger/go.mod create mode 100644 dagger/go.sum create mode 100644 dagger/main.go diff --git a/dagger/.gitattributes b/dagger/.gitattributes new file mode 100644 index 00000000..3a454933 --- /dev/null +++ b/dagger/.gitattributes @@ -0,0 +1,4 @@ +/dagger.gen.go linguist-generated +/internal/dagger/** linguist-generated +/internal/querybuilder/** linguist-generated +/internal/telemetry/** linguist-generated diff --git a/dagger/.gitignore b/dagger/.gitignore new file mode 100644 index 00000000..7ebabcc1 --- /dev/null +++ b/dagger/.gitignore @@ -0,0 +1,4 @@ +/dagger.gen.go +/internal/dagger +/internal/querybuilder +/internal/telemetry diff --git a/dagger/go.mod b/dagger/go.mod new file mode 100644 index 00000000..6253d918 --- /dev/null +++ b/dagger/go.mod @@ -0,0 +1,47 @@ +module dagger/harbor-cli + +go 1.23.1 + +require ( + github.com/99designs/gqlgen v0.17.49 + github.com/Khan/genqlient v0.7.0 + github.com/vektah/gqlparser/v2 v2.5.16 + go.opentelemetry.io/otel v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 + go.opentelemetry.io/otel/log v0.3.0 + go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/trace v1.27.0 + go.opentelemetry.io/proto/otlp v1.3.1 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/sync v0.8.0 + google.golang.org/grpc v1.65.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect +) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/dagger/go.sum b/dagger/go.sum new file mode 100644 index 00000000..f6bb5391 --- /dev/null +++ b/dagger/go.sum @@ -0,0 +1,77 @@ +github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= +github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= +github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= +github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs= +go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= +go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= +go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/dagger/main.go b/dagger/main.go new file mode 100644 index 00000000..82de09e9 --- /dev/null +++ b/dagger/main.go @@ -0,0 +1,37 @@ +// A generated module for HarborCli functions +// +// This module has been generated via dagger init and serves as a reference to +// basic module structure as you get started with Dagger. +// +// Two functions have been pre-created. You can modify, delete, or add to them, +// as needed. They demonstrate usage of arguments and return types using simple +// echo and grep commands. The functions can be called from the dagger CLI or +// from one of the SDKs. +// +// The first line in this comment block is a short description line and the +// rest is a long description with more detail on the module's purpose or usage, +// if appropriate. All modules should have a short description. + +package main + +import ( + "context" + "dagger/harbor-cli/internal/dagger" +) + +type HarborCli struct{} + +// Returns a container that echoes whatever string argument is provided +func (m *HarborCli) ContainerEcho(stringArg string) *dagger.Container { + return dag.Container().From("alpine:latest").WithExec([]string{"echo", stringArg}) +} + +// Returns lines that match a pattern in the files of the provided Directory +func (m *HarborCli) GrepDir(ctx context.Context, directoryArg *dagger.Directory, pattern string) (string, error) { + return dag.Container(). + From("alpine:latest"). + WithMountedDirectory("/mnt", directoryArg). + WithWorkdir("/mnt"). + WithExec([]string{"grep", "-R", pattern, "."}). + Stdout(ctx) +} From 2af20ebab038733f2f86456e7abd0963017a8ede Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Fri, 4 Oct 2024 21:37:36 -0400 Subject: [PATCH 13/21] drop old dagger files Signed-off-by: Tyler Auerbeck --- dagger.json | 8 +- internal/dagger/dagger.gen.go | 8251 ------------------------- internal/querybuilder/marshal.go | 162 - internal/querybuilder/querybuilder.go | 213 - internal/telemetry/attrs.go | 86 - internal/telemetry/env.go | 59 - internal/telemetry/exporters.go | 120 - internal/telemetry/init.go | 377 -- internal/telemetry/live.go | 31 - internal/telemetry/logging.go | 119 - internal/telemetry/proxy.go | 6 - internal/telemetry/span.go | 53 - internal/telemetry/transform.go | 961 --- main.go | 133 - 14 files changed, 1 insertion(+), 10578 deletions(-) delete mode 100644 internal/dagger/dagger.gen.go delete mode 100644 internal/querybuilder/marshal.go delete mode 100644 internal/querybuilder/querybuilder.go delete mode 100644 internal/telemetry/attrs.go delete mode 100644 internal/telemetry/env.go delete mode 100644 internal/telemetry/exporters.go delete mode 100644 internal/telemetry/init.go delete mode 100644 internal/telemetry/live.go delete mode 100644 internal/telemetry/logging.go delete mode 100644 internal/telemetry/proxy.go delete mode 100644 internal/telemetry/span.go delete mode 100644 internal/telemetry/transform.go delete mode 100644 main.go diff --git a/dagger.json b/dagger.json index 1eef0255..ae93ae20 100644 --- a/dagger.json +++ b/dagger.json @@ -1,12 +1,6 @@ { "name": "harbor-cli", "sdk": "go", - "dependencies": [ - { - "name": "cosign", - "source": "github.com/scottames/daggerverse/cosign@8359122a7b90f2c8c6f3165570fdcbec6e923023" - } - ], - "source": ".", + "source": "dagger", "engineVersion": "v0.13.3" } diff --git a/internal/dagger/dagger.gen.go b/internal/dagger/dagger.gen.go deleted file mode 100644 index df14f551..00000000 --- a/internal/dagger/dagger.gen.go +++ /dev/null @@ -1,8251 +0,0 @@ -// Code generated by dagger. DO NOT EDIT. - -package dagger - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net" - "net/http" - "os" - "reflect" - "strconv" - "strings" - - "github.com/Khan/genqlient/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" - - "github.com/goharbor/harbor-cli/internal/querybuilder" - "github.com/goharbor/harbor-cli/internal/telemetry" -) - -func Tracer() trace.Tracer { - return otel.Tracer("dagger.io/sdk.go") -} - -// reassigned at runtime after the span is initialized -var marshalCtx = context.Background() - -// SetMarshalContext is a hack that lets us set the ctx to use for -// MarshalJSON implementations that get an object's ID. -func SetMarshalContext(ctx context.Context) { - marshalCtx = ctx -} - -// assertNotNil panic if the given value is nil. -// This function is used to validate that input with pointer type are not nil. -// See https://github.com/dagger/dagger/issues/5696 for more context. -func assertNotNil(argName string, value any) { - // We use reflect because just comparing value to nil is not working since - // the value is wrapped into a type when passed as parameter. - // E.g., nil become (*dagger.File)(nil). - if reflect.ValueOf(value).IsNil() { - panic(fmt.Sprintf("unexpected nil pointer for argument %q", argName)) - } -} - -type DaggerObject = querybuilder.GraphQLMarshaller - -// getCustomError parses a GraphQL error into a more specific error type. -func getCustomError(err error) error { - var gqlErr *gqlerror.Error - - if !errors.As(err, &gqlErr) { - return nil - } - - ext := gqlErr.Extensions - - typ, ok := ext["_type"].(string) - if !ok { - return nil - } - - if typ == "EXEC_ERROR" { - e := &ExecError{ - original: err, - } - if code, ok := ext["exitCode"].(float64); ok { - e.ExitCode = int(code) - } - if args, ok := ext["cmd"].([]interface{}); ok { - cmd := make([]string, len(args)) - for i, v := range args { - cmd[i] = v.(string) - } - e.Cmd = cmd - } - if stdout, ok := ext["stdout"].(string); ok { - e.Stdout = stdout - } - if stderr, ok := ext["stderr"].(string); ok { - e.Stderr = stderr - } - return e - } - - return nil -} - -// ExecError is an API error from an exec operation. -type ExecError struct { - original error - Cmd []string - ExitCode int - Stdout string - Stderr string -} - -func (e *ExecError) Error() string { - // As a default when just printing the error, include the stdout - // and stderr for visibility - msg := e.Message() - if strings.TrimSpace(e.Stdout) != "" { - msg += "\nStdout:\n" + e.Stdout - } - if strings.TrimSpace(e.Stderr) != "" { - msg += "\nStderr:\n" + e.Stderr - } - return msg -} - -func (e *ExecError) Message() string { - return e.original.Error() -} - -func (e *ExecError) Unwrap() error { - return e.original -} - -// The `CacheVolumeID` scalar type represents an identifier for an object of type CacheVolume. -type CacheVolumeID string - -// The `ContainerID` scalar type represents an identifier for an object of type Container. -type ContainerID string - -// The `CosignID` scalar type represents an identifier for an object of type Cosign. -type CosignID string - -// The `CurrentModuleID` scalar type represents an identifier for an object of type CurrentModule. -type CurrentModuleID string - -// The `DaggerEngineCacheEntryID` scalar type represents an identifier for an object of type DaggerEngineCacheEntry. -type DaggerEngineCacheEntryID string - -// The `DaggerEngineCacheEntrySetID` scalar type represents an identifier for an object of type DaggerEngineCacheEntrySet. -type DaggerEngineCacheEntrySetID string - -// The `DaggerEngineCacheID` scalar type represents an identifier for an object of type DaggerEngineCache. -type DaggerEngineCacheID string - -// The `DirectoryID` scalar type represents an identifier for an object of type Directory. -type DirectoryID string - -// The `EnumTypeDefID` scalar type represents an identifier for an object of type EnumTypeDef. -type EnumTypeDefID string - -// The `EnumValueTypeDefID` scalar type represents an identifier for an object of type EnumValueTypeDef. -type EnumValueTypeDefID string - -// The `EnvVariableID` scalar type represents an identifier for an object of type EnvVariable. -type EnvVariableID string - -// The `FieldTypeDefID` scalar type represents an identifier for an object of type FieldTypeDef. -type FieldTypeDefID string - -// The `FileID` scalar type represents an identifier for an object of type File. -type FileID string - -// The `FunctionArgID` scalar type represents an identifier for an object of type FunctionArg. -type FunctionArgID string - -// The `FunctionCallArgValueID` scalar type represents an identifier for an object of type FunctionCallArgValue. -type FunctionCallArgValueID string - -// The `FunctionCallID` scalar type represents an identifier for an object of type FunctionCall. -type FunctionCallID string - -// The `FunctionID` scalar type represents an identifier for an object of type Function. -type FunctionID string - -// The `GeneratedCodeID` scalar type represents an identifier for an object of type GeneratedCode. -type GeneratedCodeID string - -// The `GitModuleSourceID` scalar type represents an identifier for an object of type GitModuleSource. -type GitModuleSourceID string - -// The `GitRefID` scalar type represents an identifier for an object of type GitRef. -type GitRefID string - -// The `GitRepositoryID` scalar type represents an identifier for an object of type GitRepository. -type GitRepositoryID string - -// The `InputTypeDefID` scalar type represents an identifier for an object of type InputTypeDef. -type InputTypeDefID string - -// The `InterfaceTypeDefID` scalar type represents an identifier for an object of type InterfaceTypeDef. -type InterfaceTypeDefID string - -// An arbitrary JSON-encoded value. -type JSON string - -// The `LabelID` scalar type represents an identifier for an object of type Label. -type LabelID string - -// The `ListTypeDefID` scalar type represents an identifier for an object of type ListTypeDef. -type ListTypeDefID string - -// The `LocalModuleSourceID` scalar type represents an identifier for an object of type LocalModuleSource. -type LocalModuleSourceID string - -// The `ModuleDependencyID` scalar type represents an identifier for an object of type ModuleDependency. -type ModuleDependencyID string - -// The `ModuleID` scalar type represents an identifier for an object of type Module. -type ModuleID string - -// The `ModuleSourceID` scalar type represents an identifier for an object of type ModuleSource. -type ModuleSourceID string - -// The `ModuleSourceViewID` scalar type represents an identifier for an object of type ModuleSourceView. -type ModuleSourceViewID string - -// The `ObjectTypeDefID` scalar type represents an identifier for an object of type ObjectTypeDef. -type ObjectTypeDefID string - -// The platform config OS and architecture in a Container. -// -// The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64"). -type Platform string - -// The `PortID` scalar type represents an identifier for an object of type Port. -type PortID string - -// The `ScalarTypeDefID` scalar type represents an identifier for an object of type ScalarTypeDef. -type ScalarTypeDefID string - -// The `SecretID` scalar type represents an identifier for an object of type Secret. -type SecretID string - -// The `ServiceID` scalar type represents an identifier for an object of type Service. -type ServiceID string - -// The `SocketID` scalar type represents an identifier for an object of type Socket. -type SocketID string - -// The `TerminalID` scalar type represents an identifier for an object of type Terminal. -type TerminalID string - -// The `TypeDefID` scalar type represents an identifier for an object of type TypeDef. -type TypeDefID string - -// The absence of a value. -// -// A Null Void is used as a placeholder for resolvers that do not return anything. -type Void string - -// Key value object that represents a build argument. -type BuildArg struct { - // The build argument name. - Name string `json:"name"` - - // The build argument value. - Value string `json:"value"` -} - -// Key value object that represents a pipeline label. -type PipelineLabel struct { - // Label name. - Name string `json:"name"` - - // Label value. - Value string `json:"value"` -} - -// Port forwarding rules for tunneling network traffic. -type PortForward struct { - // Destination port for traffic. - Backend int `json:"backend"` - - // Port to expose to clients. If unspecified, a default will be chosen. - Frontend int `json:"frontend"` - - // Transport layer protocol to use for traffic. - Protocol NetworkProtocol `json:"protocol,omitempty"` -} - -// A directory whose contents persist across runs. -type CacheVolume struct { - query *querybuilder.Selection - - id *CacheVolumeID -} - -func (r *CacheVolume) WithGraphQLQuery(q *querybuilder.Selection) *CacheVolume { - return &CacheVolume{ - query: q, - } -} - -// A unique identifier for this CacheVolume. -func (r *CacheVolume) ID(ctx context.Context) (CacheVolumeID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response CacheVolumeID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *CacheVolume) XXX_GraphQLType() string { - return "CacheVolume" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *CacheVolume) XXX_GraphQLIDType() string { - return "CacheVolumeID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *CacheVolume) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *CacheVolume) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *CacheVolume) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadCacheVolumeFromID(CacheVolumeID(id)) - return nil -} - -// An OCI-compatible container, also known as a Docker container. -type Container struct { - query *querybuilder.Selection - - envVariable *string - export *string - id *ContainerID - imageRef *string - label *string - platform *Platform - publish *string - stderr *string - stdout *string - sync *ContainerID - up *Void - user *string - workdir *string -} -type WithContainerFunc func(r *Container) *Container - -// With calls the provided function with current Container. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Container) With(f WithContainerFunc) *Container { - return f(r) -} - -func (r *Container) WithGraphQLQuery(q *querybuilder.Selection) *Container { - return &Container{ - query: q, - } -} - -// Turn the container into a Service. -// -// Be sure to set any exposed ports before this conversion. -func (r *Container) AsService() *Service { - q := r.query.Select("asService") - - return &Service{ - query: q, - } -} - -// ContainerAsTarballOpts contains options for Container.AsTarball -type ContainerAsTarballOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform images. - PlatformVariants []*Container - // Force each layer of the image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the image's layers. - // - // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. - MediaTypes ImageMediaTypes -} - -// Returns a File representing the container serialized to a tarball. -func (r *Container) AsTarball(opts ...ContainerAsTarballOpts) *File { - q := r.query.Select("asTarball") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - - return &File{ - query: q, - } -} - -// ContainerBuildOpts contains options for Container.Build -type ContainerBuildOpts struct { - // Path to the Dockerfile to use. - Dockerfile string - // Target build stage to build. - Target string - // Additional build arguments. - BuildArgs []BuildArg - // Secrets to pass to the build. - // - // They will be mounted at /run/secrets/[secret-name] in the build container - // - // They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl [http://example.com?token=$(cat /run/secrets/my-secret)](http://example.com?token=$(cat /run/secrets/my-secret)) - Secrets []*Secret -} - -// Initializes this container from a Dockerfile build. -func (r *Container) Build(context *Directory, opts ...ContainerBuildOpts) *Container { - assertNotNil("context", context) - q := r.query.Select("build") - for i := len(opts) - 1; i >= 0; i-- { - // `dockerfile` optional argument - if !querybuilder.IsZeroValue(opts[i].Dockerfile) { - q = q.Arg("dockerfile", opts[i].Dockerfile) - } - // `target` optional argument - if !querybuilder.IsZeroValue(opts[i].Target) { - q = q.Arg("target", opts[i].Target) - } - // `buildArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].BuildArgs) { - q = q.Arg("buildArgs", opts[i].BuildArgs) - } - // `secrets` optional argument - if !querybuilder.IsZeroValue(opts[i].Secrets) { - q = q.Arg("secrets", opts[i].Secrets) - } - } - q = q.Arg("context", context) - - return &Container{ - query: q, - } -} - -// Retrieves default arguments for future commands. -func (r *Container) DefaultArgs(ctx context.Context) ([]string, error) { - q := r.query.Select("defaultArgs") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves a directory at the given path. -// -// Mounts are included. -func (r *Container) Directory(path string) *Directory { - q := r.query.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// Retrieves entrypoint to be prepended to the arguments of all commands. -func (r *Container) Entrypoint(ctx context.Context) ([]string, error) { - q := r.query.Select("entrypoint") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves the value of the specified environment variable. -func (r *Container) EnvVariable(ctx context.Context, name string) (string, error) { - if r.envVariable != nil { - return *r.envVariable, nil - } - q := r.query.Select("envVariable") - q = q.Arg("name", name) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves the list of environment variables passed to commands. -func (r *Container) EnvVariables(ctx context.Context) ([]EnvVariable, error) { - q := r.query.Select("envVariables") - - q = q.Select("id") - - type envVariables struct { - Id EnvVariableID - } - - convert := func(fields []envVariables) []EnvVariable { - out := []EnvVariable{} - - for i := range fields { - val := EnvVariable{id: &fields[i].Id} - val.query = q.Root().Select("loadEnvVariableFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []envVariables - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// EXPERIMENTAL API! Subject to change/removal at any time. -// -// Configures all available GPUs on the host to be accessible to this container. -// -// This currently works for Nvidia devices only. -func (r *Container) ExperimentalWithAllGPUs() *Container { - q := r.query.Select("experimentalWithAllGPUs") - - return &Container{ - query: q, - } -} - -// EXPERIMENTAL API! Subject to change/removal at any time. -// -// Configures the provided list of devices to be accessible to this container. -// -// This currently works for Nvidia devices only. -func (r *Container) ExperimentalWithGPU(devices []string) *Container { - q := r.query.Select("experimentalWithGPU") - q = q.Arg("devices", devices) - - return &Container{ - query: q, - } -} - -// ContainerExportOpts contains options for Container.Export -type ContainerExportOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform image. - PlatformVariants []*Container - // Force each layer of the exported image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the exported image's layers. - // - // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. - MediaTypes ImageMediaTypes -} - -// Writes the container as an OCI tarball to the destination file path on the host. -// -// It can also export platform variants. -func (r *Container) Export(ctx context.Context, path string, opts ...ContainerExportOpts) (string, error) { - if r.export != nil { - return *r.export, nil - } - q := r.query.Select("export") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - q = q.Arg("path", path) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves the list of exposed ports. -// -// This includes ports already exposed by the image, even if not explicitly added with dagger. -func (r *Container) ExposedPorts(ctx context.Context) ([]Port, error) { - q := r.query.Select("exposedPorts") - - q = q.Select("id") - - type exposedPorts struct { - Id PortID - } - - convert := func(fields []exposedPorts) []Port { - out := []Port{} - - for i := range fields { - val := Port{id: &fields[i].Id} - val.query = q.Root().Select("loadPortFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []exposedPorts - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Retrieves a file at the given path. -// -// Mounts are included. -func (r *Container) File(path string) *File { - q := r.query.Select("file") - q = q.Arg("path", path) - - return &File{ - query: q, - } -} - -// Initializes this container from a pulled base image. -func (r *Container) From(address string) *Container { - q := r.query.Select("from") - q = q.Arg("address", address) - - return &Container{ - query: q, - } -} - -// A unique identifier for this Container. -func (r *Container) ID(ctx context.Context) (ContainerID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ContainerID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Container) XXX_GraphQLType() string { - return "Container" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Container) XXX_GraphQLIDType() string { - return "ContainerID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Container) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Container) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Container) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadContainerFromID(ContainerID(id)) - return nil -} - -// The unique image reference which can only be retrieved immediately after the 'Container.From' call. -func (r *Container) ImageRef(ctx context.Context) (string, error) { - if r.imageRef != nil { - return *r.imageRef, nil - } - q := r.query.Select("imageRef") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// ContainerImportOpts contains options for Container.Import -type ContainerImportOpts struct { - // Identifies the tag to import from the archive, if the archive bundles multiple tags. - Tag string -} - -// Reads the container from an OCI tarball. -func (r *Container) Import(source *File, opts ...ContainerImportOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("import") - for i := len(opts) - 1; i >= 0; i-- { - // `tag` optional argument - if !querybuilder.IsZeroValue(opts[i].Tag) { - q = q.Arg("tag", opts[i].Tag) - } - } - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// Retrieves the value of the specified label. -func (r *Container) Label(ctx context.Context, name string) (string, error) { - if r.label != nil { - return *r.label, nil - } - q := r.query.Select("label") - q = q.Arg("name", name) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves the list of labels passed to container. -func (r *Container) Labels(ctx context.Context) ([]Label, error) { - q := r.query.Select("labels") - - q = q.Select("id") - - type labels struct { - Id LabelID - } - - convert := func(fields []labels) []Label { - out := []Label{} - - for i := range fields { - val := Label{id: &fields[i].Id} - val.query = q.Root().Select("loadLabelFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []labels - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Retrieves the list of paths where a directory is mounted. -func (r *Container) Mounts(ctx context.Context) ([]string, error) { - q := r.query.Select("mounts") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The platform this container executes and publishes as. -func (r *Container) Platform(ctx context.Context) (Platform, error) { - if r.platform != nil { - return *r.platform, nil - } - q := r.query.Select("platform") - - var response Platform - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// ContainerPublishOpts contains options for Container.Publish -type ContainerPublishOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform image. - PlatformVariants []*Container - // Force each layer of the published image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the published image's layers. - // - // Defaults to OCI, which is largely compatible with most recent registries, but Docker may be needed for older registries without OCI support. - MediaTypes ImageMediaTypes -} - -// Publishes this container as a new image to the specified address. -// -// Publish returns a fully qualified ref. -// -// It can also publish platform variants. -func (r *Container) Publish(ctx context.Context, address string, opts ...ContainerPublishOpts) (string, error) { - if r.publish != nil { - return *r.publish, nil - } - q := r.query.Select("publish") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - q = q.Arg("address", address) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves this container's root filesystem. Mounts are not included. -func (r *Container) Rootfs() *Directory { - q := r.query.Select("rootfs") - - return &Directory{ - query: q, - } -} - -// The error stream of the last executed command. -// -// Will execute default command if none is set, or error if there's no default. -func (r *Container) Stderr(ctx context.Context) (string, error) { - if r.stderr != nil { - return *r.stderr, nil - } - q := r.query.Select("stderr") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The output stream of the last executed command. -// -// Will execute default command if none is set, or error if there's no default. -func (r *Container) Stdout(ctx context.Context) (string, error) { - if r.stdout != nil { - return *r.stdout, nil - } - q := r.query.Select("stdout") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Forces evaluation of the pipeline in the engine. -// -// It doesn't run the default command if no exec has been set. -func (r *Container) Sync(ctx context.Context) (*Container, error) { - q := r.query.Select("sync") - - var id ContainerID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &Container{ - query: q.Root().Select("loadContainerFromID").Arg("id", id), - }, nil -} - -// ContainerTerminalOpts contains options for Container.Terminal -type ContainerTerminalOpts struct { - // If set, override the container's default terminal command and invoke these command arguments instead. - Cmd []string - // Provides Dagger access to the executed command. - // - // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. - ExperimentalPrivilegedNesting bool - // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. - InsecureRootCapabilities bool -} - -// Opens an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default). -func (r *Container) Terminal(opts ...ContainerTerminalOpts) *Container { - q := r.query.Select("terminal") - for i := len(opts) - 1; i >= 0; i-- { - // `cmd` optional argument - if !querybuilder.IsZeroValue(opts[i].Cmd) { - q = q.Arg("cmd", opts[i].Cmd) - } - // `experimentalPrivilegedNesting` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { - q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) - } - // `insecureRootCapabilities` optional argument - if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { - q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) - } - } - - return &Container{ - query: q, - } -} - -// ContainerUpOpts contains options for Container.Up -type ContainerUpOpts struct { - // List of frontend/backend port mappings to forward. - // - // Frontend is the port accepting traffic on the host, backend is the service port. - Ports []PortForward - // Bind each tunnel port to a random port on the host. - Random bool -} - -// Starts a Service and creates a tunnel that forwards traffic from the caller's network to that service. -// -// Be sure to set any exposed ports before calling this api. -func (r *Container) Up(ctx context.Context, opts ...ContainerUpOpts) error { - if r.up != nil { - return nil - } - q := r.query.Select("up") - for i := len(opts) - 1; i >= 0; i-- { - // `ports` optional argument - if !querybuilder.IsZeroValue(opts[i].Ports) { - q = q.Arg("ports", opts[i].Ports) - } - // `random` optional argument - if !querybuilder.IsZeroValue(opts[i].Random) { - q = q.Arg("random", opts[i].Random) - } - } - - return q.Execute(ctx) -} - -// Retrieves the user to be set for all commands. -func (r *Container) User(ctx context.Context) (string, error) { - if r.user != nil { - return *r.user, nil - } - q := r.query.Select("user") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves this container plus the given OCI anotation. -func (r *Container) WithAnnotation(name string, value string) *Container { - q := r.query.Select("withAnnotation") - q = q.Arg("name", name) - q = q.Arg("value", value) - - return &Container{ - query: q, - } -} - -// Configures default arguments for future commands. -func (r *Container) WithDefaultArgs(args []string) *Container { - q := r.query.Select("withDefaultArgs") - q = q.Arg("args", args) - - return &Container{ - query: q, - } -} - -// ContainerWithDefaultTerminalCmdOpts contains options for Container.WithDefaultTerminalCmd -type ContainerWithDefaultTerminalCmdOpts struct { - // Provides Dagger access to the executed command. - // - // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. - ExperimentalPrivilegedNesting bool - // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. - InsecureRootCapabilities bool -} - -// Set the default command to invoke for the container's terminal API. -func (r *Container) WithDefaultTerminalCmd(args []string, opts ...ContainerWithDefaultTerminalCmdOpts) *Container { - q := r.query.Select("withDefaultTerminalCmd") - for i := len(opts) - 1; i >= 0; i-- { - // `experimentalPrivilegedNesting` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { - q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) - } - // `insecureRootCapabilities` optional argument - if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { - q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) - } - } - q = q.Arg("args", args) - - return &Container{ - query: q, - } -} - -// ContainerWithDirectoryOpts contains options for Container.WithDirectory -type ContainerWithDirectoryOpts struct { - // Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). - Exclude []string - // Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). - Include []string - // A user:group to set for the directory and its contents. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a directory written at the given path. -func (r *Container) WithDirectory(path string, directory *Directory, opts ...ContainerWithDirectoryOpts) *Container { - assertNotNil("directory", directory) - q := r.query.Select("withDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("directory", directory) - - return &Container{ - query: q, - } -} - -// ContainerWithEntrypointOpts contains options for Container.WithEntrypoint -type ContainerWithEntrypointOpts struct { - // Don't remove the default arguments when setting the entrypoint. - KeepDefaultArgs bool -} - -// Retrieves this container but with a different command entrypoint. -func (r *Container) WithEntrypoint(args []string, opts ...ContainerWithEntrypointOpts) *Container { - q := r.query.Select("withEntrypoint") - for i := len(opts) - 1; i >= 0; i-- { - // `keepDefaultArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { - q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) - } - } - q = q.Arg("args", args) - - return &Container{ - query: q, - } -} - -// ContainerWithEnvVariableOpts contains options for Container.WithEnvVariable -type ContainerWithEnvVariableOpts struct { - // Replace `${VAR}` or `$VAR` in the value according to the current environment variables defined in the container (e.g., "/opt/bin:$PATH"). - Expand bool -} - -// Retrieves this container plus the given environment variable. -func (r *Container) WithEnvVariable(name string, value string, opts ...ContainerWithEnvVariableOpts) *Container { - q := r.query.Select("withEnvVariable") - for i := len(opts) - 1; i >= 0; i-- { - // `expand` optional argument - if !querybuilder.IsZeroValue(opts[i].Expand) { - q = q.Arg("expand", opts[i].Expand) - } - } - q = q.Arg("name", name) - q = q.Arg("value", value) - - return &Container{ - query: q, - } -} - -// ContainerWithExecOpts contains options for Container.WithExec -type ContainerWithExecOpts struct { - // If the container has an entrypoint, prepend it to the args. - UseEntrypoint bool - // Content to write to the command's standard input before closing (e.g., "Hello world"). - Stdin string - // Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). - RedirectStdout string - // Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). - RedirectStderr string - // Provides Dagger access to the executed command. - // - // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. - ExperimentalPrivilegedNesting bool - // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. - InsecureRootCapabilities bool -} - -// Retrieves this container after executing the specified command inside it. -func (r *Container) WithExec(args []string, opts ...ContainerWithExecOpts) *Container { - q := r.query.Select("withExec") - for i := len(opts) - 1; i >= 0; i-- { - // `useEntrypoint` optional argument - if !querybuilder.IsZeroValue(opts[i].UseEntrypoint) { - q = q.Arg("useEntrypoint", opts[i].UseEntrypoint) - } - // `stdin` optional argument - if !querybuilder.IsZeroValue(opts[i].Stdin) { - q = q.Arg("stdin", opts[i].Stdin) - } - // `redirectStdout` optional argument - if !querybuilder.IsZeroValue(opts[i].RedirectStdout) { - q = q.Arg("redirectStdout", opts[i].RedirectStdout) - } - // `redirectStderr` optional argument - if !querybuilder.IsZeroValue(opts[i].RedirectStderr) { - q = q.Arg("redirectStderr", opts[i].RedirectStderr) - } - // `experimentalPrivilegedNesting` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { - q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) - } - // `insecureRootCapabilities` optional argument - if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { - q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) - } - } - q = q.Arg("args", args) - - return &Container{ - query: q, - } -} - -// ContainerWithExposedPortOpts contains options for Container.WithExposedPort -type ContainerWithExposedPortOpts struct { - // Transport layer network protocol - Protocol NetworkProtocol - // Optional port description - Description string - // Skip the health check when run as a service. - ExperimentalSkipHealthcheck bool -} - -// Expose a network port. -// -// Exposed ports serve two purposes: -// -// - For health checks and introspection, when running services -// -// - For setting the EXPOSE OCI field when publishing the container -func (r *Container) WithExposedPort(port int, opts ...ContainerWithExposedPortOpts) *Container { - q := r.query.Select("withExposedPort") - for i := len(opts) - 1; i >= 0; i-- { - // `protocol` optional argument - if !querybuilder.IsZeroValue(opts[i].Protocol) { - q = q.Arg("protocol", opts[i].Protocol) - } - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `experimentalSkipHealthcheck` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalSkipHealthcheck) { - q = q.Arg("experimentalSkipHealthcheck", opts[i].ExperimentalSkipHealthcheck) - } - } - q = q.Arg("port", port) - - return &Container{ - query: q, - } -} - -// ContainerWithFileOpts contains options for Container.WithFile -type ContainerWithFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int - // A user:group to set for the file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus the contents of the given file copied to the given path. -func (r *Container) WithFile(path string, source *File, opts ...ContainerWithFileOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("withFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// ContainerWithFilesOpts contains options for Container.WithFiles -type ContainerWithFilesOpts struct { - // Permission given to the copied files (e.g., 0600). - Permissions int - // A user:group to set for the files. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus the contents of the given files copied to the given path. -func (r *Container) WithFiles(path string, sources []*File, opts ...ContainerWithFilesOpts) *Container { - q := r.query.Select("withFiles") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("sources", sources) - - return &Container{ - query: q, - } -} - -// Indicate that subsequent operations should be featured more prominently in the UI. -func (r *Container) WithFocus() *Container { - q := r.query.Select("withFocus") - - return &Container{ - query: q, - } -} - -// Retrieves this container plus the given label. -func (r *Container) WithLabel(name string, value string) *Container { - q := r.query.Select("withLabel") - q = q.Arg("name", name) - q = q.Arg("value", value) - - return &Container{ - query: q, - } -} - -// ContainerWithMountedCacheOpts contains options for Container.WithMountedCache -type ContainerWithMountedCacheOpts struct { - // Identifier of the directory to use as the cache volume's root. - Source *Directory - // Sharing mode of the cache volume. - Sharing CacheSharingMode - // A user:group to set for the mounted cache directory. - // - // Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a cache volume mounted at the given path. -func (r *Container) WithMountedCache(path string, cache *CacheVolume, opts ...ContainerWithMountedCacheOpts) *Container { - assertNotNil("cache", cache) - q := r.query.Select("withMountedCache") - for i := len(opts) - 1; i >= 0; i-- { - // `source` optional argument - if !querybuilder.IsZeroValue(opts[i].Source) { - q = q.Arg("source", opts[i].Source) - } - // `sharing` optional argument - if !querybuilder.IsZeroValue(opts[i].Sharing) { - q = q.Arg("sharing", opts[i].Sharing) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("cache", cache) - - return &Container{ - query: q, - } -} - -// ContainerWithMountedDirectoryOpts contains options for Container.WithMountedDirectory -type ContainerWithMountedDirectoryOpts struct { - // A user:group to set for the mounted directory and its contents. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a directory mounted at the given path. -func (r *Container) WithMountedDirectory(path string, source *Directory, opts ...ContainerWithMountedDirectoryOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("withMountedDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// ContainerWithMountedFileOpts contains options for Container.WithMountedFile -type ContainerWithMountedFileOpts struct { - // A user or user:group to set for the mounted file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a file mounted at the given path. -func (r *Container) WithMountedFile(path string, source *File, opts ...ContainerWithMountedFileOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("withMountedFile") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// ContainerWithMountedSecretOpts contains options for Container.WithMountedSecret -type ContainerWithMountedSecretOpts struct { - // A user:group to set for the mounted secret. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string - // Permission given to the mounted secret (e.g., 0600). - // - // This option requires an owner to be set to be active. - Mode int -} - -// Retrieves this container plus a secret mounted into a file at the given path. -func (r *Container) WithMountedSecret(path string, source *Secret, opts ...ContainerWithMountedSecretOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("withMountedSecret") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - // `mode` optional argument - if !querybuilder.IsZeroValue(opts[i].Mode) { - q = q.Arg("mode", opts[i].Mode) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// Retrieves this container plus a temporary directory mounted at the given path. Any writes will be ephemeral to a single withExec call; they will not be persisted to subsequent withExecs. -func (r *Container) WithMountedTemp(path string) *Container { - q := r.query.Select("withMountedTemp") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// ContainerWithNewFileOpts contains options for Container.WithNewFile -type ContainerWithNewFileOpts struct { - // Permission given to the written file (e.g., 0600). - Permissions int - // A user:group to set for the file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a new file written at the given path. -func (r *Container) WithNewFile(path string, contents string, opts ...ContainerWithNewFileOpts) *Container { - q := r.query.Select("withNewFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("contents", contents) - - return &Container{ - query: q, - } -} - -// Retrieves this container with a registry authentication for a given address. -func (r *Container) WithRegistryAuth(address string, username string, secret *Secret) *Container { - assertNotNil("secret", secret) - q := r.query.Select("withRegistryAuth") - q = q.Arg("address", address) - q = q.Arg("username", username) - q = q.Arg("secret", secret) - - return &Container{ - query: q, - } -} - -// Retrieves the container with the given directory mounted to /. -func (r *Container) WithRootfs(directory *Directory) *Container { - assertNotNil("directory", directory) - q := r.query.Select("withRootfs") - q = q.Arg("directory", directory) - - return &Container{ - query: q, - } -} - -// Retrieves this container plus an env variable containing the given secret. -func (r *Container) WithSecretVariable(name string, secret *Secret) *Container { - assertNotNil("secret", secret) - q := r.query.Select("withSecretVariable") - q = q.Arg("name", name) - q = q.Arg("secret", secret) - - return &Container{ - query: q, - } -} - -// Establish a runtime dependency on a service. -// -// The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set. -// -// The service will be reachable from the container via the provided hostname alias. -// -// The service dependency will also convey to any files or directories produced by the container. -func (r *Container) WithServiceBinding(alias string, service *Service) *Container { - assertNotNil("service", service) - q := r.query.Select("withServiceBinding") - q = q.Arg("alias", alias) - q = q.Arg("service", service) - - return &Container{ - query: q, - } -} - -// ContainerWithUnixSocketOpts contains options for Container.WithUnixSocket -type ContainerWithUnixSocketOpts struct { - // A user:group to set for the mounted socket. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a socket forwarded to the given Unix socket path. -func (r *Container) WithUnixSocket(path string, source *Socket, opts ...ContainerWithUnixSocketOpts) *Container { - assertNotNil("source", source) - q := r.query.Select("withUnixSocket") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - query: q, - } -} - -// Retrieves this container with a different command user. -func (r *Container) WithUser(name string) *Container { - q := r.query.Select("withUser") - q = q.Arg("name", name) - - return &Container{ - query: q, - } -} - -// Retrieves this container with a different working directory. -func (r *Container) WithWorkdir(path string) *Container { - q := r.query.Select("withWorkdir") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// Retrieves this container minus the given OCI annotation. -func (r *Container) WithoutAnnotation(name string) *Container { - q := r.query.Select("withoutAnnotation") - q = q.Arg("name", name) - - return &Container{ - query: q, - } -} - -// Retrieves this container with unset default arguments for future commands. -func (r *Container) WithoutDefaultArgs() *Container { - q := r.query.Select("withoutDefaultArgs") - - return &Container{ - query: q, - } -} - -// Retrieves this container with the directory at the given path removed. -func (r *Container) WithoutDirectory(path string) *Container { - q := r.query.Select("withoutDirectory") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// ContainerWithoutEntrypointOpts contains options for Container.WithoutEntrypoint -type ContainerWithoutEntrypointOpts struct { - // Don't remove the default arguments when unsetting the entrypoint. - KeepDefaultArgs bool -} - -// Retrieves this container with an unset command entrypoint. -func (r *Container) WithoutEntrypoint(opts ...ContainerWithoutEntrypointOpts) *Container { - q := r.query.Select("withoutEntrypoint") - for i := len(opts) - 1; i >= 0; i-- { - // `keepDefaultArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { - q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) - } - } - - return &Container{ - query: q, - } -} - -// Retrieves this container minus the given environment variable. -func (r *Container) WithoutEnvVariable(name string) *Container { - q := r.query.Select("withoutEnvVariable") - q = q.Arg("name", name) - - return &Container{ - query: q, - } -} - -// ContainerWithoutExposedPortOpts contains options for Container.WithoutExposedPort -type ContainerWithoutExposedPortOpts struct { - // Port protocol to unexpose - Protocol NetworkProtocol -} - -// Unexpose a previously exposed port. -func (r *Container) WithoutExposedPort(port int, opts ...ContainerWithoutExposedPortOpts) *Container { - q := r.query.Select("withoutExposedPort") - for i := len(opts) - 1; i >= 0; i-- { - // `protocol` optional argument - if !querybuilder.IsZeroValue(opts[i].Protocol) { - q = q.Arg("protocol", opts[i].Protocol) - } - } - q = q.Arg("port", port) - - return &Container{ - query: q, - } -} - -// Retrieves this container with the file at the given path removed. -func (r *Container) WithoutFile(path string) *Container { - q := r.query.Select("withoutFile") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// Retrieves this container with the files at the given paths removed. -func (r *Container) WithoutFiles(paths []string) *Container { - q := r.query.Select("withoutFiles") - q = q.Arg("paths", paths) - - return &Container{ - query: q, - } -} - -// Indicate that subsequent operations should not be featured more prominently in the UI. -// -// This is the initial state of all containers. -func (r *Container) WithoutFocus() *Container { - q := r.query.Select("withoutFocus") - - return &Container{ - query: q, - } -} - -// Retrieves this container minus the given environment label. -func (r *Container) WithoutLabel(name string) *Container { - q := r.query.Select("withoutLabel") - q = q.Arg("name", name) - - return &Container{ - query: q, - } -} - -// Retrieves this container after unmounting everything at the given path. -func (r *Container) WithoutMount(path string) *Container { - q := r.query.Select("withoutMount") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// Retrieves this container without the registry authentication of a given address. -func (r *Container) WithoutRegistryAuth(address string) *Container { - q := r.query.Select("withoutRegistryAuth") - q = q.Arg("address", address) - - return &Container{ - query: q, - } -} - -// Retrieves this container minus the given environment variable containing the secret. -func (r *Container) WithoutSecretVariable(name string) *Container { - q := r.query.Select("withoutSecretVariable") - q = q.Arg("name", name) - - return &Container{ - query: q, - } -} - -// Retrieves this container with a previously added Unix socket removed. -func (r *Container) WithoutUnixSocket(path string) *Container { - q := r.query.Select("withoutUnixSocket") - q = q.Arg("path", path) - - return &Container{ - query: q, - } -} - -// Retrieves this container with an unset command user. -// -// Should default to root. -func (r *Container) WithoutUser() *Container { - q := r.query.Select("withoutUser") - - return &Container{ - query: q, - } -} - -// Retrieves this container with an unset working directory. -// -// Should default to "/". -func (r *Container) WithoutWorkdir() *Container { - q := r.query.Select("withoutWorkdir") - - return &Container{ - query: q, - } -} - -// Retrieves the working directory for all commands. -func (r *Container) Workdir(ctx context.Context) (string, error) { - if r.workdir != nil { - return *r.workdir, nil - } - q := r.query.Select("workdir") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Cosign represents the cosign Dagger module type -type Cosign struct { - query *querybuilder.Selection - - id *CosignID -} - -func (r *Cosign) WithGraphQLQuery(q *querybuilder.Selection) *Cosign { - return &Cosign{ - query: q, - } -} - -// A unique identifier for this Cosign. -func (r *Cosign) ID(ctx context.Context) (CosignID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response CosignID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Cosign) XXX_GraphQLType() string { - return "Cosign" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Cosign) XXX_GraphQLIDType() string { - return "CosignID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Cosign) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Cosign) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Cosign) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadCosignFromID(CosignID(id)) - return nil -} - -// CosignSignOpts contains options for Cosign.Sign -type CosignSignOpts struct { - // - // registry username - // - RegistryUsername string - // - // name of the image - // - RegistryPassword *Secret - // - // Docker config - // - DockerConfig *File - // - // Cosign container image - // - CosignImage string - // - // Cosign container image user - // - CosignUser string -} - -// Sign will run cosign from the image, as defined by the cosignImage -// parameter, to sign the given Container image digests -// -// Note: keyless signing not supported as-is -// -// See https://edu.chainguard.dev/open-source/sigstore/cosign/an-introduction-to-cosign/ -func (r *Cosign) Sign(ctx context.Context, privateKey *Secret, password *Secret, digests []string, opts ...CosignSignOpts) ([]string, error) { - assertNotNil("privateKey", privateKey) - assertNotNil("password", password) - q := r.query.Select("sign") - for i := len(opts) - 1; i >= 0; i-- { - // `registryUsername` optional argument - if !querybuilder.IsZeroValue(opts[i].RegistryUsername) { - q = q.Arg("registryUsername", opts[i].RegistryUsername) - } - // `registryPassword` optional argument - if !querybuilder.IsZeroValue(opts[i].RegistryPassword) { - q = q.Arg("registryPassword", opts[i].RegistryPassword) - } - // `dockerConfig` optional argument - if !querybuilder.IsZeroValue(opts[i].DockerConfig) { - q = q.Arg("dockerConfig", opts[i].DockerConfig) - } - // `cosignImage` optional argument - if !querybuilder.IsZeroValue(opts[i].CosignImage) { - q = q.Arg("cosignImage", opts[i].CosignImage) - } - // `cosignUser` optional argument - if !querybuilder.IsZeroValue(opts[i].CosignUser) { - q = q.Arg("cosignUser", opts[i].CosignUser) - } - } - q = q.Arg("privateKey", privateKey) - q = q.Arg("password", password) - q = q.Arg("digests", digests) - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Reflective module API provided to functions at runtime. -type CurrentModule struct { - query *querybuilder.Selection - - id *CurrentModuleID - name *string -} - -func (r *CurrentModule) WithGraphQLQuery(q *querybuilder.Selection) *CurrentModule { - return &CurrentModule{ - query: q, - } -} - -// A unique identifier for this CurrentModule. -func (r *CurrentModule) ID(ctx context.Context) (CurrentModuleID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response CurrentModuleID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *CurrentModule) XXX_GraphQLType() string { - return "CurrentModule" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *CurrentModule) XXX_GraphQLIDType() string { - return "CurrentModuleID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *CurrentModule) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *CurrentModule) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *CurrentModule) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadCurrentModuleFromID(CurrentModuleID(id)) - return nil -} - -// The name of the module being executed in -func (r *CurrentModule) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). -func (r *CurrentModule) Source() *Directory { - q := r.query.Select("source") - - return &Directory{ - query: q, - } -} - -// CurrentModuleWorkdirOpts contains options for CurrentModule.Workdir -type CurrentModuleWorkdirOpts struct { - // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). - Exclude []string - // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). - Include []string -} - -// Load a directory from the module's scratch working directory, including any changes that may have been made to it during module function execution. -func (r *CurrentModule) Workdir(path string, opts ...CurrentModuleWorkdirOpts) *Directory { - q := r.query.Select("workdir") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - } - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution.Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution. -func (r *CurrentModule) WorkdirFile(path string) *File { - q := r.query.Select("workdirFile") - q = q.Arg("path", path) - - return &File{ - query: q, - } -} - -// A cache storage for the Dagger engine -type DaggerEngineCache struct { - query *querybuilder.Selection - - id *DaggerEngineCacheID - keepBytes *int - prune *Void -} - -func (r *DaggerEngineCache) WithGraphQLQuery(q *querybuilder.Selection) *DaggerEngineCache { - return &DaggerEngineCache{ - query: q, - } -} - -// The current set of entries in the cache -func (r *DaggerEngineCache) EntrySet() *DaggerEngineCacheEntrySet { - q := r.query.Select("entrySet") - - return &DaggerEngineCacheEntrySet{ - query: q, - } -} - -// A unique identifier for this DaggerEngineCache. -func (r *DaggerEngineCache) ID(ctx context.Context) (DaggerEngineCacheID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response DaggerEngineCacheID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *DaggerEngineCache) XXX_GraphQLType() string { - return "DaggerEngineCache" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *DaggerEngineCache) XXX_GraphQLIDType() string { - return "DaggerEngineCacheID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *DaggerEngineCache) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *DaggerEngineCache) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *DaggerEngineCache) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadDaggerEngineCacheFromID(DaggerEngineCacheID(id)) - return nil -} - -// The maximum bytes to keep in the cache without pruning, after which automatic pruning may kick in. -func (r *DaggerEngineCache) KeepBytes(ctx context.Context) (int, error) { - if r.keepBytes != nil { - return *r.keepBytes, nil - } - q := r.query.Select("keepBytes") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Prune the cache of releaseable entries -func (r *DaggerEngineCache) Prune(ctx context.Context) error { - if r.prune != nil { - return nil - } - q := r.query.Select("prune") - - return q.Execute(ctx) -} - -// An individual cache entry in a cache entry set -type DaggerEngineCacheEntry struct { - query *querybuilder.Selection - - activelyUsed *bool - createdTimeUnixNano *int - description *string - diskSpaceBytes *int - id *DaggerEngineCacheEntryID - mostRecentUseTimeUnixNano *int -} - -func (r *DaggerEngineCacheEntry) WithGraphQLQuery(q *querybuilder.Selection) *DaggerEngineCacheEntry { - return &DaggerEngineCacheEntry{ - query: q, - } -} - -// Whether the cache entry is actively being used. -func (r *DaggerEngineCacheEntry) ActivelyUsed(ctx context.Context) (bool, error) { - if r.activelyUsed != nil { - return *r.activelyUsed, nil - } - q := r.query.Select("activelyUsed") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The time the cache entry was created, in Unix nanoseconds. -func (r *DaggerEngineCacheEntry) CreatedTimeUnixNano(ctx context.Context) (int, error) { - if r.createdTimeUnixNano != nil { - return *r.createdTimeUnixNano, nil - } - q := r.query.Select("createdTimeUnixNano") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The description of the cache entry. -func (r *DaggerEngineCacheEntry) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The disk space used by the cache entry. -func (r *DaggerEngineCacheEntry) DiskSpaceBytes(ctx context.Context) (int, error) { - if r.diskSpaceBytes != nil { - return *r.diskSpaceBytes, nil - } - q := r.query.Select("diskSpaceBytes") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this DaggerEngineCacheEntry. -func (r *DaggerEngineCacheEntry) ID(ctx context.Context) (DaggerEngineCacheEntryID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response DaggerEngineCacheEntryID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *DaggerEngineCacheEntry) XXX_GraphQLType() string { - return "DaggerEngineCacheEntry" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *DaggerEngineCacheEntry) XXX_GraphQLIDType() string { - return "DaggerEngineCacheEntryID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *DaggerEngineCacheEntry) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *DaggerEngineCacheEntry) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *DaggerEngineCacheEntry) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadDaggerEngineCacheEntryFromID(DaggerEngineCacheEntryID(id)) - return nil -} - -// The most recent time the cache entry was used, in Unix nanoseconds. -func (r *DaggerEngineCacheEntry) MostRecentUseTimeUnixNano(ctx context.Context) (int, error) { - if r.mostRecentUseTimeUnixNano != nil { - return *r.mostRecentUseTimeUnixNano, nil - } - q := r.query.Select("mostRecentUseTimeUnixNano") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A set of cache entries returned by a query to a cache -type DaggerEngineCacheEntrySet struct { - query *querybuilder.Selection - - diskSpaceBytes *int - entryCount *int - id *DaggerEngineCacheEntrySetID -} - -func (r *DaggerEngineCacheEntrySet) WithGraphQLQuery(q *querybuilder.Selection) *DaggerEngineCacheEntrySet { - return &DaggerEngineCacheEntrySet{ - query: q, - } -} - -// The total disk space used by the cache entries in this set. -func (r *DaggerEngineCacheEntrySet) DiskSpaceBytes(ctx context.Context) (int, error) { - if r.diskSpaceBytes != nil { - return *r.diskSpaceBytes, nil - } - q := r.query.Select("diskSpaceBytes") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The list of individual cache entries in the set -func (r *DaggerEngineCacheEntrySet) Entries(ctx context.Context) ([]DaggerEngineCacheEntry, error) { - q := r.query.Select("entries") - - q = q.Select("id") - - type entries struct { - Id DaggerEngineCacheEntryID - } - - convert := func(fields []entries) []DaggerEngineCacheEntry { - out := []DaggerEngineCacheEntry{} - - for i := range fields { - val := DaggerEngineCacheEntry{id: &fields[i].Id} - val.query = q.Root().Select("loadDaggerEngineCacheEntryFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []entries - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The number of cache entries in this set. -func (r *DaggerEngineCacheEntrySet) EntryCount(ctx context.Context) (int, error) { - if r.entryCount != nil { - return *r.entryCount, nil - } - q := r.query.Select("entryCount") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this DaggerEngineCacheEntrySet. -func (r *DaggerEngineCacheEntrySet) ID(ctx context.Context) (DaggerEngineCacheEntrySetID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response DaggerEngineCacheEntrySetID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *DaggerEngineCacheEntrySet) XXX_GraphQLType() string { - return "DaggerEngineCacheEntrySet" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *DaggerEngineCacheEntrySet) XXX_GraphQLIDType() string { - return "DaggerEngineCacheEntrySetID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *DaggerEngineCacheEntrySet) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *DaggerEngineCacheEntrySet) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *DaggerEngineCacheEntrySet) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadDaggerEngineCacheEntrySetFromID(DaggerEngineCacheEntrySetID(id)) - return nil -} - -// A directory. -type Directory struct { - query *querybuilder.Selection - - digest *string - export *string - id *DirectoryID - sync *DirectoryID -} -type WithDirectoryFunc func(r *Directory) *Directory - -// With calls the provided function with current Directory. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Directory) With(f WithDirectoryFunc) *Directory { - return f(r) -} - -func (r *Directory) WithGraphQLQuery(q *querybuilder.Selection) *Directory { - return &Directory{ - query: q, - } -} - -// DirectoryAsModuleOpts contains options for Directory.AsModule -type DirectoryAsModuleOpts struct { - // An optional subpath of the directory which contains the module's configuration file. - // - // This is needed when the module code is in a subdirectory but requires parent directories to be loaded in order to execute. For example, the module source code may need a go.mod, project.toml, package.json, etc. file from a parent directory. - // - // If not set, the module source code is loaded from the root of the directory. - SourceRootPath string - // The engine version to upgrade to. - EngineVersion string -} - -// Load the directory as a Dagger module -func (r *Directory) AsModule(opts ...DirectoryAsModuleOpts) *Module { - q := r.query.Select("asModule") - for i := len(opts) - 1; i >= 0; i-- { - // `sourceRootPath` optional argument - if !querybuilder.IsZeroValue(opts[i].SourceRootPath) { - q = q.Arg("sourceRootPath", opts[i].SourceRootPath) - } - // `engineVersion` optional argument - if !querybuilder.IsZeroValue(opts[i].EngineVersion) { - q = q.Arg("engineVersion", opts[i].EngineVersion) - } - } - - return &Module{ - query: q, - } -} - -// Gets the difference between this directory and an another directory. -func (r *Directory) Diff(other *Directory) *Directory { - assertNotNil("other", other) - q := r.query.Select("diff") - q = q.Arg("other", other) - - return &Directory{ - query: q, - } -} - -// Return the directory's digest. The format of the digest is not guaranteed to be stable between releases of Dagger. It is guaranteed to be stable between invocations of the same Dagger engine. -func (r *Directory) Digest(ctx context.Context) (string, error) { - if r.digest != nil { - return *r.digest, nil - } - q := r.query.Select("digest") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves a directory at the given path. -func (r *Directory) Directory(path string) *Directory { - q := r.query.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// DirectoryDockerBuildOpts contains options for Directory.DockerBuild -type DirectoryDockerBuildOpts struct { - // The platform to build. - Platform Platform - // Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). - Dockerfile string - // Target build stage to build. - Target string - // Build arguments to use in the build. - BuildArgs []BuildArg - // Secrets to pass to the build. - // - // They will be mounted at /run/secrets/[secret-name]. - Secrets []*Secret -} - -// Builds a new Docker container from this directory. -func (r *Directory) DockerBuild(opts ...DirectoryDockerBuildOpts) *Container { - q := r.query.Select("dockerBuild") - for i := len(opts) - 1; i >= 0; i-- { - // `platform` optional argument - if !querybuilder.IsZeroValue(opts[i].Platform) { - q = q.Arg("platform", opts[i].Platform) - } - // `dockerfile` optional argument - if !querybuilder.IsZeroValue(opts[i].Dockerfile) { - q = q.Arg("dockerfile", opts[i].Dockerfile) - } - // `target` optional argument - if !querybuilder.IsZeroValue(opts[i].Target) { - q = q.Arg("target", opts[i].Target) - } - // `buildArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].BuildArgs) { - q = q.Arg("buildArgs", opts[i].BuildArgs) - } - // `secrets` optional argument - if !querybuilder.IsZeroValue(opts[i].Secrets) { - q = q.Arg("secrets", opts[i].Secrets) - } - } - - return &Container{ - query: q, - } -} - -// DirectoryEntriesOpts contains options for Directory.Entries -type DirectoryEntriesOpts struct { - // Location of the directory to look at (e.g., "/src"). - Path string -} - -// Returns a list of files and directories at the given path. -func (r *Directory) Entries(ctx context.Context, opts ...DirectoryEntriesOpts) ([]string, error) { - q := r.query.Select("entries") - for i := len(opts) - 1; i >= 0; i-- { - // `path` optional argument - if !querybuilder.IsZeroValue(opts[i].Path) { - q = q.Arg("path", opts[i].Path) - } - } - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// DirectoryExportOpts contains options for Directory.Export -type DirectoryExportOpts struct { - // If true, then the host directory will be wiped clean before exporting so that it exactly matches the directory being exported; this means it will delete any files on the host that aren't in the exported dir. If false (the default), the contents of the directory will be merged with any existing contents of the host directory, leaving any existing files on the host that aren't in the exported directory alone. - Wipe bool -} - -// Writes the contents of the directory to a path on the host. -func (r *Directory) Export(ctx context.Context, path string, opts ...DirectoryExportOpts) (string, error) { - if r.export != nil { - return *r.export, nil - } - q := r.query.Select("export") - for i := len(opts) - 1; i >= 0; i-- { - // `wipe` optional argument - if !querybuilder.IsZeroValue(opts[i].Wipe) { - q = q.Arg("wipe", opts[i].Wipe) - } - } - q = q.Arg("path", path) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves a file at the given path. -func (r *Directory) File(path string) *File { - q := r.query.Select("file") - q = q.Arg("path", path) - - return &File{ - query: q, - } -} - -// Returns a list of files and directories that matche the given pattern. -func (r *Directory) Glob(ctx context.Context, pattern string) ([]string, error) { - q := r.query.Select("glob") - q = q.Arg("pattern", pattern) - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this Directory. -func (r *Directory) ID(ctx context.Context) (DirectoryID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response DirectoryID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Directory) XXX_GraphQLType() string { - return "Directory" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Directory) XXX_GraphQLIDType() string { - return "DirectoryID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Directory) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Directory) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Directory) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadDirectoryFromID(DirectoryID(id)) - return nil -} - -// Force evaluation in the engine. -func (r *Directory) Sync(ctx context.Context) (*Directory, error) { - q := r.query.Select("sync") - - var id DirectoryID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &Directory{ - query: q.Root().Select("loadDirectoryFromID").Arg("id", id), - }, nil -} - -// DirectoryTerminalOpts contains options for Directory.Terminal -type DirectoryTerminalOpts struct { - // If set, override the container's default terminal command and invoke these command arguments instead. - Cmd []string - // Provides Dagger access to the executed command. - // - // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. - ExperimentalPrivilegedNesting bool - // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. - InsecureRootCapabilities bool - // If set, override the default container used for the terminal. - Container *Container -} - -// Opens an interactive terminal in new container with this directory mounted inside. -func (r *Directory) Terminal(opts ...DirectoryTerminalOpts) *Directory { - q := r.query.Select("terminal") - for i := len(opts) - 1; i >= 0; i-- { - // `cmd` optional argument - if !querybuilder.IsZeroValue(opts[i].Cmd) { - q = q.Arg("cmd", opts[i].Cmd) - } - // `experimentalPrivilegedNesting` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { - q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) - } - // `insecureRootCapabilities` optional argument - if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { - q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) - } - // `container` optional argument - if !querybuilder.IsZeroValue(opts[i].Container) { - q = q.Arg("container", opts[i].Container) - } - } - - return &Directory{ - query: q, - } -} - -// DirectoryWithDirectoryOpts contains options for Directory.WithDirectory -type DirectoryWithDirectoryOpts struct { - // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). - Exclude []string - // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). - Include []string -} - -// Retrieves this directory plus a directory written at the given path. -func (r *Directory) WithDirectory(path string, directory *Directory, opts ...DirectoryWithDirectoryOpts) *Directory { - assertNotNil("directory", directory) - q := r.query.Select("withDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - } - q = q.Arg("path", path) - q = q.Arg("directory", directory) - - return &Directory{ - query: q, - } -} - -// DirectoryWithFileOpts contains options for Directory.WithFile -type DirectoryWithFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus the contents of the given file copied to the given path. -func (r *Directory) WithFile(path string, source *File, opts ...DirectoryWithFileOpts) *Directory { - assertNotNil("source", source) - q := r.query.Select("withFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Directory{ - query: q, - } -} - -// DirectoryWithFilesOpts contains options for Directory.WithFiles -type DirectoryWithFilesOpts struct { - // Permission given to the copied files (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus the contents of the given files copied to the given path. -func (r *Directory) WithFiles(path string, sources []*File, opts ...DirectoryWithFilesOpts) *Directory { - q := r.query.Select("withFiles") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("sources", sources) - - return &Directory{ - query: q, - } -} - -// DirectoryWithNewDirectoryOpts contains options for Directory.WithNewDirectory -type DirectoryWithNewDirectoryOpts struct { - // Permission granted to the created directory (e.g., 0777). - Permissions int -} - -// Retrieves this directory plus a new directory created at the given path. -func (r *Directory) WithNewDirectory(path string, opts ...DirectoryWithNewDirectoryOpts) *Directory { - q := r.query.Select("withNewDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// DirectoryWithNewFileOpts contains options for Directory.WithNewFile -type DirectoryWithNewFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus a new file written at the given path. -func (r *Directory) WithNewFile(path string, contents string, opts ...DirectoryWithNewFileOpts) *Directory { - q := r.query.Select("withNewFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("contents", contents) - - return &Directory{ - query: q, - } -} - -// Retrieves this directory with all file/dir timestamps set to the given time. -func (r *Directory) WithTimestamps(timestamp int) *Directory { - q := r.query.Select("withTimestamps") - q = q.Arg("timestamp", timestamp) - - return &Directory{ - query: q, - } -} - -// Retrieves this directory with the directory at the given path removed. -func (r *Directory) WithoutDirectory(path string) *Directory { - q := r.query.Select("withoutDirectory") - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// Retrieves this directory with the file at the given path removed. -func (r *Directory) WithoutFile(path string) *Directory { - q := r.query.Select("withoutFile") - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// Retrieves this directory with the files at the given paths removed. -func (r *Directory) WithoutFiles(paths []string) *Directory { - q := r.query.Select("withoutFiles") - q = q.Arg("paths", paths) - - return &Directory{ - query: q, - } -} - -// A definition of a custom enum defined in a Module. -type EnumTypeDef struct { - query *querybuilder.Selection - - description *string - id *EnumTypeDefID - name *string - sourceModuleName *string -} - -func (r *EnumTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *EnumTypeDef { - return &EnumTypeDef{ - query: q, - } -} - -// A doc string for the enum, if any. -func (r *EnumTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this EnumTypeDef. -func (r *EnumTypeDef) ID(ctx context.Context) (EnumTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response EnumTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *EnumTypeDef) XXX_GraphQLType() string { - return "EnumTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *EnumTypeDef) XXX_GraphQLIDType() string { - return "EnumTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *EnumTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *EnumTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *EnumTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadEnumTypeDefFromID(EnumTypeDefID(id)) - return nil -} - -// The name of the enum. -func (r *EnumTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// If this EnumTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *EnumTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.query.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The values of the enum. -func (r *EnumTypeDef) Values(ctx context.Context) ([]EnumValueTypeDef, error) { - q := r.query.Select("values") - - q = q.Select("id") - - type values struct { - Id EnumValueTypeDefID - } - - convert := func(fields []values) []EnumValueTypeDef { - out := []EnumValueTypeDef{} - - for i := range fields { - val := EnumValueTypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadEnumValueTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []values - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A definition of a value in a custom enum defined in a Module. -type EnumValueTypeDef struct { - query *querybuilder.Selection - - description *string - id *EnumValueTypeDefID - name *string -} - -func (r *EnumValueTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *EnumValueTypeDef { - return &EnumValueTypeDef{ - query: q, - } -} - -// A doc string for the enum value, if any. -func (r *EnumValueTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this EnumValueTypeDef. -func (r *EnumValueTypeDef) ID(ctx context.Context) (EnumValueTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response EnumValueTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *EnumValueTypeDef) XXX_GraphQLType() string { - return "EnumValueTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *EnumValueTypeDef) XXX_GraphQLIDType() string { - return "EnumValueTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *EnumValueTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *EnumValueTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *EnumValueTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadEnumValueTypeDefFromID(EnumValueTypeDefID(id)) - return nil -} - -// The name of the enum value. -func (r *EnumValueTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// An environment variable name and value. -type EnvVariable struct { - query *querybuilder.Selection - - id *EnvVariableID - name *string - value *string -} - -func (r *EnvVariable) WithGraphQLQuery(q *querybuilder.Selection) *EnvVariable { - return &EnvVariable{ - query: q, - } -} - -// A unique identifier for this EnvVariable. -func (r *EnvVariable) ID(ctx context.Context) (EnvVariableID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response EnvVariableID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *EnvVariable) XXX_GraphQLType() string { - return "EnvVariable" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *EnvVariable) XXX_GraphQLIDType() string { - return "EnvVariableID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *EnvVariable) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *EnvVariable) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *EnvVariable) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadEnvVariableFromID(EnvVariableID(id)) - return nil -} - -// The environment variable name. -func (r *EnvVariable) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The environment variable value. -func (r *EnvVariable) Value(ctx context.Context) (string, error) { - if r.value != nil { - return *r.value, nil - } - q := r.query.Select("value") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A definition of a field on a custom object defined in a Module. -// -// A field on an object has a static value, as opposed to a function on an object whose value is computed by invoking code (and can accept arguments). -type FieldTypeDef struct { - query *querybuilder.Selection - - description *string - id *FieldTypeDefID - name *string -} - -func (r *FieldTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *FieldTypeDef { - return &FieldTypeDef{ - query: q, - } -} - -// A doc string for the field, if any. -func (r *FieldTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this FieldTypeDef. -func (r *FieldTypeDef) ID(ctx context.Context) (FieldTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FieldTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FieldTypeDef) XXX_GraphQLType() string { - return "FieldTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FieldTypeDef) XXX_GraphQLIDType() string { - return "FieldTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FieldTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FieldTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FieldTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFieldTypeDefFromID(FieldTypeDefID(id)) - return nil -} - -// The name of the field in lowerCamelCase format. -func (r *FieldTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The type of the field. -func (r *FieldTypeDef) TypeDef() *TypeDef { - q := r.query.Select("typeDef") - - return &TypeDef{ - query: q, - } -} - -// A file. -type File struct { - query *querybuilder.Selection - - contents *string - digest *string - export *string - id *FileID - name *string - size *int - sync *FileID -} -type WithFileFunc func(r *File) *File - -// With calls the provided function with current File. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *File) With(f WithFileFunc) *File { - return f(r) -} - -func (r *File) WithGraphQLQuery(q *querybuilder.Selection) *File { - return &File{ - query: q, - } -} - -// Retrieves the contents of the file. -func (r *File) Contents(ctx context.Context) (string, error) { - if r.contents != nil { - return *r.contents, nil - } - q := r.query.Select("contents") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// FileDigestOpts contains options for File.Digest -type FileDigestOpts struct { - // If true, exclude metadata from the digest. - ExcludeMetadata bool -} - -// Return the file's digest. The format of the digest is not guaranteed to be stable between releases of Dagger. It is guaranteed to be stable between invocations of the same Dagger engine. -func (r *File) Digest(ctx context.Context, opts ...FileDigestOpts) (string, error) { - if r.digest != nil { - return *r.digest, nil - } - q := r.query.Select("digest") - for i := len(opts) - 1; i >= 0; i-- { - // `excludeMetadata` optional argument - if !querybuilder.IsZeroValue(opts[i].ExcludeMetadata) { - q = q.Arg("excludeMetadata", opts[i].ExcludeMetadata) - } - } - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// FileExportOpts contains options for File.Export -type FileExportOpts struct { - // If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. - AllowParentDirPath bool -} - -// Writes the file to a file path on the host. -func (r *File) Export(ctx context.Context, path string, opts ...FileExportOpts) (string, error) { - if r.export != nil { - return *r.export, nil - } - q := r.query.Select("export") - for i := len(opts) - 1; i >= 0; i-- { - // `allowParentDirPath` optional argument - if !querybuilder.IsZeroValue(opts[i].AllowParentDirPath) { - q = q.Arg("allowParentDirPath", opts[i].AllowParentDirPath) - } - } - q = q.Arg("path", path) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this File. -func (r *File) ID(ctx context.Context) (FileID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FileID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *File) XXX_GraphQLType() string { - return "File" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *File) XXX_GraphQLIDType() string { - return "FileID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *File) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *File) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *File) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFileFromID(FileID(id)) - return nil -} - -// Retrieves the name of the file. -func (r *File) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves the size of the file, in bytes. -func (r *File) Size(ctx context.Context) (int, error) { - if r.size != nil { - return *r.size, nil - } - q := r.query.Select("size") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Force evaluation in the engine. -func (r *File) Sync(ctx context.Context) (*File, error) { - q := r.query.Select("sync") - - var id FileID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &File{ - query: q.Root().Select("loadFileFromID").Arg("id", id), - }, nil -} - -// Retrieves this file with its name set to the given name. -func (r *File) WithName(name string) *File { - q := r.query.Select("withName") - q = q.Arg("name", name) - - return &File{ - query: q, - } -} - -// Retrieves this file with its created/modified timestamps set to the given time. -func (r *File) WithTimestamps(timestamp int) *File { - q := r.query.Select("withTimestamps") - q = q.Arg("timestamp", timestamp) - - return &File{ - query: q, - } -} - -// Function represents a resolver provided by a Module. -// -// A function always evaluates against a parent object and is given a set of named arguments. -type Function struct { - query *querybuilder.Selection - - description *string - id *FunctionID - name *string -} -type WithFunctionFunc func(r *Function) *Function - -// With calls the provided function with current Function. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Function) With(f WithFunctionFunc) *Function { - return f(r) -} - -func (r *Function) WithGraphQLQuery(q *querybuilder.Selection) *Function { - return &Function{ - query: q, - } -} - -// Arguments accepted by the function, if any. -func (r *Function) Args(ctx context.Context) ([]FunctionArg, error) { - q := r.query.Select("args") - - q = q.Select("id") - - type args struct { - Id FunctionArgID - } - - convert := func(fields []args) []FunctionArg { - out := []FunctionArg{} - - for i := range fields { - val := FunctionArg{id: &fields[i].Id} - val.query = q.Root().Select("loadFunctionArgFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []args - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A doc string for the function, if any. -func (r *Function) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this Function. -func (r *Function) ID(ctx context.Context) (FunctionID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FunctionID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Function) XXX_GraphQLType() string { - return "Function" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Function) XXX_GraphQLIDType() string { - return "FunctionID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Function) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Function) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Function) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionFromID(FunctionID(id)) - return nil -} - -// The name of the function. -func (r *Function) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The type returned by the function. -func (r *Function) ReturnType() *TypeDef { - q := r.query.Select("returnType") - - return &TypeDef{ - query: q, - } -} - -// FunctionWithArgOpts contains options for Function.WithArg -type FunctionWithArgOpts struct { - // A doc string for the argument, if any - Description string - // A default value to use for this argument if not explicitly set by the caller, if any - DefaultValue JSON - // If the argument is a Directory or File type, default to load path from context directory, relative to root directory. - DefaultPath string - // Patterns to ignore when loading the contextual argument value. - Ignore []string -} - -// Returns the function with the provided argument -func (r *Function) WithArg(name string, typeDef *TypeDef, opts ...FunctionWithArgOpts) *Function { - assertNotNil("typeDef", typeDef) - q := r.query.Select("withArg") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `defaultValue` optional argument - if !querybuilder.IsZeroValue(opts[i].DefaultValue) { - q = q.Arg("defaultValue", opts[i].DefaultValue) - } - // `defaultPath` optional argument - if !querybuilder.IsZeroValue(opts[i].DefaultPath) { - q = q.Arg("defaultPath", opts[i].DefaultPath) - } - // `ignore` optional argument - if !querybuilder.IsZeroValue(opts[i].Ignore) { - q = q.Arg("ignore", opts[i].Ignore) - } - } - q = q.Arg("name", name) - q = q.Arg("typeDef", typeDef) - - return &Function{ - query: q, - } -} - -// Returns the function with the given doc string. -func (r *Function) WithDescription(description string) *Function { - q := r.query.Select("withDescription") - q = q.Arg("description", description) - - return &Function{ - query: q, - } -} - -// An argument accepted by a function. -// -// This is a specification for an argument at function definition time, not an argument passed at function call time. -type FunctionArg struct { - query *querybuilder.Selection - - defaultPath *string - defaultValue *JSON - description *string - id *FunctionArgID - name *string -} - -func (r *FunctionArg) WithGraphQLQuery(q *querybuilder.Selection) *FunctionArg { - return &FunctionArg{ - query: q, - } -} - -// Only applies to arguments of type File or Directory. If the argument is not set, load it from the given path in the context directory -func (r *FunctionArg) DefaultPath(ctx context.Context) (string, error) { - if r.defaultPath != nil { - return *r.defaultPath, nil - } - q := r.query.Select("defaultPath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A default value to use for this argument when not explicitly set by the caller, if any. -func (r *FunctionArg) DefaultValue(ctx context.Context) (JSON, error) { - if r.defaultValue != nil { - return *r.defaultValue, nil - } - q := r.query.Select("defaultValue") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A doc string for the argument, if any. -func (r *FunctionArg) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this FunctionArg. -func (r *FunctionArg) ID(ctx context.Context) (FunctionArgID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FunctionArgID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionArg) XXX_GraphQLType() string { - return "FunctionArg" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionArg) XXX_GraphQLIDType() string { - return "FunctionArgID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionArg) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionArg) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionArg) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionArgFromID(FunctionArgID(id)) - return nil -} - -// Only applies to arguments of type Directory. The ignore patterns are applied to the input directory, and matching entries are filtered out, in a cache-efficient manner. -func (r *FunctionArg) Ignore(ctx context.Context) ([]string, error) { - q := r.query.Select("ignore") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The name of the argument in lowerCamelCase format. -func (r *FunctionArg) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The type of the argument. -func (r *FunctionArg) TypeDef() *TypeDef { - q := r.query.Select("typeDef") - - return &TypeDef{ - query: q, - } -} - -// An active function call. -type FunctionCall struct { - query *querybuilder.Selection - - id *FunctionCallID - name *string - parent *JSON - parentName *string - returnValue *Void -} - -func (r *FunctionCall) WithGraphQLQuery(q *querybuilder.Selection) *FunctionCall { - return &FunctionCall{ - query: q, - } -} - -// A unique identifier for this FunctionCall. -func (r *FunctionCall) ID(ctx context.Context) (FunctionCallID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FunctionCallID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionCall) XXX_GraphQLType() string { - return "FunctionCall" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionCall) XXX_GraphQLIDType() string { - return "FunctionCallID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionCall) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionCall) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionCall) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionCallFromID(FunctionCallID(id)) - return nil -} - -// The argument values the function is being invoked with. -func (r *FunctionCall) InputArgs(ctx context.Context) ([]FunctionCallArgValue, error) { - q := r.query.Select("inputArgs") - - q = q.Select("id") - - type inputArgs struct { - Id FunctionCallArgValueID - } - - convert := func(fields []inputArgs) []FunctionCallArgValue { - out := []FunctionCallArgValue{} - - for i := range fields { - val := FunctionCallArgValue{id: &fields[i].Id} - val.query = q.Root().Select("loadFunctionCallArgValueFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []inputArgs - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The name of the function being called. -func (r *FunctionCall) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The value of the parent object of the function being called. If the function is top-level to the module, this is always an empty object. -func (r *FunctionCall) Parent(ctx context.Context) (JSON, error) { - if r.parent != nil { - return *r.parent, nil - } - q := r.query.Select("parent") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The name of the parent object of the function being called. If the function is top-level to the module, this is the name of the module. -func (r *FunctionCall) ParentName(ctx context.Context) (string, error) { - if r.parentName != nil { - return *r.parentName, nil - } - q := r.query.Select("parentName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Set the return value of the function call to the provided value. -func (r *FunctionCall) ReturnValue(ctx context.Context, value JSON) error { - if r.returnValue != nil { - return nil - } - q := r.query.Select("returnValue") - q = q.Arg("value", value) - - return q.Execute(ctx) -} - -// A value passed as a named argument to a function call. -type FunctionCallArgValue struct { - query *querybuilder.Selection - - id *FunctionCallArgValueID - name *string - value *JSON -} - -func (r *FunctionCallArgValue) WithGraphQLQuery(q *querybuilder.Selection) *FunctionCallArgValue { - return &FunctionCallArgValue{ - query: q, - } -} - -// A unique identifier for this FunctionCallArgValue. -func (r *FunctionCallArgValue) ID(ctx context.Context) (FunctionCallArgValueID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response FunctionCallArgValueID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionCallArgValue) XXX_GraphQLType() string { - return "FunctionCallArgValue" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionCallArgValue) XXX_GraphQLIDType() string { - return "FunctionCallArgValueID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionCallArgValue) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionCallArgValue) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionCallArgValue) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionCallArgValueFromID(FunctionCallArgValueID(id)) - return nil -} - -// The name of the argument. -func (r *FunctionCallArgValue) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The value of the argument represented as a JSON serialized string. -func (r *FunctionCallArgValue) Value(ctx context.Context) (JSON, error) { - if r.value != nil { - return *r.value, nil - } - q := r.query.Select("value") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The result of running an SDK's codegen. -type GeneratedCode struct { - query *querybuilder.Selection - - id *GeneratedCodeID -} -type WithGeneratedCodeFunc func(r *GeneratedCode) *GeneratedCode - -// With calls the provided function with current GeneratedCode. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *GeneratedCode) With(f WithGeneratedCodeFunc) *GeneratedCode { - return f(r) -} - -func (r *GeneratedCode) WithGraphQLQuery(q *querybuilder.Selection) *GeneratedCode { - return &GeneratedCode{ - query: q, - } -} - -// The directory containing the generated code. -func (r *GeneratedCode) Code() *Directory { - q := r.query.Select("code") - - return &Directory{ - query: q, - } -} - -// A unique identifier for this GeneratedCode. -func (r *GeneratedCode) ID(ctx context.Context) (GeneratedCodeID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response GeneratedCodeID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GeneratedCode) XXX_GraphQLType() string { - return "GeneratedCode" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GeneratedCode) XXX_GraphQLIDType() string { - return "GeneratedCodeID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GeneratedCode) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GeneratedCode) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GeneratedCode) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGeneratedCodeFromID(GeneratedCodeID(id)) - return nil -} - -// List of paths to mark generated in version control (i.e. .gitattributes). -func (r *GeneratedCode) VcsGeneratedPaths(ctx context.Context) ([]string, error) { - q := r.query.Select("vcsGeneratedPaths") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// List of paths to ignore in version control (i.e. .gitignore). -func (r *GeneratedCode) VcsIgnoredPaths(ctx context.Context) ([]string, error) { - q := r.query.Select("vcsIgnoredPaths") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Set the list of paths to mark generated in version control. -func (r *GeneratedCode) WithVCSGeneratedPaths(paths []string) *GeneratedCode { - q := r.query.Select("withVCSGeneratedPaths") - q = q.Arg("paths", paths) - - return &GeneratedCode{ - query: q, - } -} - -// Set the list of paths to ignore in version control. -func (r *GeneratedCode) WithVCSIgnoredPaths(paths []string) *GeneratedCode { - q := r.query.Select("withVCSIgnoredPaths") - q = q.Arg("paths", paths) - - return &GeneratedCode{ - query: q, - } -} - -// Module source originating from a git repo. -type GitModuleSource struct { - query *querybuilder.Selection - - cloneRef *string - commit *string - htmlRepoURL *string - htmlURL *string - id *GitModuleSourceID - root *string - rootSubpath *string - version *string -} - -func (r *GitModuleSource) WithGraphQLQuery(q *querybuilder.Selection) *GitModuleSource { - return &GitModuleSource{ - query: q, - } -} - -// The ref to clone the root of the git repo from -func (r *GitModuleSource) CloneRef(ctx context.Context) (string, error) { - if r.cloneRef != nil { - return *r.cloneRef, nil - } - q := r.query.Select("cloneRef") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The resolved commit of the git repo this source points to. -func (r *GitModuleSource) Commit(ctx context.Context) (string, error) { - if r.commit != nil { - return *r.commit, nil - } - q := r.query.Select("commit") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The directory containing everything needed to load load and use the module. -func (r *GitModuleSource) ContextDirectory() *Directory { - q := r.query.Select("contextDirectory") - - return &Directory{ - query: q, - } -} - -// The URL to access the web view of the repository (e.g., GitHub, GitLab, Bitbucket) -func (r *GitModuleSource) HTMLRepoURL(ctx context.Context) (string, error) { - if r.htmlRepoURL != nil { - return *r.htmlRepoURL, nil - } - q := r.query.Select("htmlRepoURL") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The URL to the source's git repo in a web browser -func (r *GitModuleSource) HTMLURL(ctx context.Context) (string, error) { - if r.htmlURL != nil { - return *r.htmlURL, nil - } - q := r.query.Select("htmlURL") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this GitModuleSource. -func (r *GitModuleSource) ID(ctx context.Context) (GitModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response GitModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitModuleSource) XXX_GraphQLType() string { - return "GitModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitModuleSource) XXX_GraphQLIDType() string { - return "GitModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitModuleSourceFromID(GitModuleSourceID(id)) - return nil -} - -// The clean module name of the root of the module -func (r *GitModuleSource) Root(ctx context.Context) (string, error) { - if r.root != nil { - return *r.root, nil - } - q := r.query.Select("root") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). -func (r *GitModuleSource) RootSubpath(ctx context.Context) (string, error) { - if r.rootSubpath != nil { - return *r.rootSubpath, nil - } - q := r.query.Select("rootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The specified version of the git repo this source points to. -func (r *GitModuleSource) Version(ctx context.Context) (string, error) { - if r.version != nil { - return *r.version, nil - } - q := r.query.Select("version") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A git ref (tag, branch, or commit). -type GitRef struct { - query *querybuilder.Selection - - commit *string - id *GitRefID -} - -func (r *GitRef) WithGraphQLQuery(q *querybuilder.Selection) *GitRef { - return &GitRef{ - query: q, - } -} - -// The resolved commit id at this ref. -func (r *GitRef) Commit(ctx context.Context) (string, error) { - if r.commit != nil { - return *r.commit, nil - } - q := r.query.Select("commit") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this GitRef. -func (r *GitRef) ID(ctx context.Context) (GitRefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response GitRefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitRef) XXX_GraphQLType() string { - return "GitRef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitRef) XXX_GraphQLIDType() string { - return "GitRefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitRef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitRef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitRef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitRefFromID(GitRefID(id)) - return nil -} - -// The filesystem tree at this ref. -func (r *GitRef) Tree() *Directory { - q := r.query.Select("tree") - - return &Directory{ - query: q, - } -} - -// A git repository. -type GitRepository struct { - query *querybuilder.Selection - - id *GitRepositoryID -} -type WithGitRepositoryFunc func(r *GitRepository) *GitRepository - -// With calls the provided function with current GitRepository. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *GitRepository) With(f WithGitRepositoryFunc) *GitRepository { - return f(r) -} - -func (r *GitRepository) WithGraphQLQuery(q *querybuilder.Selection) *GitRepository { - return &GitRepository{ - query: q, - } -} - -// Returns details of a branch. -func (r *GitRepository) Branch(name string) *GitRef { - q := r.query.Select("branch") - q = q.Arg("name", name) - - return &GitRef{ - query: q, - } -} - -// Returns details of a commit. -func (r *GitRepository) Commit(id string) *GitRef { - q := r.query.Select("commit") - q = q.Arg("id", id) - - return &GitRef{ - query: q, - } -} - -// Returns details for HEAD. -func (r *GitRepository) Head() *GitRef { - q := r.query.Select("head") - - return &GitRef{ - query: q, - } -} - -// A unique identifier for this GitRepository. -func (r *GitRepository) ID(ctx context.Context) (GitRepositoryID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response GitRepositoryID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitRepository) XXX_GraphQLType() string { - return "GitRepository" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitRepository) XXX_GraphQLIDType() string { - return "GitRepositoryID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitRepository) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitRepository) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitRepository) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitRepositoryFromID(GitRepositoryID(id)) - return nil -} - -// Returns details of a ref. -func (r *GitRepository) Ref(name string) *GitRef { - q := r.query.Select("ref") - q = q.Arg("name", name) - - return &GitRef{ - query: q, - } -} - -// Returns details of a tag. -func (r *GitRepository) Tag(name string) *GitRef { - q := r.query.Select("tag") - q = q.Arg("name", name) - - return &GitRef{ - query: q, - } -} - -// GitRepositoryTagsOpts contains options for GitRepository.Tags -type GitRepositoryTagsOpts struct { - // Glob patterns (e.g., "refs/tags/v*"). - Patterns []string -} - -// tags that match any of the given glob patterns. -func (r *GitRepository) Tags(ctx context.Context, opts ...GitRepositoryTagsOpts) ([]string, error) { - q := r.query.Select("tags") - for i := len(opts) - 1; i >= 0; i-- { - // `patterns` optional argument - if !querybuilder.IsZeroValue(opts[i].Patterns) { - q = q.Arg("patterns", opts[i].Patterns) - } - } - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Header to authenticate the remote with. -func (r *GitRepository) WithAuthHeader(header *Secret) *GitRepository { - assertNotNil("header", header) - q := r.query.Select("withAuthHeader") - q = q.Arg("header", header) - - return &GitRepository{ - query: q, - } -} - -// Token to authenticate the remote with. -func (r *GitRepository) WithAuthToken(token *Secret) *GitRepository { - assertNotNil("token", token) - q := r.query.Select("withAuthToken") - q = q.Arg("token", token) - - return &GitRepository{ - query: q, - } -} - -// A graphql input type, which is essentially just a group of named args. -// This is currently only used to represent pre-existing usage of graphql input types -// in the core API. It is not used by user modules and shouldn't ever be as user -// module accept input objects via their id rather than graphql input types. -type InputTypeDef struct { - query *querybuilder.Selection - - id *InputTypeDefID - name *string -} - -func (r *InputTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *InputTypeDef { - return &InputTypeDef{ - query: q, - } -} - -// Static fields defined on this input object, if any. -func (r *InputTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { - q := r.query.Select("fields") - - q = q.Select("id") - - type fields struct { - Id FieldTypeDefID - } - - convert := func(fields []fields) []FieldTypeDef { - out := []FieldTypeDef{} - - for i := range fields { - val := FieldTypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []fields - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this InputTypeDef. -func (r *InputTypeDef) ID(ctx context.Context) (InputTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response InputTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *InputTypeDef) XXX_GraphQLType() string { - return "InputTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *InputTypeDef) XXX_GraphQLIDType() string { - return "InputTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *InputTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *InputTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *InputTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadInputTypeDefFromID(InputTypeDefID(id)) - return nil -} - -// The name of the input object. -func (r *InputTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A definition of a custom interface defined in a Module. -type InterfaceTypeDef struct { - query *querybuilder.Selection - - description *string - id *InterfaceTypeDefID - name *string - sourceModuleName *string -} - -func (r *InterfaceTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *InterfaceTypeDef { - return &InterfaceTypeDef{ - query: q, - } -} - -// The doc string for the interface, if any. -func (r *InterfaceTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Functions defined on this interface, if any. -func (r *InterfaceTypeDef) Functions(ctx context.Context) ([]Function, error) { - q := r.query.Select("functions") - - q = q.Select("id") - - type functions struct { - Id FunctionID - } - - convert := func(fields []functions) []Function { - out := []Function{} - - for i := range fields { - val := Function{id: &fields[i].Id} - val.query = q.Root().Select("loadFunctionFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []functions - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this InterfaceTypeDef. -func (r *InterfaceTypeDef) ID(ctx context.Context) (InterfaceTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response InterfaceTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *InterfaceTypeDef) XXX_GraphQLType() string { - return "InterfaceTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *InterfaceTypeDef) XXX_GraphQLIDType() string { - return "InterfaceTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *InterfaceTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *InterfaceTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *InterfaceTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadInterfaceTypeDefFromID(InterfaceTypeDefID(id)) - return nil -} - -// The name of the interface. -func (r *InterfaceTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// If this InterfaceTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *InterfaceTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.query.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A simple key value object that represents a label. -type Label struct { - query *querybuilder.Selection - - id *LabelID - name *string - value *string -} - -func (r *Label) WithGraphQLQuery(q *querybuilder.Selection) *Label { - return &Label{ - query: q, - } -} - -// A unique identifier for this Label. -func (r *Label) ID(ctx context.Context) (LabelID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response LabelID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Label) XXX_GraphQLType() string { - return "Label" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Label) XXX_GraphQLIDType() string { - return "LabelID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Label) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Label) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Label) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadLabelFromID(LabelID(id)) - return nil -} - -// The label name. -func (r *Label) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The label value. -func (r *Label) Value(ctx context.Context) (string, error) { - if r.value != nil { - return *r.value, nil - } - q := r.query.Select("value") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A definition of a list type in a Module. -type ListTypeDef struct { - query *querybuilder.Selection - - id *ListTypeDefID -} - -func (r *ListTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *ListTypeDef { - return &ListTypeDef{ - query: q, - } -} - -// The type of the elements in the list. -func (r *ListTypeDef) ElementTypeDef() *TypeDef { - q := r.query.Select("elementTypeDef") - - return &TypeDef{ - query: q, - } -} - -// A unique identifier for this ListTypeDef. -func (r *ListTypeDef) ID(ctx context.Context) (ListTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ListTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ListTypeDef) XXX_GraphQLType() string { - return "ListTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ListTypeDef) XXX_GraphQLIDType() string { - return "ListTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ListTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ListTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ListTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadListTypeDefFromID(ListTypeDefID(id)) - return nil -} - -// Module source that that originates from a path locally relative to an arbitrary directory. -type LocalModuleSource struct { - query *querybuilder.Selection - - id *LocalModuleSourceID - relHostPath *string - rootSubpath *string -} - -func (r *LocalModuleSource) WithGraphQLQuery(q *querybuilder.Selection) *LocalModuleSource { - return &LocalModuleSource{ - query: q, - } -} - -// The directory containing everything needed to load load and use the module. -func (r *LocalModuleSource) ContextDirectory() *Directory { - q := r.query.Select("contextDirectory") - - return &Directory{ - query: q, - } -} - -// A unique identifier for this LocalModuleSource. -func (r *LocalModuleSource) ID(ctx context.Context) (LocalModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response LocalModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *LocalModuleSource) XXX_GraphQLType() string { - return "LocalModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *LocalModuleSource) XXX_GraphQLIDType() string { - return "LocalModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *LocalModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *LocalModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *LocalModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadLocalModuleSourceFromID(LocalModuleSourceID(id)) - return nil -} - -// The relative path to the module root from the host directory -func (r *LocalModuleSource) RelHostPath(ctx context.Context) (string, error) { - if r.relHostPath != nil { - return *r.relHostPath, nil - } - q := r.query.Select("relHostPath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). -func (r *LocalModuleSource) RootSubpath(ctx context.Context) (string, error) { - if r.rootSubpath != nil { - return *r.rootSubpath, nil - } - q := r.query.Select("rootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A Dagger module. -type Module struct { - query *querybuilder.Selection - - description *string - id *ModuleID - name *string - sdk *string - serve *Void -} -type WithModuleFunc func(r *Module) *Module - -// With calls the provided function with current Module. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Module) With(f WithModuleFunc) *Module { - return f(r) -} - -func (r *Module) WithGraphQLQuery(q *querybuilder.Selection) *Module { - return &Module{ - query: q, - } -} - -// Modules used by this module. -func (r *Module) Dependencies(ctx context.Context) ([]Module, error) { - q := r.query.Select("dependencies") - - q = q.Select("id") - - type dependencies struct { - Id ModuleID - } - - convert := func(fields []dependencies) []Module { - out := []Module{} - - for i := range fields { - val := Module{id: &fields[i].Id} - val.query = q.Root().Select("loadModuleFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []dependencies - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The dependencies as configured by the module. -func (r *Module) DependencyConfig(ctx context.Context) ([]ModuleDependency, error) { - q := r.query.Select("dependencyConfig") - - q = q.Select("id") - - type dependencyConfig struct { - Id ModuleDependencyID - } - - convert := func(fields []dependencyConfig) []ModuleDependency { - out := []ModuleDependency{} - - for i := range fields { - val := ModuleDependency{id: &fields[i].Id} - val.query = q.Root().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []dependencyConfig - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The doc string of the module, if any -func (r *Module) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Enumerations served by this module. -func (r *Module) Enums(ctx context.Context) ([]TypeDef, error) { - q := r.query.Select("enums") - - q = q.Select("id") - - type enums struct { - Id TypeDefID - } - - convert := func(fields []enums) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []enums - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The generated files and directories made on top of the module source's context directory. -func (r *Module) GeneratedContextDiff() *Directory { - q := r.query.Select("generatedContextDiff") - - return &Directory{ - query: q, - } -} - -// The module source's context plus any configuration and source files created by codegen. -func (r *Module) GeneratedContextDirectory() *Directory { - q := r.query.Select("generatedContextDirectory") - - return &Directory{ - query: q, - } -} - -// A unique identifier for this Module. -func (r *Module) ID(ctx context.Context) (ModuleID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ModuleID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Module) XXX_GraphQLType() string { - return "Module" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Module) XXX_GraphQLIDType() string { - return "ModuleID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Module) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Module) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Module) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleFromID(ModuleID(id)) - return nil -} - -// Retrieves the module with the objects loaded via its SDK. -func (r *Module) Initialize() *Module { - q := r.query.Select("initialize") - - return &Module{ - query: q, - } -} - -// Interfaces served by this module. -func (r *Module) Interfaces(ctx context.Context) ([]TypeDef, error) { - q := r.query.Select("interfaces") - - q = q.Select("id") - - type interfaces struct { - Id TypeDefID - } - - convert := func(fields []interfaces) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []interfaces - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The name of the module -func (r *Module) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Objects served by this module. -func (r *Module) Objects(ctx context.Context) ([]TypeDef, error) { - q := r.query.Select("objects") - - q = q.Select("id") - - type objects struct { - Id TypeDefID - } - - convert := func(fields []objects) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []objects - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. -func (r *Module) Runtime() *Container { - q := r.query.Select("runtime") - - return &Container{ - query: q, - } -} - -// The SDK used by this module. Either a name of a builtin SDK or a module source ref string pointing to the SDK's implementation. -func (r *Module) SDK(ctx context.Context) (string, error) { - if r.sdk != nil { - return *r.sdk, nil - } - q := r.query.Select("sdk") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Serve a module's API in the current session. -// -// Note: this can only be called once per session. In the future, it could return a stream or service to remove the side effect. -func (r *Module) Serve(ctx context.Context) error { - if r.serve != nil { - return nil - } - q := r.query.Select("serve") - - return q.Execute(ctx) -} - -// The source for the module. -func (r *Module) Source() *ModuleSource { - q := r.query.Select("source") - - return &ModuleSource{ - query: q, - } -} - -// Retrieves the module with the given description -func (r *Module) WithDescription(description string) *Module { - q := r.query.Select("withDescription") - q = q.Arg("description", description) - - return &Module{ - query: q, - } -} - -// This module plus the given Enum type and associated values -func (r *Module) WithEnum(enum *TypeDef) *Module { - assertNotNil("enum", enum) - q := r.query.Select("withEnum") - q = q.Arg("enum", enum) - - return &Module{ - query: q, - } -} - -// This module plus the given Interface type and associated functions -func (r *Module) WithInterface(iface *TypeDef) *Module { - assertNotNil("iface", iface) - q := r.query.Select("withInterface") - q = q.Arg("iface", iface) - - return &Module{ - query: q, - } -} - -// This module plus the given Object type and associated functions. -func (r *Module) WithObject(object *TypeDef) *Module { - assertNotNil("object", object) - q := r.query.Select("withObject") - q = q.Arg("object", object) - - return &Module{ - query: q, - } -} - -// ModuleWithSourceOpts contains options for Module.WithSource -type ModuleWithSourceOpts struct { - // The engine version to upgrade to. - EngineVersion string -} - -// Retrieves the module with basic configuration loaded if present. -func (r *Module) WithSource(source *ModuleSource, opts ...ModuleWithSourceOpts) *Module { - assertNotNil("source", source) - q := r.query.Select("withSource") - for i := len(opts) - 1; i >= 0; i-- { - // `engineVersion` optional argument - if !querybuilder.IsZeroValue(opts[i].EngineVersion) { - q = q.Arg("engineVersion", opts[i].EngineVersion) - } - } - q = q.Arg("source", source) - - return &Module{ - query: q, - } -} - -// The configuration of dependency of a module. -type ModuleDependency struct { - query *querybuilder.Selection - - id *ModuleDependencyID - name *string -} - -func (r *ModuleDependency) WithGraphQLQuery(q *querybuilder.Selection) *ModuleDependency { - return &ModuleDependency{ - query: q, - } -} - -// A unique identifier for this ModuleDependency. -func (r *ModuleDependency) ID(ctx context.Context) (ModuleDependencyID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ModuleDependencyID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ModuleDependency) XXX_GraphQLType() string { - return "ModuleDependency" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ModuleDependency) XXX_GraphQLIDType() string { - return "ModuleDependencyID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ModuleDependency) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ModuleDependency) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ModuleDependency) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleDependencyFromID(ModuleDependencyID(id)) - return nil -} - -// The name of the dependency module. -func (r *ModuleDependency) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The source for the dependency module. -func (r *ModuleDependency) Source() *ModuleSource { - q := r.query.Select("source") - - return &ModuleSource{ - query: q, - } -} - -// The source needed to load and run a module, along with any metadata about the source such as versions/urls/etc. -type ModuleSource struct { - query *querybuilder.Selection - - asString *string - configExists *bool - digest *string - id *ModuleSourceID - kind *ModuleSourceKind - moduleName *string - moduleOriginalName *string - resolveContextPathFromCaller *string - sourceRootSubpath *string - sourceSubpath *string -} -type WithModuleSourceFunc func(r *ModuleSource) *ModuleSource - -// With calls the provided function with current ModuleSource. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *ModuleSource) With(f WithModuleSourceFunc) *ModuleSource { - return f(r) -} - -func (r *ModuleSource) WithGraphQLQuery(q *querybuilder.Selection) *ModuleSource { - return &ModuleSource{ - query: q, - } -} - -// If the source is a of kind git, the git source representation of it. -func (r *ModuleSource) AsGitSource() *GitModuleSource { - q := r.query.Select("asGitSource") - - return &GitModuleSource{ - query: q, - } -} - -// If the source is of kind local, the local source representation of it. -func (r *ModuleSource) AsLocalSource() *LocalModuleSource { - q := r.query.Select("asLocalSource") - - return &LocalModuleSource{ - query: q, - } -} - -// ModuleSourceAsModuleOpts contains options for ModuleSource.AsModule -type ModuleSourceAsModuleOpts struct { - // The engine version to upgrade to. - EngineVersion string -} - -// Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation -func (r *ModuleSource) AsModule(opts ...ModuleSourceAsModuleOpts) *Module { - q := r.query.Select("asModule") - for i := len(opts) - 1; i >= 0; i-- { - // `engineVersion` optional argument - if !querybuilder.IsZeroValue(opts[i].EngineVersion) { - q = q.Arg("engineVersion", opts[i].EngineVersion) - } - } - - return &Module{ - query: q, - } -} - -// A human readable ref string representation of this module source. -func (r *ModuleSource) AsString(ctx context.Context) (string, error) { - if r.asString != nil { - return *r.asString, nil - } - q := r.query.Select("asString") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Returns whether the module source has a configuration file. -func (r *ModuleSource) ConfigExists(ctx context.Context) (bool, error) { - if r.configExists != nil { - return *r.configExists, nil - } - q := r.query.Select("configExists") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The directory containing everything needed to load load and use the module. -func (r *ModuleSource) ContextDirectory() *Directory { - q := r.query.Select("contextDirectory") - - return &Directory{ - query: q, - } -} - -// The dependencies of the module source. Includes dependencies from the configuration and any extras from withDependencies calls. -func (r *ModuleSource) Dependencies(ctx context.Context) ([]ModuleDependency, error) { - q := r.query.Select("dependencies") - - q = q.Select("id") - - type dependencies struct { - Id ModuleDependencyID - } - - convert := func(fields []dependencies) []ModuleDependency { - out := []ModuleDependency{} - - for i := range fields { - val := ModuleDependency{id: &fields[i].Id} - val.query = q.Root().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []dependencies - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Return the module source's content digest. The format of the digest is not guaranteed to be stable between releases of Dagger. It is guaranteed to be stable between invocations of the same Dagger engine. -func (r *ModuleSource) Digest(ctx context.Context) (string, error) { - if r.digest != nil { - return *r.digest, nil - } - q := r.query.Select("digest") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The directory containing the module configuration and source code (source code may be in a subdir). -func (r *ModuleSource) Directory(path string) *Directory { - q := r.query.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// A unique identifier for this ModuleSource. -func (r *ModuleSource) ID(ctx context.Context) (ModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ModuleSource) XXX_GraphQLType() string { - return "ModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ModuleSource) XXX_GraphQLIDType() string { - return "ModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleSourceFromID(ModuleSourceID(id)) - return nil -} - -// The kind of source (e.g. local, git, etc.) -func (r *ModuleSource) Kind(ctx context.Context) (ModuleSourceKind, error) { - if r.kind != nil { - return *r.kind, nil - } - q := r.query.Select("kind") - - var response ModuleSourceKind - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// If set, the name of the module this source references, including any overrides at runtime by callers. -func (r *ModuleSource) ModuleName(ctx context.Context) (string, error) { - if r.moduleName != nil { - return *r.moduleName, nil - } - q := r.query.Select("moduleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The original name of the module this source references, as defined in the module configuration. -func (r *ModuleSource) ModuleOriginalName(ctx context.Context) (string, error) { - if r.moduleOriginalName != nil { - return *r.moduleOriginalName, nil - } - q := r.query.Select("moduleOriginalName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The path to the module source's context directory on the caller's filesystem. Only valid for local sources. -func (r *ModuleSource) ResolveContextPathFromCaller(ctx context.Context) (string, error) { - if r.resolveContextPathFromCaller != nil { - return *r.resolveContextPathFromCaller, nil - } - q := r.query.Select("resolveContextPathFromCaller") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Resolve the provided module source arg as a dependency relative to this module source. -func (r *ModuleSource) ResolveDependency(dep *ModuleSource) *ModuleSource { - assertNotNil("dep", dep) - q := r.query.Select("resolveDependency") - q = q.Arg("dep", dep) - - return &ModuleSource{ - query: q, - } -} - -// ModuleSourceResolveDirectoryFromCallerOpts contains options for ModuleSource.ResolveDirectoryFromCaller -type ModuleSourceResolveDirectoryFromCallerOpts struct { - // If set, the name of the view to apply to the path. - ViewName string -} - -// Load a directory from the caller optionally with a given view applied. -func (r *ModuleSource) ResolveDirectoryFromCaller(path string, opts ...ModuleSourceResolveDirectoryFromCallerOpts) *Directory { - q := r.query.Select("resolveDirectoryFromCaller") - for i := len(opts) - 1; i >= 0; i-- { - // `viewName` optional argument - if !querybuilder.IsZeroValue(opts[i].ViewName) { - q = q.Arg("viewName", opts[i].ViewName) - } - } - q = q.Arg("path", path) - - return &Directory{ - query: q, - } -} - -// Load the source from its path on the caller's filesystem, including only needed+configured files and directories. Only valid for local sources. -func (r *ModuleSource) ResolveFromCaller() *ModuleSource { - q := r.query.Select("resolveFromCaller") - - return &ModuleSource{ - query: q, - } -} - -// The path relative to context of the root of the module source, which contains dagger.json. It also contains the module implementation source code, but that may or may not being a subdir of this root. -func (r *ModuleSource) SourceRootSubpath(ctx context.Context) (string, error) { - if r.sourceRootSubpath != nil { - return *r.sourceRootSubpath, nil - } - q := r.query.Select("sourceRootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The path relative to context of the module implementation source code. -func (r *ModuleSource) SourceSubpath(ctx context.Context) (string, error) { - if r.sourceSubpath != nil { - return *r.sourceSubpath, nil - } - q := r.query.Select("sourceSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieve a named view defined for this module source. -func (r *ModuleSource) View(name string) *ModuleSourceView { - q := r.query.Select("view") - q = q.Arg("name", name) - - return &ModuleSourceView{ - query: q, - } -} - -// The named views defined for this module source, which are sets of directory filters that can be applied to directory arguments provided to functions. -func (r *ModuleSource) Views(ctx context.Context) ([]ModuleSourceView, error) { - q := r.query.Select("views") - - q = q.Select("id") - - type views struct { - Id ModuleSourceViewID - } - - convert := func(fields []views) []ModuleSourceView { - out := []ModuleSourceView{} - - for i := range fields { - val := ModuleSourceView{id: &fields[i].Id} - val.query = q.Root().Select("loadModuleSourceViewFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []views - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Update the module source with a new context directory. Only valid for local sources. -func (r *ModuleSource) WithContextDirectory(dir *Directory) *ModuleSource { - assertNotNil("dir", dir) - q := r.query.Select("withContextDirectory") - q = q.Arg("dir", dir) - - return &ModuleSource{ - query: q, - } -} - -// Append the provided dependencies to the module source's dependency list. -func (r *ModuleSource) WithDependencies(dependencies []*ModuleDependency) *ModuleSource { - q := r.query.Select("withDependencies") - q = q.Arg("dependencies", dependencies) - - return &ModuleSource{ - query: q, - } -} - -// ModuleSourceWithInitOpts contains options for ModuleSource.WithInit -type ModuleSourceWithInitOpts struct { - // Merge module dependencies into the current project's - Merge bool -} - -// Sets module init arguments -func (r *ModuleSource) WithInit(opts ...ModuleSourceWithInitOpts) *ModuleSource { - q := r.query.Select("withInit") - for i := len(opts) - 1; i >= 0; i-- { - // `merge` optional argument - if !querybuilder.IsZeroValue(opts[i].Merge) { - q = q.Arg("merge", opts[i].Merge) - } - } - - return &ModuleSource{ - query: q, - } -} - -// Update the module source with a new name. -func (r *ModuleSource) WithName(name string) *ModuleSource { - q := r.query.Select("withName") - q = q.Arg("name", name) - - return &ModuleSource{ - query: q, - } -} - -// Update the module source with a new SDK. -func (r *ModuleSource) WithSDK(sdk string) *ModuleSource { - q := r.query.Select("withSDK") - q = q.Arg("sdk", sdk) - - return &ModuleSource{ - query: q, - } -} - -// Update the module source with a new source subpath. -func (r *ModuleSource) WithSourceSubpath(path string) *ModuleSource { - q := r.query.Select("withSourceSubpath") - q = q.Arg("path", path) - - return &ModuleSource{ - query: q, - } -} - -// Update the module source with a new named view. -func (r *ModuleSource) WithView(name string, patterns []string) *ModuleSource { - q := r.query.Select("withView") - q = q.Arg("name", name) - q = q.Arg("patterns", patterns) - - return &ModuleSource{ - query: q, - } -} - -// A named set of path filters that can be applied to directory arguments provided to functions. -type ModuleSourceView struct { - query *querybuilder.Selection - - id *ModuleSourceViewID - name *string -} - -func (r *ModuleSourceView) WithGraphQLQuery(q *querybuilder.Selection) *ModuleSourceView { - return &ModuleSourceView{ - query: q, - } -} - -// A unique identifier for this ModuleSourceView. -func (r *ModuleSourceView) ID(ctx context.Context) (ModuleSourceViewID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ModuleSourceViewID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ModuleSourceView) XXX_GraphQLType() string { - return "ModuleSourceView" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ModuleSourceView) XXX_GraphQLIDType() string { - return "ModuleSourceViewID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ModuleSourceView) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ModuleSourceView) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ModuleSourceView) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleSourceViewFromID(ModuleSourceViewID(id)) - return nil -} - -// The name of the view -func (r *ModuleSourceView) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The patterns of the view used to filter paths -func (r *ModuleSourceView) Patterns(ctx context.Context) ([]string, error) { - q := r.query.Select("patterns") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A definition of a custom object defined in a Module. -type ObjectTypeDef struct { - query *querybuilder.Selection - - description *string - id *ObjectTypeDefID - name *string - sourceModuleName *string -} - -func (r *ObjectTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *ObjectTypeDef { - return &ObjectTypeDef{ - query: q, - } -} - -// The function used to construct new instances of this object, if any -func (r *ObjectTypeDef) Constructor() *Function { - q := r.query.Select("constructor") - - return &Function{ - query: q, - } -} - -// The doc string for the object, if any. -func (r *ObjectTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Static fields defined on this object, if any. -func (r *ObjectTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { - q := r.query.Select("fields") - - q = q.Select("id") - - type fields struct { - Id FieldTypeDefID - } - - convert := func(fields []fields) []FieldTypeDef { - out := []FieldTypeDef{} - - for i := range fields { - val := FieldTypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []fields - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Functions defined on this object, if any. -func (r *ObjectTypeDef) Functions(ctx context.Context) ([]Function, error) { - q := r.query.Select("functions") - - q = q.Select("id") - - type functions struct { - Id FunctionID - } - - convert := func(fields []functions) []Function { - out := []Function{} - - for i := range fields { - val := Function{id: &fields[i].Id} - val.query = q.Root().Select("loadFunctionFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []functions - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this ObjectTypeDef. -func (r *ObjectTypeDef) ID(ctx context.Context) (ObjectTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ObjectTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ObjectTypeDef) XXX_GraphQLType() string { - return "ObjectTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ObjectTypeDef) XXX_GraphQLIDType() string { - return "ObjectTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ObjectTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ObjectTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ObjectTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadObjectTypeDefFromID(ObjectTypeDefID(id)) - return nil -} - -// The name of the object. -func (r *ObjectTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// If this ObjectTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *ObjectTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.query.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A port exposed by a container. -type Port struct { - query *querybuilder.Selection - - description *string - experimentalSkipHealthcheck *bool - id *PortID - port *int - protocol *NetworkProtocol -} - -func (r *Port) WithGraphQLQuery(q *querybuilder.Selection) *Port { - return &Port{ - query: q, - } -} - -// The port description. -func (r *Port) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Skip the health check when run as a service. -func (r *Port) ExperimentalSkipHealthcheck(ctx context.Context) (bool, error) { - if r.experimentalSkipHealthcheck != nil { - return *r.experimentalSkipHealthcheck, nil - } - q := r.query.Select("experimentalSkipHealthcheck") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this Port. -func (r *Port) ID(ctx context.Context) (PortID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response PortID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Port) XXX_GraphQLType() string { - return "Port" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Port) XXX_GraphQLIDType() string { - return "PortID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Port) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Port) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Port) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadPortFromID(PortID(id)) - return nil -} - -// The port number. -func (r *Port) Port(ctx context.Context) (int, error) { - if r.port != nil { - return *r.port, nil - } - q := r.query.Select("port") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The transport layer protocol. -func (r *Port) Protocol(ctx context.Context) (NetworkProtocol, error) { - if r.protocol != nil { - return *r.protocol, nil - } - q := r.query.Select("protocol") - - var response NetworkProtocol - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -func (r *Client) WithGraphQLQuery(q *querybuilder.Selection) *Client { - return &Client{ - query: q, - client: r.client, - } -} - -// Retrieves a content-addressed blob. -func (r *Client) Blob(digest string, size int, mediaType string, uncompressed string) *Directory { - q := r.query.Select("blob") - q = q.Arg("digest", digest) - q = q.Arg("size", size) - q = q.Arg("mediaType", mediaType) - q = q.Arg("uncompressed", uncompressed) - - return &Directory{ - query: q, - } -} - -// Retrieves a container builtin to the engine. -func (r *Client) BuiltinContainer(digest string) *Container { - q := r.query.Select("builtinContainer") - q = q.Arg("digest", digest) - - return &Container{ - query: q, - } -} - -// Constructs a cache volume for a given cache key. -func (r *Client) CacheVolume(key string) *CacheVolume { - q := r.query.Select("cacheVolume") - q = q.Arg("key", key) - - return &CacheVolume{ - query: q, - } -} - -// ContainerOpts contains options for Client.Container -type ContainerOpts struct { - // Platform to initialize the container with. - Platform Platform -} - -// Creates a scratch container. -// -// Optional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host. -func (r *Client) Container(opts ...ContainerOpts) *Container { - q := r.query.Select("container") - for i := len(opts) - 1; i >= 0; i-- { - // `platform` optional argument - if !querybuilder.IsZeroValue(opts[i].Platform) { - q = q.Arg("platform", opts[i].Platform) - } - } - - return &Container{ - query: q, - } -} - -func (r *Client) Cosign() *Cosign { - q := r.query.Select("cosign") - - return &Cosign{ - query: q, - } -} - -// The FunctionCall context that the SDK caller is currently executing in. -// -// If the caller is not currently executing in a function, this will return an error. -func (r *Client) CurrentFunctionCall() *FunctionCall { - q := r.query.Select("currentFunctionCall") - - return &FunctionCall{ - query: q, - } -} - -// The module currently being served in the session, if any. -func (r *Client) CurrentModule() *CurrentModule { - q := r.query.Select("currentModule") - - return &CurrentModule{ - query: q, - } -} - -// The TypeDef representations of the objects currently being served in the session. -func (r *Client) CurrentTypeDefs(ctx context.Context) ([]TypeDef, error) { - q := r.query.Select("currentTypeDefs") - - q = q.Select("id") - - type currentTypeDefs struct { - Id TypeDefID - } - - convert := func(fields []currentTypeDefs) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.query = q.Root().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []currentTypeDefs - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The default platform of the engine. -func (r *Client) DefaultPlatform(ctx context.Context) (Platform, error) { - q := r.query.Select("defaultPlatform") - - var response Platform - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Creates an empty directory. -func (r *Client) Directory() *Directory { - q := r.query.Select("directory") - - return &Directory{ - query: q, - } -} - -// Creates a function. -func (r *Client) Function(name string, returnType *TypeDef) *Function { - assertNotNil("returnType", returnType) - q := r.query.Select("function") - q = q.Arg("name", name) - q = q.Arg("returnType", returnType) - - return &Function{ - query: q, - } -} - -// Create a code generation result, given a directory containing the generated code. -func (r *Client) GeneratedCode(code *Directory) *GeneratedCode { - assertNotNil("code", code) - q := r.query.Select("generatedCode") - q = q.Arg("code", code) - - return &GeneratedCode{ - query: q, - } -} - -// GitOpts contains options for Client.Git -type GitOpts struct { - // Set to true to keep .git directory. - KeepGitDir bool - // A service which must be started before the repo is fetched. - ExperimentalServiceHost *Service - // Set SSH known hosts - SSHKnownHosts string - // Set SSH auth socket - SSHAuthSocket *Socket -} - -// Queries a Git repository. -func (r *Client) Git(url string, opts ...GitOpts) *GitRepository { - q := r.query.Select("git") - for i := len(opts) - 1; i >= 0; i-- { - // `keepGitDir` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepGitDir) { - q = q.Arg("keepGitDir", opts[i].KeepGitDir) - } - // `experimentalServiceHost` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { - q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) - } - // `sshKnownHosts` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) { - q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts) - } - // `sshAuthSocket` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) { - q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket) - } - } - q = q.Arg("url", url) - - return &GitRepository{ - query: q, - } -} - -// HTTPOpts contains options for Client.HTTP -type HTTPOpts struct { - // A service which must be started before the URL is fetched. - ExperimentalServiceHost *Service -} - -// Returns a file containing an http remote url content. -func (r *Client) HTTP(url string, opts ...HTTPOpts) *File { - q := r.query.Select("http") - for i := len(opts) - 1; i >= 0; i-- { - // `experimentalServiceHost` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { - q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) - } - } - q = q.Arg("url", url) - - return &File{ - query: q, - } -} - -// Load a CacheVolume from its ID. -func (r *Client) LoadCacheVolumeFromID(id CacheVolumeID) *CacheVolume { - q := r.query.Select("loadCacheVolumeFromID") - q = q.Arg("id", id) - - return &CacheVolume{ - query: q, - } -} - -// Load a Container from its ID. -func (r *Client) LoadContainerFromID(id ContainerID) *Container { - q := r.query.Select("loadContainerFromID") - q = q.Arg("id", id) - - return &Container{ - query: q, - } -} - -// Load a Cosign from its ID. -func (r *Client) LoadCosignFromID(id CosignID) *Cosign { - q := r.query.Select("loadCosignFromID") - q = q.Arg("id", id) - - return &Cosign{ - query: q, - } -} - -// Load a CurrentModule from its ID. -func (r *Client) LoadCurrentModuleFromID(id CurrentModuleID) *CurrentModule { - q := r.query.Select("loadCurrentModuleFromID") - q = q.Arg("id", id) - - return &CurrentModule{ - query: q, - } -} - -// Load a DaggerEngineCacheEntry from its ID. -func (r *Client) LoadDaggerEngineCacheEntryFromID(id DaggerEngineCacheEntryID) *DaggerEngineCacheEntry { - q := r.query.Select("loadDaggerEngineCacheEntryFromID") - q = q.Arg("id", id) - - return &DaggerEngineCacheEntry{ - query: q, - } -} - -// Load a DaggerEngineCacheEntrySet from its ID. -func (r *Client) LoadDaggerEngineCacheEntrySetFromID(id DaggerEngineCacheEntrySetID) *DaggerEngineCacheEntrySet { - q := r.query.Select("loadDaggerEngineCacheEntrySetFromID") - q = q.Arg("id", id) - - return &DaggerEngineCacheEntrySet{ - query: q, - } -} - -// Load a DaggerEngineCache from its ID. -func (r *Client) LoadDaggerEngineCacheFromID(id DaggerEngineCacheID) *DaggerEngineCache { - q := r.query.Select("loadDaggerEngineCacheFromID") - q = q.Arg("id", id) - - return &DaggerEngineCache{ - query: q, - } -} - -// Load a Directory from its ID. -func (r *Client) LoadDirectoryFromID(id DirectoryID) *Directory { - q := r.query.Select("loadDirectoryFromID") - q = q.Arg("id", id) - - return &Directory{ - query: q, - } -} - -// Load a EnumTypeDef from its ID. -func (r *Client) LoadEnumTypeDefFromID(id EnumTypeDefID) *EnumTypeDef { - q := r.query.Select("loadEnumTypeDefFromID") - q = q.Arg("id", id) - - return &EnumTypeDef{ - query: q, - } -} - -// Load a EnumValueTypeDef from its ID. -func (r *Client) LoadEnumValueTypeDefFromID(id EnumValueTypeDefID) *EnumValueTypeDef { - q := r.query.Select("loadEnumValueTypeDefFromID") - q = q.Arg("id", id) - - return &EnumValueTypeDef{ - query: q, - } -} - -// Load a EnvVariable from its ID. -func (r *Client) LoadEnvVariableFromID(id EnvVariableID) *EnvVariable { - q := r.query.Select("loadEnvVariableFromID") - q = q.Arg("id", id) - - return &EnvVariable{ - query: q, - } -} - -// Load a FieldTypeDef from its ID. -func (r *Client) LoadFieldTypeDefFromID(id FieldTypeDefID) *FieldTypeDef { - q := r.query.Select("loadFieldTypeDefFromID") - q = q.Arg("id", id) - - return &FieldTypeDef{ - query: q, - } -} - -// Load a File from its ID. -func (r *Client) LoadFileFromID(id FileID) *File { - q := r.query.Select("loadFileFromID") - q = q.Arg("id", id) - - return &File{ - query: q, - } -} - -// Load a FunctionArg from its ID. -func (r *Client) LoadFunctionArgFromID(id FunctionArgID) *FunctionArg { - q := r.query.Select("loadFunctionArgFromID") - q = q.Arg("id", id) - - return &FunctionArg{ - query: q, - } -} - -// Load a FunctionCallArgValue from its ID. -func (r *Client) LoadFunctionCallArgValueFromID(id FunctionCallArgValueID) *FunctionCallArgValue { - q := r.query.Select("loadFunctionCallArgValueFromID") - q = q.Arg("id", id) - - return &FunctionCallArgValue{ - query: q, - } -} - -// Load a FunctionCall from its ID. -func (r *Client) LoadFunctionCallFromID(id FunctionCallID) *FunctionCall { - q := r.query.Select("loadFunctionCallFromID") - q = q.Arg("id", id) - - return &FunctionCall{ - query: q, - } -} - -// Load a Function from its ID. -func (r *Client) LoadFunctionFromID(id FunctionID) *Function { - q := r.query.Select("loadFunctionFromID") - q = q.Arg("id", id) - - return &Function{ - query: q, - } -} - -// Load a GeneratedCode from its ID. -func (r *Client) LoadGeneratedCodeFromID(id GeneratedCodeID) *GeneratedCode { - q := r.query.Select("loadGeneratedCodeFromID") - q = q.Arg("id", id) - - return &GeneratedCode{ - query: q, - } -} - -// Load a GitModuleSource from its ID. -func (r *Client) LoadGitModuleSourceFromID(id GitModuleSourceID) *GitModuleSource { - q := r.query.Select("loadGitModuleSourceFromID") - q = q.Arg("id", id) - - return &GitModuleSource{ - query: q, - } -} - -// Load a GitRef from its ID. -func (r *Client) LoadGitRefFromID(id GitRefID) *GitRef { - q := r.query.Select("loadGitRefFromID") - q = q.Arg("id", id) - - return &GitRef{ - query: q, - } -} - -// Load a GitRepository from its ID. -func (r *Client) LoadGitRepositoryFromID(id GitRepositoryID) *GitRepository { - q := r.query.Select("loadGitRepositoryFromID") - q = q.Arg("id", id) - - return &GitRepository{ - query: q, - } -} - -// Load a InputTypeDef from its ID. -func (r *Client) LoadInputTypeDefFromID(id InputTypeDefID) *InputTypeDef { - q := r.query.Select("loadInputTypeDefFromID") - q = q.Arg("id", id) - - return &InputTypeDef{ - query: q, - } -} - -// Load a InterfaceTypeDef from its ID. -func (r *Client) LoadInterfaceTypeDefFromID(id InterfaceTypeDefID) *InterfaceTypeDef { - q := r.query.Select("loadInterfaceTypeDefFromID") - q = q.Arg("id", id) - - return &InterfaceTypeDef{ - query: q, - } -} - -// Load a Label from its ID. -func (r *Client) LoadLabelFromID(id LabelID) *Label { - q := r.query.Select("loadLabelFromID") - q = q.Arg("id", id) - - return &Label{ - query: q, - } -} - -// Load a ListTypeDef from its ID. -func (r *Client) LoadListTypeDefFromID(id ListTypeDefID) *ListTypeDef { - q := r.query.Select("loadListTypeDefFromID") - q = q.Arg("id", id) - - return &ListTypeDef{ - query: q, - } -} - -// Load a LocalModuleSource from its ID. -func (r *Client) LoadLocalModuleSourceFromID(id LocalModuleSourceID) *LocalModuleSource { - q := r.query.Select("loadLocalModuleSourceFromID") - q = q.Arg("id", id) - - return &LocalModuleSource{ - query: q, - } -} - -// Load a ModuleDependency from its ID. -func (r *Client) LoadModuleDependencyFromID(id ModuleDependencyID) *ModuleDependency { - q := r.query.Select("loadModuleDependencyFromID") - q = q.Arg("id", id) - - return &ModuleDependency{ - query: q, - } -} - -// Load a Module from its ID. -func (r *Client) LoadModuleFromID(id ModuleID) *Module { - q := r.query.Select("loadModuleFromID") - q = q.Arg("id", id) - - return &Module{ - query: q, - } -} - -// Load a ModuleSource from its ID. -func (r *Client) LoadModuleSourceFromID(id ModuleSourceID) *ModuleSource { - q := r.query.Select("loadModuleSourceFromID") - q = q.Arg("id", id) - - return &ModuleSource{ - query: q, - } -} - -// Load a ModuleSourceView from its ID. -func (r *Client) LoadModuleSourceViewFromID(id ModuleSourceViewID) *ModuleSourceView { - q := r.query.Select("loadModuleSourceViewFromID") - q = q.Arg("id", id) - - return &ModuleSourceView{ - query: q, - } -} - -// Load a ObjectTypeDef from its ID. -func (r *Client) LoadObjectTypeDefFromID(id ObjectTypeDefID) *ObjectTypeDef { - q := r.query.Select("loadObjectTypeDefFromID") - q = q.Arg("id", id) - - return &ObjectTypeDef{ - query: q, - } -} - -// Load a Port from its ID. -func (r *Client) LoadPortFromID(id PortID) *Port { - q := r.query.Select("loadPortFromID") - q = q.Arg("id", id) - - return &Port{ - query: q, - } -} - -// Load a ScalarTypeDef from its ID. -func (r *Client) LoadScalarTypeDefFromID(id ScalarTypeDefID) *ScalarTypeDef { - q := r.query.Select("loadScalarTypeDefFromID") - q = q.Arg("id", id) - - return &ScalarTypeDef{ - query: q, - } -} - -// Load a Secret from its ID. -func (r *Client) LoadSecretFromID(id SecretID) *Secret { - q := r.query.Select("loadSecretFromID") - q = q.Arg("id", id) - - return &Secret{ - query: q, - } -} - -// Load a Service from its ID. -func (r *Client) LoadServiceFromID(id ServiceID) *Service { - q := r.query.Select("loadServiceFromID") - q = q.Arg("id", id) - - return &Service{ - query: q, - } -} - -// Load a Socket from its ID. -func (r *Client) LoadSocketFromID(id SocketID) *Socket { - q := r.query.Select("loadSocketFromID") - q = q.Arg("id", id) - - return &Socket{ - query: q, - } -} - -// Load a Terminal from its ID. -func (r *Client) LoadTerminalFromID(id TerminalID) *Terminal { - q := r.query.Select("loadTerminalFromID") - q = q.Arg("id", id) - - return &Terminal{ - query: q, - } -} - -// Load a TypeDef from its ID. -func (r *Client) LoadTypeDefFromID(id TypeDefID) *TypeDef { - q := r.query.Select("loadTypeDefFromID") - q = q.Arg("id", id) - - return &TypeDef{ - query: q, - } -} - -// Create a new module. -func (r *Client) Module() *Module { - q := r.query.Select("module") - - return &Module{ - query: q, - } -} - -// ModuleDependencyOpts contains options for Client.ModuleDependency -type ModuleDependencyOpts struct { - // If set, the name to use for the dependency. Otherwise, once installed to a parent module, the name of the dependency module will be used by default. - Name string -} - -// Create a new module dependency configuration from a module source and name -func (r *Client) ModuleDependency(source *ModuleSource, opts ...ModuleDependencyOpts) *ModuleDependency { - assertNotNil("source", source) - q := r.query.Select("moduleDependency") - for i := len(opts) - 1; i >= 0; i-- { - // `name` optional argument - if !querybuilder.IsZeroValue(opts[i].Name) { - q = q.Arg("name", opts[i].Name) - } - } - q = q.Arg("source", source) - - return &ModuleDependency{ - query: q, - } -} - -// ModuleSourceOpts contains options for Client.ModuleSource -type ModuleSourceOpts struct { - // If true, enforce that the source is a stable version for source kinds that support versioning. - Stable bool - // The relative path to the module root from the host directory - RelHostPath string -} - -// Create a new module source instance from a source ref string. -func (r *Client) ModuleSource(refString string, opts ...ModuleSourceOpts) *ModuleSource { - q := r.query.Select("moduleSource") - for i := len(opts) - 1; i >= 0; i-- { - // `stable` optional argument - if !querybuilder.IsZeroValue(opts[i].Stable) { - q = q.Arg("stable", opts[i].Stable) - } - // `relHostPath` optional argument - if !querybuilder.IsZeroValue(opts[i].RelHostPath) { - q = q.Arg("relHostPath", opts[i].RelHostPath) - } - } - q = q.Arg("refString", refString) - - return &ModuleSource{ - query: q, - } -} - -// SecretOpts contains options for Client.Secret -type SecretOpts struct { - Accessor string -} - -// Reference a secret by name. -func (r *Client) Secret(name string, opts ...SecretOpts) *Secret { - q := r.query.Select("secret") - for i := len(opts) - 1; i >= 0; i-- { - // `accessor` optional argument - if !querybuilder.IsZeroValue(opts[i].Accessor) { - q = q.Arg("accessor", opts[i].Accessor) - } - } - q = q.Arg("name", name) - - return &Secret{ - query: q, - } -} - -// Sets a secret given a user defined name to its plaintext and returns the secret. -// -// The plaintext value is limited to a size of 128000 bytes. -func (r *Client) SetSecret(name string, plaintext string) *Secret { - q := r.query.Select("setSecret") - q = q.Arg("name", name) - q = q.Arg("plaintext", plaintext) - - return &Secret{ - query: q, - } -} - -// Create a new TypeDef. -func (r *Client) TypeDef() *TypeDef { - q := r.query.Select("typeDef") - - return &TypeDef{ - query: q, - } -} - -// Get the current Dagger Engine version. -func (r *Client) Version(ctx context.Context) (string, error) { - q := r.query.Select("version") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A definition of a custom scalar defined in a Module. -type ScalarTypeDef struct { - query *querybuilder.Selection - - description *string - id *ScalarTypeDefID - name *string - sourceModuleName *string -} - -func (r *ScalarTypeDef) WithGraphQLQuery(q *querybuilder.Selection) *ScalarTypeDef { - return &ScalarTypeDef{ - query: q, - } -} - -// A doc string for the scalar, if any. -func (r *ScalarTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.query.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this ScalarTypeDef. -func (r *ScalarTypeDef) ID(ctx context.Context) (ScalarTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ScalarTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ScalarTypeDef) XXX_GraphQLType() string { - return "ScalarTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ScalarTypeDef) XXX_GraphQLIDType() string { - return "ScalarTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ScalarTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ScalarTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ScalarTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadScalarTypeDefFromID(ScalarTypeDefID(id)) - return nil -} - -// The name of the scalar. -func (r *ScalarTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// If this ScalarTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *ScalarTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.query.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A reference to a secret value, which can be handled more safely than the value itself. -type Secret struct { - query *querybuilder.Selection - - id *SecretID - name *string - plaintext *string -} - -func (r *Secret) WithGraphQLQuery(q *querybuilder.Selection) *Secret { - return &Secret{ - query: q, - } -} - -// A unique identifier for this Secret. -func (r *Secret) ID(ctx context.Context) (SecretID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response SecretID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Secret) XXX_GraphQLType() string { - return "Secret" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Secret) XXX_GraphQLIDType() string { - return "SecretID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Secret) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Secret) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Secret) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadSecretFromID(SecretID(id)) - return nil -} - -// The name of this secret. -func (r *Secret) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.query.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// The value of this secret. -func (r *Secret) Plaintext(ctx context.Context) (string, error) { - if r.plaintext != nil { - return *r.plaintext, nil - } - q := r.query.Select("plaintext") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A content-addressed service providing TCP connectivity. -type Service struct { - query *querybuilder.Selection - - endpoint *string - hostname *string - id *ServiceID - start *ServiceID - stop *ServiceID - up *Void -} - -func (r *Service) WithGraphQLQuery(q *querybuilder.Selection) *Service { - return &Service{ - query: q, - } -} - -// ServiceEndpointOpts contains options for Service.Endpoint -type ServiceEndpointOpts struct { - // The exposed port number for the endpoint - Port int - // Return a URL with the given scheme, eg. http for http:// - Scheme string -} - -// Retrieves an endpoint that clients can use to reach this container. -// -// If no port is specified, the first exposed port is used. If none exist an error is returned. -// -// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. -func (r *Service) Endpoint(ctx context.Context, opts ...ServiceEndpointOpts) (string, error) { - if r.endpoint != nil { - return *r.endpoint, nil - } - q := r.query.Select("endpoint") - for i := len(opts) - 1; i >= 0; i-- { - // `port` optional argument - if !querybuilder.IsZeroValue(opts[i].Port) { - q = q.Arg("port", opts[i].Port) - } - // `scheme` optional argument - if !querybuilder.IsZeroValue(opts[i].Scheme) { - q = q.Arg("scheme", opts[i].Scheme) - } - } - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Retrieves a hostname which can be used by clients to reach this container. -func (r *Service) Hostname(ctx context.Context) (string, error) { - if r.hostname != nil { - return *r.hostname, nil - } - q := r.query.Select("hostname") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// A unique identifier for this Service. -func (r *Service) ID(ctx context.Context) (ServiceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response ServiceID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Service) XXX_GraphQLType() string { - return "Service" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Service) XXX_GraphQLIDType() string { - return "ServiceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Service) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Service) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Service) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadServiceFromID(ServiceID(id)) - return nil -} - -// Retrieves the list of ports provided by the service. -func (r *Service) Ports(ctx context.Context) ([]Port, error) { - q := r.query.Select("ports") - - q = q.Select("id") - - type ports struct { - Id PortID - } - - convert := func(fields []ports) []Port { - out := []Port{} - - for i := range fields { - val := Port{id: &fields[i].Id} - val.query = q.Root().Select("loadPortFromID").Arg("id", fields[i].Id) - out = append(out, val) - } - - return out - } - var response []ports - - q = q.Bind(&response) - - err := q.Execute(ctx) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Start the service and wait for its health checks to succeed. -// -// Services bound to a Container do not need to be manually started. -func (r *Service) Start(ctx context.Context) (*Service, error) { - q := r.query.Select("start") - - var id ServiceID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &Service{ - query: q.Root().Select("loadServiceFromID").Arg("id", id), - }, nil -} - -// ServiceStopOpts contains options for Service.Stop -type ServiceStopOpts struct { - // Immediately kill the service without waiting for a graceful exit - Kill bool -} - -// Stop the service. -func (r *Service) Stop(ctx context.Context, opts ...ServiceStopOpts) (*Service, error) { - q := r.query.Select("stop") - for i := len(opts) - 1; i >= 0; i-- { - // `kill` optional argument - if !querybuilder.IsZeroValue(opts[i].Kill) { - q = q.Arg("kill", opts[i].Kill) - } - } - - var id ServiceID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &Service{ - query: q.Root().Select("loadServiceFromID").Arg("id", id), - }, nil -} - -// ServiceUpOpts contains options for Service.Up -type ServiceUpOpts struct { - // List of frontend/backend port mappings to forward. - // - // Frontend is the port accepting traffic on the host, backend is the service port. - Ports []PortForward - // Bind each tunnel port to a random port on the host. - Random bool -} - -// Creates a tunnel that forwards traffic from the caller's network to this service. -func (r *Service) Up(ctx context.Context, opts ...ServiceUpOpts) error { - if r.up != nil { - return nil - } - q := r.query.Select("up") - for i := len(opts) - 1; i >= 0; i-- { - // `ports` optional argument - if !querybuilder.IsZeroValue(opts[i].Ports) { - q = q.Arg("ports", opts[i].Ports) - } - // `random` optional argument - if !querybuilder.IsZeroValue(opts[i].Random) { - q = q.Arg("random", opts[i].Random) - } - } - - return q.Execute(ctx) -} - -// A Unix or TCP/IP socket that can be mounted into a container. -type Socket struct { - query *querybuilder.Selection - - id *SocketID -} - -func (r *Socket) WithGraphQLQuery(q *querybuilder.Selection) *Socket { - return &Socket{ - query: q, - } -} - -// A unique identifier for this Socket. -func (r *Socket) ID(ctx context.Context) (SocketID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response SocketID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Socket) XXX_GraphQLType() string { - return "Socket" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Socket) XXX_GraphQLIDType() string { - return "SocketID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Socket) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Socket) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Socket) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadSocketFromID(SocketID(id)) - return nil -} - -// An interactive terminal that clients can connect to. -type Terminal struct { - query *querybuilder.Selection - - id *TerminalID - sync *TerminalID -} - -func (r *Terminal) WithGraphQLQuery(q *querybuilder.Selection) *Terminal { - return &Terminal{ - query: q, - } -} - -// A unique identifier for this Terminal. -func (r *Terminal) ID(ctx context.Context) (TerminalID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response TerminalID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Terminal) XXX_GraphQLType() string { - return "Terminal" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Terminal) XXX_GraphQLIDType() string { - return "TerminalID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Terminal) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Terminal) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Terminal) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadTerminalFromID(TerminalID(id)) - return nil -} - -// Forces evaluation of the pipeline in the engine. -// -// It doesn't run the default command if no exec has been set. -func (r *Terminal) Sync(ctx context.Context) (*Terminal, error) { - q := r.query.Select("sync") - - var id TerminalID - if err := q.Bind(&id).Execute(ctx); err != nil { - return nil, err - } - return &Terminal{ - query: q.Root().Select("loadTerminalFromID").Arg("id", id), - }, nil -} - -// A definition of a parameter or return type in a Module. -type TypeDef struct { - query *querybuilder.Selection - - id *TypeDefID - kind *TypeDefKind - optional *bool -} -type WithTypeDefFunc func(r *TypeDef) *TypeDef - -// With calls the provided function with current TypeDef. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *TypeDef) With(f WithTypeDefFunc) *TypeDef { - return f(r) -} - -func (r *TypeDef) WithGraphQLQuery(q *querybuilder.Selection) *TypeDef { - return &TypeDef{ - query: q, - } -} - -// If kind is ENUM, the enum-specific type definition. If kind is not ENUM, this will be null. -func (r *TypeDef) AsEnum() *EnumTypeDef { - q := r.query.Select("asEnum") - - return &EnumTypeDef{ - query: q, - } -} - -// If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. -func (r *TypeDef) AsInput() *InputTypeDef { - q := r.query.Select("asInput") - - return &InputTypeDef{ - query: q, - } -} - -// If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. -func (r *TypeDef) AsInterface() *InterfaceTypeDef { - q := r.query.Select("asInterface") - - return &InterfaceTypeDef{ - query: q, - } -} - -// If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. -func (r *TypeDef) AsList() *ListTypeDef { - q := r.query.Select("asList") - - return &ListTypeDef{ - query: q, - } -} - -// If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. -func (r *TypeDef) AsObject() *ObjectTypeDef { - q := r.query.Select("asObject") - - return &ObjectTypeDef{ - query: q, - } -} - -// If kind is SCALAR, the scalar-specific type definition. If kind is not SCALAR, this will be null. -func (r *TypeDef) AsScalar() *ScalarTypeDef { - q := r.query.Select("asScalar") - - return &ScalarTypeDef{ - query: q, - } -} - -// A unique identifier for this TypeDef. -func (r *TypeDef) ID(ctx context.Context) (TypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.query.Select("id") - - var response TypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *TypeDef) XXX_GraphQLType() string { - return "TypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *TypeDef) XXX_GraphQLIDType() string { - return "TypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *TypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *TypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(marshalCtx) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *TypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadTypeDefFromID(TypeDefID(id)) - return nil -} - -// The kind of type this is (e.g. primitive, list, object). -func (r *TypeDef) Kind(ctx context.Context) (TypeDefKind, error) { - if r.kind != nil { - return *r.kind, nil - } - q := r.query.Select("kind") - - var response TypeDefKind - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Whether this type can be set to null. Defaults to false. -func (r *TypeDef) Optional(ctx context.Context) (bool, error) { - if r.optional != nil { - return *r.optional, nil - } - q := r.query.Select("optional") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx) -} - -// Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. -func (r *TypeDef) WithConstructor(function *Function) *TypeDef { - assertNotNil("function", function) - q := r.query.Select("withConstructor") - q = q.Arg("function", function) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithEnumOpts contains options for TypeDef.WithEnum -type TypeDefWithEnumOpts struct { - // A doc string for the enum, if any - Description string -} - -// Returns a TypeDef of kind Enum with the provided name. -// -// Note that an enum's values may be omitted if the intent is only to refer to an enum. This is how functions are able to return their own, or any other circular reference. -func (r *TypeDef) WithEnum(name string, opts ...TypeDefWithEnumOpts) *TypeDef { - q := r.query.Select("withEnum") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithEnumValueOpts contains options for TypeDef.WithEnumValue -type TypeDefWithEnumValueOpts struct { - // A doc string for the value, if any - Description string -} - -// Adds a static value for an Enum TypeDef, failing if the type is not an enum. -func (r *TypeDef) WithEnumValue(value string, opts ...TypeDefWithEnumValueOpts) *TypeDef { - q := r.query.Select("withEnumValue") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("value", value) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithFieldOpts contains options for TypeDef.WithField -type TypeDefWithFieldOpts struct { - // A doc string for the field, if any - Description string -} - -// Adds a static field for an Object TypeDef, failing if the type is not an object. -func (r *TypeDef) WithField(name string, typeDef *TypeDef, opts ...TypeDefWithFieldOpts) *TypeDef { - assertNotNil("typeDef", typeDef) - q := r.query.Select("withField") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - q = q.Arg("typeDef", typeDef) - - return &TypeDef{ - query: q, - } -} - -// Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. -func (r *TypeDef) WithFunction(function *Function) *TypeDef { - assertNotNil("function", function) - q := r.query.Select("withFunction") - q = q.Arg("function", function) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithInterfaceOpts contains options for TypeDef.WithInterface -type TypeDefWithInterfaceOpts struct { - Description string -} - -// Returns a TypeDef of kind Interface with the provided name. -func (r *TypeDef) WithInterface(name string, opts ...TypeDefWithInterfaceOpts) *TypeDef { - q := r.query.Select("withInterface") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - query: q, - } -} - -// Sets the kind of the type. -func (r *TypeDef) WithKind(kind TypeDefKind) *TypeDef { - q := r.query.Select("withKind") - q = q.Arg("kind", kind) - - return &TypeDef{ - query: q, - } -} - -// Returns a TypeDef of kind List with the provided type for its elements. -func (r *TypeDef) WithListOf(elementType *TypeDef) *TypeDef { - assertNotNil("elementType", elementType) - q := r.query.Select("withListOf") - q = q.Arg("elementType", elementType) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithObjectOpts contains options for TypeDef.WithObject -type TypeDefWithObjectOpts struct { - Description string -} - -// Returns a TypeDef of kind Object with the provided name. -// -// Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. -func (r *TypeDef) WithObject(name string, opts ...TypeDefWithObjectOpts) *TypeDef { - q := r.query.Select("withObject") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - query: q, - } -} - -// Sets whether this type can be set to null. -func (r *TypeDef) WithOptional(optional bool) *TypeDef { - q := r.query.Select("withOptional") - q = q.Arg("optional", optional) - - return &TypeDef{ - query: q, - } -} - -// TypeDefWithScalarOpts contains options for TypeDef.WithScalar -type TypeDefWithScalarOpts struct { - Description string -} - -// Returns a TypeDef of kind Scalar with the provided name. -func (r *TypeDef) WithScalar(name string, opts ...TypeDefWithScalarOpts) *TypeDef { - q := r.query.Select("withScalar") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - query: q, - } -} - -type CacheSharingMode string - -func (CacheSharingMode) IsEnum() {} - -const ( - // Shares the cache volume amongst many build pipelines, but will serialize the writes - Locked CacheSharingMode = "LOCKED" - - // Keeps a cache volume for a single build pipeline - Private CacheSharingMode = "PRIVATE" - - // Shares the cache volume amongst many build pipelines - Shared CacheSharingMode = "SHARED" -) - -type ImageLayerCompression string - -func (ImageLayerCompression) IsEnum() {} - -const ( - Estargz ImageLayerCompression = "EStarGZ" - - Gzip ImageLayerCompression = "Gzip" - - Uncompressed ImageLayerCompression = "Uncompressed" - - Zstd ImageLayerCompression = "Zstd" -) - -type ImageMediaTypes string - -func (ImageMediaTypes) IsEnum() {} - -const ( - Dockermediatypes ImageMediaTypes = "DockerMediaTypes" - - Ocimediatypes ImageMediaTypes = "OCIMediaTypes" -) - -type ModuleSourceKind string - -func (ModuleSourceKind) IsEnum() {} - -const ( - GitSource ModuleSourceKind = "GIT_SOURCE" - - LocalSource ModuleSourceKind = "LOCAL_SOURCE" -) - -type NetworkProtocol string - -func (NetworkProtocol) IsEnum() {} - -const ( - Tcp NetworkProtocol = "TCP" - - Udp NetworkProtocol = "UDP" -) - -type TypeDefKind string - -func (TypeDefKind) IsEnum() {} - -const ( - // A boolean value. - BooleanKind TypeDefKind = "BOOLEAN_KIND" - - // A GraphQL enum type and its values - // - // Always paired with an EnumTypeDef. - EnumKind TypeDefKind = "ENUM_KIND" - - // A graphql input type, used only when representing the core API via TypeDefs. - InputKind TypeDefKind = "INPUT_KIND" - - // An integer value. - IntegerKind TypeDefKind = "INTEGER_KIND" - - // A named type of functions that can be matched+implemented by other objects+interfaces. - // - // Always paired with an InterfaceTypeDef. - InterfaceKind TypeDefKind = "INTERFACE_KIND" - - // A list of values all having the same type. - // - // Always paired with a ListTypeDef. - ListKind TypeDefKind = "LIST_KIND" - - // A named type defined in the GraphQL schema, with fields and functions. - // - // Always paired with an ObjectTypeDef. - ObjectKind TypeDefKind = "OBJECT_KIND" - - // A scalar value of any basic kind. - ScalarKind TypeDefKind = "SCALAR_KIND" - - // A string value. - StringKind TypeDefKind = "STRING_KIND" - - // A special kind used to signify that no value is returned. - // - // This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. - VoidKind TypeDefKind = "VOID_KIND" -) - -type Client struct { - query *querybuilder.Selection - client graphql.Client -} - -var dag *Client - -func init() { - gqlClient, q := getClientParams() - dag = &Client{ - query: q.Client(gqlClient), - client: gqlClient, - } -} - -func Connect() *Client { - return dag -} - -// GraphQLClient returns the underlying graphql.Client -func (c *Client) GraphQLClient() graphql.Client { - return c.client -} - -func getClientParams() (graphql.Client, *querybuilder.Selection) { - portStr, ok := os.LookupEnv("DAGGER_SESSION_PORT") - if !ok { - panic("DAGGER_SESSION_PORT is not set") - } - port, err := strconv.Atoi(portStr) - if err != nil { - panic(fmt.Errorf("DAGGER_SESSION_PORT %q is invalid: %w", portStr, err)) - } - - sessionToken := os.Getenv("DAGGER_SESSION_TOKEN") - if sessionToken == "" { - panic("DAGGER_SESSION_TOKEN is not set") - } - - host := fmt.Sprintf("127.0.0.1:%d", port) - - dialTransport := &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("tcp", host) - }, - } - httpClient := &http.Client{ - Transport: roundTripperFunc(func(r *http.Request) (*http.Response, error) { - r.SetBasicAuth(sessionToken, "") - - // detect $TRACEPARENT set by 'dagger run' - r = r.WithContext(fallbackSpanContext(r.Context())) - - // propagate span context via headers (i.e. for Dagger-in-Dagger) - telemetry.Propagator.Inject(r.Context(), propagation.HeaderCarrier(r.Header)) - - return dialTransport.RoundTrip(r) - }), - } - gqlClient := errorWrappedClient{graphql.NewClient(fmt.Sprintf("http://%s/query", host), httpClient)} - - return gqlClient, querybuilder.Query() -} - -func fallbackSpanContext(ctx context.Context) context.Context { - if trace.SpanContextFromContext(ctx).IsValid() { - return ctx - } - return telemetry.Propagator.Extract(ctx, telemetry.NewEnvCarrier(true)) -} - -// TODO: pollutes namespace, move to non internal package in dagger.io/dagger -type roundTripperFunc func(*http.Request) (*http.Response, error) - -func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { - return fn(req) -} - -type errorWrappedClient struct { - graphql.Client -} - -func (c errorWrappedClient) MakeRequest(ctx context.Context, req *graphql.Request, resp *graphql.Response) error { - err := c.Client.MakeRequest(ctx, req, resp) - if err != nil { - if e := getCustomError(err); e != nil { - return e - } - return err - } - return nil -} diff --git a/internal/querybuilder/marshal.go b/internal/querybuilder/marshal.go deleted file mode 100644 index 1f5468af..00000000 --- a/internal/querybuilder/marshal.go +++ /dev/null @@ -1,162 +0,0 @@ -package querybuilder - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "reflect" - "strings" - - gqlgen "github.com/99designs/gqlgen/graphql" - "golang.org/x/exp/slices" - "golang.org/x/sync/errgroup" -) - -// GraphQLMarshaller is an internal interface for marshalling an object into GraphQL. -type GraphQLMarshaller interface { - // XXX_GraphQLType is an internal function. It returns the native GraphQL type name - XXX_GraphQLType() string - // XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object - XXX_GraphQLIDType() string - // XXX_GraphqlID is an internal function. It returns the underlying type ID - XXX_GraphQLID(ctx context.Context) (string, error) - json.Marshaler -} - -const ( - GraphQLMarshallerType = "XXX_GraphQLType" - GraphQLMarshallerIDType = "XXX_GraphQLIDType" - GraphQLMarshallerID = "XXX_GraphQLID" -) - -type enum interface { - IsEnum() -} - -var ( - gqlMarshaller = reflect.TypeOf((*GraphQLMarshaller)(nil)).Elem() - enumT = reflect.TypeOf((*enum)(nil)).Elem() -) - -func MarshalGQL(ctx context.Context, v any) (string, error) { - return marshalValue(ctx, reflect.ValueOf(v)) -} - -func marshalValue(ctx context.Context, v reflect.Value) (string, error) { - t := v.Type() - - if t.Implements(gqlMarshaller) { - return marshalCustom(ctx, v) - } - - switch t.Kind() { - case reflect.Bool: - return fmt.Sprintf("%t", v.Bool()), nil - case reflect.Int: - return fmt.Sprintf("%d", v.Int()), nil - case reflect.String: - if t.Implements(enumT) { - // enums render as their literal value - return v.String(), nil - } - - // escape strings following graphQL spec - // https://github.com/graphql/graphql-spec/blob/main/spec/Section%202%20--%20Language.md#string-value - var buf bytes.Buffer - gqlgen.MarshalString(v.String()).MarshalGQL(&buf) - return buf.String(), nil - case reflect.Pointer, reflect.Interface: - if v.IsNil() { - return "null", nil - } - return marshalValue(ctx, v.Elem()) - case reflect.Slice: - n := v.Len() - elems := make([]string, n) - eg, gctx := errgroup.WithContext(ctx) - for i := 0; i < n; i++ { - i := i - eg.Go(func() error { - m, err := marshalValue(gctx, v.Index(i)) - if err != nil { - return err - } - elems[i] = m - return nil - }) - } - if err := eg.Wait(); err != nil { - return "", err - } - return fmt.Sprintf("[%s]", strings.Join(elems, ",")), nil - case reflect.Struct: - n := v.NumField() - elems := make([]string, n) - eg, gctx := errgroup.WithContext(ctx) - for i := 0; i < n; i++ { - i := i - eg.Go(func() error { - f := t.Field(i) - fv := v.Field(i) - name := f.Name - jsonTag := strings.Split(f.Tag.Get("json"), ",") - if jsonTag[0] != "" { - name = jsonTag[0] - } - isOptional := slices.Contains(jsonTag[1:], "omitempty") - if isOptional && IsZeroValue(fv.Interface()) { - return nil - } - m, err := marshalValue(gctx, fv) - if err != nil { - return err - } - if m != `""` && m != "null" { - elems[i] = fmt.Sprintf("%s:%s", name, m) - } - return nil - }) - } - if err := eg.Wait(); err != nil { - return "", err - } - nonNullElems := make([]string, 0, n) - for _, elem := range elems { - if elem != "" { - nonNullElems = append(nonNullElems, elem) - } - } - return fmt.Sprintf("{%s}", strings.Join(nonNullElems, ",")), nil - default: - panic(fmt.Errorf("unsupported argument of kind %s", t.Kind())) - } -} - -func marshalCustom(ctx context.Context, v reflect.Value) (string, error) { - result := v.MethodByName(GraphQLMarshallerID).Call([]reflect.Value{ - reflect.ValueOf(ctx), - }) - if len(result) != 2 { - panic(result) - } - err := result[1].Interface() - if err != nil { - return "", err.(error) - } - - return fmt.Sprintf("%q", result[0].String()), nil -} - -func IsZeroValue(value any) bool { - v := reflect.ValueOf(value) - kind := v.Type().Kind() - switch kind { - case reflect.Pointer: - return v.IsNil() - case reflect.Slice, reflect.Array: - return v.Len() == 0 - default: - return v.IsZero() - } -} diff --git a/internal/querybuilder/querybuilder.go b/internal/querybuilder/querybuilder.go deleted file mode 100644 index 2f5acc97..00000000 --- a/internal/querybuilder/querybuilder.go +++ /dev/null @@ -1,213 +0,0 @@ -package querybuilder - -import ( - "context" - "encoding/json" - "fmt" - "runtime/debug" - "strings" - "sync" - - "github.com/Khan/genqlient/graphql" - "golang.org/x/sync/errgroup" -) - -func Query() *Selection { - return &Selection{} -} - -type Selection struct { - name string - alias string - args map[string]*argument - bind any - multiple bool - - prev *Selection - - client graphql.Client -} - -func (s *Selection) path() []*Selection { - selections := []*Selection{} - for sel := s; sel.prev != nil; sel = sel.prev { - selections = append([]*Selection{sel}, selections...) - } - - return selections -} - -func (s *Selection) Root() *Selection { - return &Selection{ - client: s.client, - } -} - -func (s *Selection) SelectWithAlias(alias, name string) *Selection { - sel := &Selection{ - name: name, - prev: s, - alias: alias, - client: s.client, - } - return sel -} - -func (s *Selection) Select(name string) *Selection { - return s.SelectWithAlias("", name) -} - -func (s *Selection) SelectMultiple(name ...string) *Selection { - sel := s.SelectWithAlias("", strings.Join(name, " ")) - sel.multiple = true - return sel -} - -func (s *Selection) Arg(name string, value any) *Selection { - sel := *s - if sel.args == nil { - sel.args = map[string]*argument{} - } - - sel.args[name] = &argument{ - value: value, - } - return &sel -} - -func (s *Selection) Bind(v interface{}) *Selection { - sel := *s - sel.bind = v - return &sel -} - -func (s *Selection) marshalArguments(ctx context.Context) error { - eg, gctx := errgroup.WithContext(ctx) - for _, sel := range s.path() { - for _, arg := range sel.args { - arg := arg - eg.Go(func() error { - return arg.marshal(gctx) - }) - } - } - - return eg.Wait() -} - -func (s *Selection) Build(ctx context.Context) (string, error) { - if err := s.marshalArguments(ctx); err != nil { - return "", err - } - - var b strings.Builder - b.WriteString("query") - - path := s.path() - - for _, sel := range path { - if sel.prev != nil && sel.prev.multiple { - return "", fmt.Errorf("sibling selections not end of chain") - } - - b.WriteRune('{') - - if sel.alias != "" { - b.WriteString(sel.alias) - b.WriteRune(':') - } - - b.WriteString(sel.name) - - if len(sel.args) > 0 { - b.WriteRune('(') - i := 0 - for name, arg := range sel.args { - if i > 0 { - b.WriteString(", ") - } - b.WriteString(name) - b.WriteRune(':') - b.WriteString(arg.marshalled) - i++ - } - b.WriteRune(')') - } - } - - b.WriteString(strings.Repeat("}", len(path))) - return b.String(), nil -} - -func (s *Selection) unpack(data any) error { - for _, i := range s.path() { - k := i.name - if i.alias != "" { - k = i.alias - } - - if !i.multiple { - if f, ok := data.(map[string]any); ok { - data = f[k] - } - } - - if i.bind != nil { - marshalled, err := json.Marshal(data) - if err != nil { - return err - } - if err := json.Unmarshal(marshalled, i.bind); err != nil { - return err - } - } - } - - return nil -} - -func (s *Selection) Client(c graphql.Client) *Selection { - sel := *s - sel.client = c - return &sel -} - -func (s *Selection) Execute(ctx context.Context) error { - if s.client == nil { - debug.PrintStack() - return fmt.Errorf("no client configured for selection") - } - - query, err := s.Build(ctx) - if err != nil { - return err - } - - var response any - err = s.client.MakeRequest(ctx, - &graphql.Request{ - Query: query, - }, - &graphql.Response{Data: &response}, - ) - if err != nil { - return err - } - - return s.unpack(response) -} - -type argument struct { - value any - - marshalled string - marshalledErr error - once sync.Once -} - -func (a *argument) marshal(ctx context.Context) error { - a.once.Do(func() { - a.marshalled, a.marshalledErr = MarshalGQL(ctx, a.value) - }) - return a.marshalledErr -} diff --git a/internal/telemetry/attrs.go b/internal/telemetry/attrs.go deleted file mode 100644 index f830f3fc..00000000 --- a/internal/telemetry/attrs.go +++ /dev/null @@ -1,86 +0,0 @@ -package telemetry - -// The following attributes are used by the UI to interpret spans and control -// their behavior in the UI. -const ( - // The base64-encoded, protobuf-marshalled callpbv1.Call that this span - // represents. - DagCallAttr = "dagger.io/dag.call" - - // The digest of the protobuf-marshalled Call that this span represents. - // - // This value acts as a node ID in the conceptual DAG. - DagDigestAttr = "dagger.io/dag.digest" - - // The list of DAG digests that the span depends on. - // - // This is not currently used by the UI, but it could be used to drive higher - // level DAG walking processes without having to unmarshal the full call. - DagInputsAttr = "dagger.io/dag.inputs" - - // The DAG call digest that the call returned, if the call returned an - // Object. - // - // This information is used to simplify values in the UI by showing their - // highest-level creator. For example, if foo().bar() returns a().b().c(), we - // will show foo().bar() instead of a().b().c() as it will be a more - // recognizable value to the user. - DagOutputAttr = "dagger.io/dag.output" - - // Indicates that this span is "internal" and can be hidden by default. - // - // Internal spans may typically be revealed with a toggle. - UIInternalAttr = "dagger.io/ui.internal" - - // Hide child spans by default. - // - // Encapsulated child spans may typically be revealed if the parent span errors. - UIEncapsulateAttr = "dagger.io/ui.encapsulate" - - // Hide span by default. - // - // This is functionally the same as UIEncapsulateAttr, but is instead set - // on a child instead of a parent. - UIEncapsulatedAttr = "dagger.io/ui.encapsulated" - - // Substitute the span for its children and move its logs to its parent. - UIPassthroughAttr = "dagger.io/ui.passthrough" //nolint: gosec // lol - - // NB: the following attributes are not currently used. - - // Indicates that this span was a cache hit and did nothing. - CachedAttr = "dagger.io/dag.cached" - - // Indicates that this span was interrupted. - CanceledAttr = "dagger.io/dag.canceled" - - // The base64-encoded, protobuf-marshalled Buildkit LLB op payload that this - // span represents. - LLBOpAttr = "dagger.io/llb.op" - - // The IDs of effects which will be correlated to this span. - // - // This is typically a list of LLB operation digests, but can be any string. - EffectIDsAttr = "dagger.io/effect.ids" - - // The ID of the effect that this span represents. - EffectIDAttr = "dagger.io/effect.id" - - // The amount of progress that needs to be reached. - ProgressTotalAttr = "dagger.io/progress.total" - - // Current value for the progress. - ProgressCurrentAttr = "dagger.io/progress.current" - - // Indicates the units for the progress numbers. - ProgressUnitsAttr = "dagger.io/progress.units" - - // The stdio stream a log corresponds to (1 for stdout, 2 for stderr). - StdioStreamAttr = "stdio.stream" - - // Indicates whether the log stream has ended. - StdioEOFAttr = "stdio.eof" - - // Indicates whether the log should be shown globally. - LogsGlobalAttr = "dagger.io/logs.global" -) diff --git a/internal/telemetry/env.go b/internal/telemetry/env.go deleted file mode 100644 index 3c1b23ff..00000000 --- a/internal/telemetry/env.go +++ /dev/null @@ -1,59 +0,0 @@ -package telemetry - -import ( - "context" - "os" - "strings" - - "go.opentelemetry.io/otel/propagation" -) - -func PropagationEnv(ctx context.Context) []string { - carrier := NewEnvCarrier(false) - Propagator.Inject(ctx, carrier) - return carrier.Env -} - -type EnvCarrier struct { - System bool - Env []string -} - -func NewEnvCarrier(system bool) *EnvCarrier { - return &EnvCarrier{ - System: system, - } -} - -var _ propagation.TextMapCarrier = (*EnvCarrier)(nil) - -func (c *EnvCarrier) Get(key string) string { - envName := strings.ToUpper(key) - for _, env := range c.Env { - env, val, ok := strings.Cut(env, "=") - if ok && env == envName { - return val - } - } - if c.System { - if envVal := os.Getenv(envName); envVal != "" { - return envVal - } - } - return "" -} - -func (c *EnvCarrier) Set(key, val string) { - c.Env = append(c.Env, strings.ToUpper(key)+"="+val) -} - -func (c *EnvCarrier) Keys() []string { - keys := make([]string, 0, len(c.Env)) - for _, env := range c.Env { - env, _, ok := strings.Cut(env, "=") - if ok { - keys = append(keys, env) - } - } - return keys -} diff --git a/internal/telemetry/exporters.go b/internal/telemetry/exporters.go deleted file mode 100644 index 988d1add..00000000 --- a/internal/telemetry/exporters.go +++ /dev/null @@ -1,120 +0,0 @@ -package telemetry - -import ( - "context" - - sdklog "go.opentelemetry.io/otel/sdk/log" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" - "go.opentelemetry.io/otel/trace/noop" - "golang.org/x/sync/errgroup" -) - -type SpanForwarder struct { - Processors []sdktrace.SpanProcessor -} - -var _ sdktrace.SpanExporter = SpanForwarder{} - -type discardWritesSpan struct { - noop.Span - sdktrace.ReadOnlySpan -} - -func (s discardWritesSpan) SpanContext() trace.SpanContext { - return s.ReadOnlySpan.SpanContext() -} - -func (m SpanForwarder) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error { - eg := new(errgroup.Group) - for _, p := range m.Processors { - p := p - eg.Go(func() error { - for _, span := range spans { - if span.EndTime().Before(span.StartTime()) { - p.OnStart(ctx, discardWritesSpan{noop.Span{}, span}) - } else { - p.OnEnd(span) - } - } - return nil - }) - } - return eg.Wait() -} - -func (m SpanForwarder) Shutdown(ctx context.Context) error { - eg := new(errgroup.Group) - for _, p := range m.Processors { - p := p - eg.Go(func() error { - return p.Shutdown(ctx) - }) - } - return eg.Wait() -} - -// FilterLiveSpansExporter is a SpanExporter that filters out spans that are -// currently running, as indicated by an end time older than its start time -// (typically year 1753). -type FilterLiveSpansExporter struct { - sdktrace.SpanExporter -} - -// ExportSpans passes each span to the span processor's OnEnd hook so that it -// can be batched and emitted more efficiently. -func (exp FilterLiveSpansExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error { - filtered := make([]sdktrace.ReadOnlySpan, 0, len(spans)) - for _, span := range spans { - if span.StartTime().After(span.EndTime()) { - } else { - filtered = append(filtered, span) - } - } - if len(filtered) == 0 { - return nil - } - return exp.SpanExporter.ExportSpans(ctx, filtered) -} - -type LogForwarder struct { - Processors []sdklog.Processor -} - -var _ sdklog.Exporter = LogForwarder{} - -func (m LogForwarder) Export(ctx context.Context, logs []sdklog.Record) error { - eg := new(errgroup.Group) - for _, e := range m.Processors { - e := e - eg.Go(func() error { - for _, log := range logs { - _ = e.OnEmit(ctx, log) - } - return nil - }) - } - return eg.Wait() -} - -func (m LogForwarder) Shutdown(ctx context.Context) error { - eg := new(errgroup.Group) - for _, e := range m.Processors { - e := e - eg.Go(func() error { - return e.Shutdown(ctx) - }) - } - return eg.Wait() -} - -func (m LogForwarder) ForceFlush(ctx context.Context) error { - eg := new(errgroup.Group) - for _, e := range m.Processors { - e := e - eg.Go(func() error { - return e.ForceFlush(ctx) - }) - } - return eg.Wait() -} diff --git a/internal/telemetry/init.go b/internal/telemetry/init.go deleted file mode 100644 index 724b5dd3..00000000 --- a/internal/telemetry/init.go +++ /dev/null @@ -1,377 +0,0 @@ -package telemetry - -import ( - "context" - "fmt" - "log/slog" - "net" - "net/url" - "os" - "strings" - "sync" - "time" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" - "go.opentelemetry.io/otel/propagation" - sdklog "go.opentelemetry.io/otel/sdk/log" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.24.0" - "google.golang.org/grpc" -) - -func OTelConfigured() bool { - for _, env := range os.Environ() { - if strings.HasPrefix(env, "OTEL_") { - return true - } - } - return false -} - -var configuredSpanExporter sdktrace.SpanExporter -var configuredSpanExporterOnce sync.Once - -func ConfiguredSpanExporter(ctx context.Context) (sdktrace.SpanExporter, bool) { - ctx = context.WithoutCancel(ctx) - - configuredSpanExporterOnce.Do(func() { - if !OTelConfigured() { - return - } - - var err error - - var proto string - if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"); v != "" { - proto = v - } else if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" { - proto = v - } else { - // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/protocol/exporter.md#specify-protocol - proto = "http/protobuf" - } - - var endpoint string - if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"); v != "" { - endpoint = v - } else if v := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT"); v != "" { - if proto == "http/protobuf" { - endpoint, err = url.JoinPath(v, "v1", "traces") - if err != nil { - slog.Warn("failed to join path", "error", err) - return - } - } else { - endpoint = v - } - } - - switch proto { - case "http/protobuf", "http": - headers := map[string]string{} - if hs := os.Getenv("OTEL_EXPORTER_OTLP_HEADERS"); hs != "" { - for _, header := range strings.Split(hs, ",") { - name, value, _ := strings.Cut(header, "=") - headers[name] = value - } - } - configuredSpanExporter, err = otlptracehttp.New(ctx, - otlptracehttp.WithEndpointURL(endpoint), - otlptracehttp.WithHeaders(headers)) - case "grpc": - var u *url.URL - u, err = url.Parse(endpoint) - if err != nil { - slog.Warn("bad OTLP logs endpoint %q: %w", endpoint, err) - return - } - opts := []otlptracegrpc.Option{ - otlptracegrpc.WithEndpointURL(endpoint), - } - if u.Scheme == "unix" { - dialer := func(ctx context.Context, addr string) (net.Conn, error) { - return net.Dial(u.Scheme, u.Path) - } - opts = append(opts, - otlptracegrpc.WithDialOption(grpc.WithContextDialer(dialer)), - otlptracegrpc.WithInsecure()) - } - configuredSpanExporter, err = otlptracegrpc.New(ctx, opts...) - default: - err = fmt.Errorf("unknown OTLP protocol: %s", proto) - } - if err != nil { - slog.Warn("failed to configure tracing", "error", err) - } - }) - return configuredSpanExporter, configuredSpanExporter != nil -} - -var configuredLogExporter sdklog.Exporter -var configuredLogExporterOnce sync.Once - -func ConfiguredLogExporter(ctx context.Context) (sdklog.Exporter, bool) { - ctx = context.WithoutCancel(ctx) - - configuredLogExporterOnce.Do(func() { - var err error - - var endpoint string - if v := os.Getenv("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"); v != "" { - endpoint = v - } else if v := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT"); v != "" { - // we can't assume all OTLP endpoints support logs. better to be explicit - // than have noisy otel errors. - return - } - if endpoint == "" { - return - } - - var proto string - if v := os.Getenv("OTEL_EXPORTER_OTLP_LOGS_PROTOCOL"); v != "" { - proto = v - } else if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" { - proto = v - } else { - // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/protocol/exporter.md#specify-protocol - proto = "http/protobuf" - } - - switch proto { - case "http/protobuf", "http": - headers := map[string]string{} - if hs := os.Getenv("OTEL_EXPORTER_OTLP_HEADERS"); hs != "" { - for _, header := range strings.Split(hs, ",") { - name, value, _ := strings.Cut(header, "=") - headers[name] = value - } - } - configuredLogExporter, err = otlploghttp.New(ctx, - otlploghttp.WithEndpointURL(endpoint), - otlploghttp.WithHeaders(headers)) - - case "grpc": - // FIXME: bring back when it's actually implemented - - // u, err := url.Parse(endpoint) - // if err != nil { - // slog.Warn("bad OTLP logs endpoint %q: %w", endpoint, err) - // return - // } - // - opts := []otlploggrpc.Option{ - // otlploggrpc.WithEndpointURL(endpoint), - } - // if u.Scheme == "unix" { - // dialer := func(ctx context.Context, addr string) (net.Conn, error) { - // return net.Dial(u.Scheme, u.Path) - // } - // opts = append(opts, - // otlploggrpc.WithDialOption(grpc.WithContextDialer(dialer)), - // otlploggrpc.WithInsecure()) - // } - configuredLogExporter, err = otlploggrpc.New(ctx, opts...) - - default: - err = fmt.Errorf("unknown OTLP protocol: %s", proto) - } - if err != nil { - slog.Warn("failed to configure logging", "error", err) - } - }) - return configuredLogExporter, configuredLogExporter != nil -} - -// fallbackResource is the fallback resource definition. A more specific -// resource should be set in Init. -func fallbackResource() *resource.Resource { - return resource.NewWithAttributes( - semconv.SchemaURL, - semconv.ServiceNameKey.String("dagger"), - ) -} - -var ( - // set by Init, closed by Close - tracerProvider *sdktrace.TracerProvider = sdktrace.NewTracerProvider() -) - -type Config struct { - // Auto-detect exporters from OTEL_* env variables. - Detect bool - - // SpanProcessors are processors to prepend to the telemetry pipeline. - SpanProcessors []sdktrace.SpanProcessor - - // LiveTraceExporters are exporters that can receive updates for spans at runtime, - // rather than waiting until the span ends. - // - // Example: TUI, Cloud - LiveTraceExporters []sdktrace.SpanExporter - - // BatchedTraceExporters are exporters that receive spans in batches, after the - // spans have ended. - // - // Example: Honeycomb, Jaeger, etc. - BatchedTraceExporters []sdktrace.SpanExporter - - // LiveLogExporters are exporters that receive logs in batches of ~100ms. - LiveLogExporters []sdklog.Exporter - - // Resource is the resource describing this component and runtime - // environment. - Resource *resource.Resource -} - -// NearlyImmediate is 100ms, below which has diminishing returns in terms of -// visual perception vs. performance cost. -const NearlyImmediate = 100 * time.Millisecond - -// LiveTracesEnabled indicates that the configured OTEL_* exporter should be -// sent live span telemetry. -var LiveTracesEnabled = os.Getenv("OTEL_EXPORTER_OTLP_TRACES_LIVE") != "" - -var Resource *resource.Resource -var SpanProcessors = []sdktrace.SpanProcessor{} -var LogProcessors = []sdklog.Processor{} - -func InitEmbedded(ctx context.Context, res *resource.Resource) context.Context { - traceCfg := Config{ - Detect: false, // false, since we want "live" exporting - Resource: res, - } - if exp, ok := ConfiguredSpanExporter(ctx); ok { - traceCfg.LiveTraceExporters = append(traceCfg.LiveTraceExporters, exp) - } - if exp, ok := ConfiguredLogExporter(ctx); ok { - traceCfg.LiveLogExporters = append(traceCfg.LiveLogExporters, exp) - } - return Init(ctx, traceCfg) -} - -// Propagator is a composite propagator of everything we could possibly want. -// -// Do not rely on otel.GetTextMapPropagator() - it's prone to change from a -// random import. -var Propagator = propagation.NewCompositeTextMapPropagator( - propagation.Baggage{}, - propagation.TraceContext{}, -) - -// closeCtx holds on to the initial context returned by Init. Close will -// extract its providers and close them. -var closeCtx context.Context - -// Init sets up the global OpenTelemetry providers tracing, logging, and -// someday metrics providers. It is called by the CLI, the engine, and the -// container shim, so it needs to be versatile. -func Init(ctx context.Context, cfg Config) context.Context { - // Set up a text map propagator so that things, well, propagate. The default - // is a noop. - otel.SetTextMapPropagator(Propagator) - - // Inherit trace context from env if present. - ctx = Propagator.Extract(ctx, NewEnvCarrier(true)) - - // Log to slog. - otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { - slog.Error("failed to emit telemetry", "error", err) - })) - - if cfg.Resource == nil { - cfg.Resource = fallbackResource() - } - - // Set up the global resource so we can pass it into dynamically allocated - // log/trace providers at runtime. - Resource = cfg.Resource - - if cfg.Detect { - if exp, ok := ConfiguredSpanExporter(ctx); ok { - if LiveTracesEnabled { - cfg.LiveTraceExporters = append(cfg.LiveTraceExporters, exp) - } else { - cfg.BatchedTraceExporters = append(cfg.BatchedTraceExporters, - // Filter out unfinished spans to avoid confusing external systems. - // - // Normally we avoid sending them here by virtue of putting this into - // BatchedTraceExporters, but that only applies to the local process. - // Unfinished spans may end up here if they're proxied out of the - // engine via Params.EngineTrace. - FilterLiveSpansExporter{exp}) - } - } - if exp, ok := ConfiguredLogExporter(ctx); ok { - cfg.LiveLogExporters = append(cfg.LiveLogExporters, exp) - } - } - - traceOpts := []sdktrace.TracerProviderOption{ - sdktrace.WithResource(cfg.Resource), - } - - SpanProcessors = cfg.SpanProcessors - - for _, exporter := range cfg.LiveTraceExporters { - processor := NewLiveSpanProcessor(exporter) - SpanProcessors = append(SpanProcessors, processor) - } - for _, exporter := range cfg.BatchedTraceExporters { - processor := sdktrace.NewBatchSpanProcessor(exporter) - SpanProcessors = append(SpanProcessors, processor) - } - for _, proc := range SpanProcessors { - traceOpts = append(traceOpts, sdktrace.WithSpanProcessor(proc)) - } - - tracerProvider = sdktrace.NewTracerProvider(traceOpts...) - - // Register our TracerProvider as the global so any imported instrumentation - // in the future will default to using it. - // - // NB: this is also necessary so that we can establish a root span, otherwise - // telemetry doesn't work. - otel.SetTracerProvider(tracerProvider) - - // Set up a log provider if configured. - if len(cfg.LiveLogExporters) > 0 { - logOpts := []sdklog.LoggerProviderOption{ - sdklog.WithResource(cfg.Resource), - } - for _, exp := range cfg.LiveLogExporters { - processor := sdklog.NewBatchProcessor(exp, - sdklog.WithExportInterval(NearlyImmediate)) - LogProcessors = append(LogProcessors, processor) - logOpts = append(logOpts, sdklog.WithProcessor(processor)) - } - ctx = WithLoggerProvider(ctx, sdklog.NewLoggerProvider(logOpts...)) - } - - closeCtx = ctx - - return ctx -} - -// Close shuts down the global OpenTelemetry providers, flushing any remaining -// data to the configured exporters. -func Close() { - ctx := closeCtx - flushCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 30*time.Second) - defer cancel() - if tracerProvider != nil { - if err := tracerProvider.Shutdown(flushCtx); err != nil { - slog.Error("failed to shut down tracer provider", "error", err) - } - } - if loggerProvider := LoggerProvider(ctx); loggerProvider != nil { - if err := loggerProvider.Shutdown(flushCtx); err != nil { - slog.Error("failed to shut down logger provider", "error", err) - } - } -} diff --git a/internal/telemetry/live.go b/internal/telemetry/live.go deleted file mode 100644 index 7294457b..00000000 --- a/internal/telemetry/live.go +++ /dev/null @@ -1,31 +0,0 @@ -package telemetry - -import ( - "context" - - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -// LiveSpanProcessor is a SpanProcessor whose OnStart calls OnEnd on the -// underlying SpanProcessor in order to send live telemetry. -type LiveSpanProcessor struct { - sdktrace.SpanProcessor -} - -func NewLiveSpanProcessor(exp sdktrace.SpanExporter) *LiveSpanProcessor { - return &LiveSpanProcessor{ - SpanProcessor: sdktrace.NewBatchSpanProcessor( - // NOTE: span heartbeating is handled by the Cloud exporter - exp, - sdktrace.WithBatchTimeout(NearlyImmediate), - ), - } -} - -func (p *LiveSpanProcessor) OnStart(ctx context.Context, span sdktrace.ReadWriteSpan) { - // Send a read-only snapshot of the live span downstream so it can be - // filtered out by FilterLiveSpansExporter. Otherwise the span can complete - // before being exported, resulting in two completed spans being sent, which - // will confuse traditional OpenTelemetry services. - p.SpanProcessor.OnEnd(SnapshotSpan(span)) -} diff --git a/internal/telemetry/logging.go b/internal/telemetry/logging.go deleted file mode 100644 index a152a042..00000000 --- a/internal/telemetry/logging.go +++ /dev/null @@ -1,119 +0,0 @@ -package telemetry - -import ( - "context" - "errors" - "io" - "time" - - "go.opentelemetry.io/otel/log" - sdklog "go.opentelemetry.io/otel/sdk/log" -) - -type loggerProviderKey struct{} - -// WithLoggerProvider returns a new context with the given LoggerProvider. -func WithLoggerProvider(ctx context.Context, provider *sdklog.LoggerProvider) context.Context { - return context.WithValue(ctx, loggerProviderKey{}, provider) -} - -// LoggerProvider returns the LoggerProvider from the context. -func LoggerProvider(ctx context.Context) *sdklog.LoggerProvider { - loggerProvider := sdklog.NewLoggerProvider() - if val := ctx.Value(loggerProviderKey{}); val != nil { - loggerProvider = val.(*sdklog.LoggerProvider) - } - return loggerProvider -} - -// Logger returns a logger with the given name. -func Logger(ctx context.Context, name string) log.Logger { - return LoggerProvider(ctx).Logger(name) // TODO more instrumentation attrs -} - -// SpanStdio returns a pair of io.WriteClosers which will send log records with -// stdio.stream=1 for stdout and stdio.stream=2 for stderr. Closing either of -// them will send a log record for that stream with an empty body and -// stdio.eof=true. -// -// SpanStdio should be used when a span represents a process that writes to -// stdout/stderr and terminates them with an EOF, to confirm that all data has -// been received. It should not be used for general-purpose logging. -// -// Both streams must be closed to ensure that draining completes. -func SpanStdio(ctx context.Context, name string, attrs ...log.KeyValue) SpanStreams { - logger := Logger(ctx, name) - return SpanStreams{ - Stdout: &spanStream{ - Writer: &Writer{ - ctx: ctx, - logger: logger, - attrs: append([]log.KeyValue{log.Int(StdioStreamAttr, 1)}, attrs...), - }, - }, - Stderr: &spanStream{ - Writer: &Writer{ - ctx: ctx, - logger: logger, - attrs: append([]log.KeyValue{log.Int(StdioStreamAttr, 2)}, attrs...), - }, - }, - } -} - -// Writer is an io.Writer that emits log records. -type Writer struct { - ctx context.Context - logger log.Logger - attrs []log.KeyValue -} - -// NewWriter returns a new Writer that emits log records with the given logger -// name and attributes. -func NewWriter(ctx context.Context, name string, attrs ...log.KeyValue) io.Writer { - return &Writer{ - ctx: ctx, - logger: Logger(ctx, name), - attrs: attrs, - } -} - -// Write emits a log record with the given payload as a string body. -func (w *Writer) Write(p []byte) (int, error) { - w.Emit(log.StringValue(string(p))) - return len(p), nil -} - -// Emit sends a log record with the given body and additional attributes. -func (w *Writer) Emit(body log.Value, attrs ...log.KeyValue) { - rec := log.Record{} - rec.SetTimestamp(time.Now()) - rec.SetBody(body) - rec.AddAttributes(w.attrs...) - rec.AddAttributes(attrs...) - w.logger.Emit(w.ctx, rec) -} - -// SpanStreams contains the stdout and stderr for a span. -type SpanStreams struct { - Stdout io.WriteCloser - Stderr io.WriteCloser -} - -// Calling Close closes both streams. -func (sl SpanStreams) Close() error { - return errors.Join( - sl.Stdout.Close(), - sl.Stderr.Close(), - ) -} - -type spanStream struct { - *Writer -} - -// Close emits an EOF log record. -func (w *spanStream) Close() error { - w.Writer.Emit(log.StringValue(""), log.Bool(StdioEOFAttr, true)) - return nil -} diff --git a/internal/telemetry/proxy.go b/internal/telemetry/proxy.go deleted file mode 100644 index 7ebea2d9..00000000 --- a/internal/telemetry/proxy.go +++ /dev/null @@ -1,6 +0,0 @@ -package telemetry - -// FIXME: this file exists to plant a "tombstone" over the previously generated -// proxy.go file. -// -// We should maybe just withoutDirectory('./internal') or something instead. diff --git a/internal/telemetry/span.go b/internal/telemetry/span.go deleted file mode 100644 index cfeb85b4..00000000 --- a/internal/telemetry/span.go +++ /dev/null @@ -1,53 +0,0 @@ -package telemetry - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/trace" -) - -// Encapsulate can be applied to a span to indicate that this span should -// collapse its children by default. -func Encapsulate() trace.SpanStartOption { - return trace.WithAttributes(attribute.Bool(UIEncapsulateAttr, true)) -} - -// Encapsulated can be applied to a child span to indicate that it should be -// collapsed by default. -func Encapsulated() trace.SpanStartOption { - return trace.WithAttributes(attribute.Bool(UIEncapsulatedAttr, true)) -} - -// Internal can be applied to a span to indicate that this span should not be -// shown to the user by default. -func Internal() trace.SpanStartOption { - return trace.WithAttributes(attribute.Bool(UIInternalAttr, true)) -} - -// Passthrough can be applied to a span to cause the UI to skip over it and -// show its children instead. -func Passthrough() trace.SpanStartOption { - return trace.WithAttributes(attribute.Bool(UIPassthroughAttr, true)) -} - -// Tracer returns a Tracer for the given library using the provider from -// the current span. -func Tracer(ctx context.Context, lib string) trace.Tracer { - return trace.SpanFromContext(ctx).TracerProvider().Tracer(lib) -} - -// End is a helper to end a span with an error if the function returns an error. -// -// It is optimized for use as a defer one-liner with a function that has a -// named error return value, conventionally `rerr`. -// -// defer telemetry.End(span, func() error { return rerr }) -func End(span trace.Span, fn func() error) { - if err := fn(); err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, err.Error()) - } - span.End() -} diff --git a/internal/telemetry/transform.go b/internal/telemetry/transform.go deleted file mode 100644 index cfca401e..00000000 --- a/internal/telemetry/transform.go +++ /dev/null @@ -1,961 +0,0 @@ -package telemetry - -import ( - "fmt" - "log/slog" - "time" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/log" - "go.opentelemetry.io/otel/sdk/instrumentation" - sdklog "go.opentelemetry.io/otel/sdk/log" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" - otlpcommonv1 "go.opentelemetry.io/proto/otlp/common/v1" - otlplogsv1 "go.opentelemetry.io/proto/otlp/logs/v1" - otlpresourcev1 "go.opentelemetry.io/proto/otlp/resource/v1" - otlptracev1 "go.opentelemetry.io/proto/otlp/trace/v1" -) - -func SnapshotSpan(span sdktrace.ReadOnlySpan) sdktrace.ReadOnlySpan { - return SpansFromPB(SpansToPB([]sdktrace.ReadOnlySpan{span}))[0] -} - -func LogsToPB(sdl []sdklog.Record) []*otlplogsv1.ResourceLogs { - if len(sdl) == 0 { - return nil - } - - rsm := make(map[attribute.Distinct]*otlplogsv1.ResourceLogs) - - type key struct { - r attribute.Distinct - is instrumentation.Scope - } - ssm := make(map[key]*otlplogsv1.ScopeLogs) - - var resources int - for _, sd := range sdl { - res := sd.Resource() - rKey := res.Equivalent() - k := key{ - r: rKey, - is: sd.InstrumentationScope(), - } - scopeLog, iOk := ssm[k] - if !iOk { - // Either the resource or instrumentation scope were unknown. - scopeLog = &otlplogsv1.ScopeLogs{ - Scope: InstrumentationScopeToPB(sd.InstrumentationScope()), - LogRecords: []*otlplogsv1.LogRecord{}, - SchemaUrl: sd.InstrumentationScope().SchemaURL, - } - } - scopeLog.LogRecords = append(scopeLog.LogRecords, logRecord(sd)) - ssm[k] = scopeLog - - rs, rOk := rsm[rKey] - if !rOk { - resources++ - // The resource was unknown. - rs = &otlplogsv1.ResourceLogs{ - Resource: ResourceToPB(res), - ScopeLogs: []*otlplogsv1.ScopeLogs{scopeLog}, - SchemaUrl: res.SchemaURL(), - } - rsm[rKey] = rs - continue - } - - // The resource has been seen before. Check if the instrumentation - // library lookup was unknown because if so we need to add it to the - // ResourceSpans. Otherwise, the instrumentation library has already - // been seen and the append we did above will be included it in the - // ScopeSpans reference. - if !iOk { - rs.ScopeLogs = append(rs.ScopeLogs, scopeLog) - } - } - - // Transform the categorized map into a slice - rss := make([]*otlplogsv1.ResourceLogs, 0, resources) - for _, rs := range rsm { - rss = append(rss, rs) - } - return rss -} - -func InstrumentationScopeToPB(il instrumentation.Scope) *otlpcommonv1.InstrumentationScope { - if il == (instrumentation.Scope{}) { - return nil - } - return &otlpcommonv1.InstrumentationScope{ - Name: il.Name, - Version: il.Version, - } -} - -// span transforms a Span into an OTLP span. -func logRecord(l sdklog.Record) *otlplogsv1.LogRecord { - attrs := []*otlpcommonv1.KeyValue{} - l.WalkAttributes(func(kv log.KeyValue) bool { - attrs = append(attrs, &otlpcommonv1.KeyValue{ - Key: kv.Key, - Value: LogValueToPB(kv.Value), - }) - return true - }) - - tid, sid := l.TraceID(), l.SpanID() - s := &otlplogsv1.LogRecord{ - TimeUnixNano: uint64(l.Timestamp().UnixNano()), - SeverityNumber: otlplogsv1.SeverityNumber(l.Severity()), - SeverityText: l.SeverityText(), - Body: LogValueToPB(l.Body()), - Attributes: attrs, - // DroppedAttributesCount: 0, - // Flags: 0, - TraceId: tid[:], - SpanId: sid[:], - } - - return s -} - -// ResourceToPB transforms a Resource into an OTLP Resource. -func ResourceToPB(r resource.Resource) *otlpresourcev1.Resource { - return &otlpresourcev1.Resource{Attributes: resourceAttributes(r)} -} - -// ResourceFromPB creates a *resource.Resource from a schema URL and -// protobuf encoded attributes. -func ResourceFromPB(schemaURL string, pb *otlpresourcev1.Resource) *resource.Resource { - if schemaURL == "" { - return resource.NewSchemaless(AttributesFromProto(pb.Attributes)...) - } - return resource.NewWithAttributes(schemaURL, AttributesFromProto(pb.Attributes)...) -} - -// ResourcePtrToPB transforms a *Resource into an OTLP Resource. -func ResourcePtrToPB(r *resource.Resource) *otlpresourcev1.Resource { - if r == nil { - return nil - } - return &otlpresourcev1.Resource{Attributes: resourceAttributes(*r)} -} - -func resourceAttributes(res resource.Resource) []*otlpcommonv1.KeyValue { - return iterator(res.Iter()) -} - -func iterator(iter attribute.Iterator) []*otlpcommonv1.KeyValue { - l := iter.Len() - if l == 0 { - return nil - } - - out := make([]*otlpcommonv1.KeyValue, 0, l) - for iter.Next() { - out = append(out, keyValueToPB(iter.Attribute())) - } - return out -} - -func keyValueToPB(kv attribute.KeyValue) *otlpcommonv1.KeyValue { - return &otlpcommonv1.KeyValue{Key: string(kv.Key), Value: value(kv.Value)} -} - -// value transforms an attribute value into an OTLP AnyValue. -func value(v attribute.Value) *otlpcommonv1.AnyValue { - av := new(otlpcommonv1.AnyValue) - switch v.Type() { - case attribute.BOOL: - av.Value = &otlpcommonv1.AnyValue_BoolValue{ - BoolValue: v.AsBool(), - } - case attribute.BOOLSLICE: - av.Value = &otlpcommonv1.AnyValue_ArrayValue{ - ArrayValue: &otlpcommonv1.ArrayValue{ - Values: boolSliceValues(v.AsBoolSlice()), - }, - } - case attribute.INT64: - av.Value = &otlpcommonv1.AnyValue_IntValue{ - IntValue: v.AsInt64(), - } - case attribute.INT64SLICE: - av.Value = &otlpcommonv1.AnyValue_ArrayValue{ - ArrayValue: &otlpcommonv1.ArrayValue{ - Values: int64SliceValues(v.AsInt64Slice()), - }, - } - case attribute.FLOAT64: - av.Value = &otlpcommonv1.AnyValue_DoubleValue{ - DoubleValue: v.AsFloat64(), - } - case attribute.FLOAT64SLICE: - av.Value = &otlpcommonv1.AnyValue_ArrayValue{ - ArrayValue: &otlpcommonv1.ArrayValue{ - Values: float64SliceValues(v.AsFloat64Slice()), - }, - } - case attribute.STRING: - av.Value = &otlpcommonv1.AnyValue_StringValue{ - StringValue: v.AsString(), - } - case attribute.STRINGSLICE: - av.Value = &otlpcommonv1.AnyValue_ArrayValue{ - ArrayValue: &otlpcommonv1.ArrayValue{ - Values: stringSliceValues(v.AsStringSlice()), - }, - } - default: - av.Value = &otlpcommonv1.AnyValue_StringValue{ - StringValue: "INVALID", - } - } - return av -} - -func boolSliceValues(vals []bool) []*otlpcommonv1.AnyValue { - converted := make([]*otlpcommonv1.AnyValue, len(vals)) - for i, v := range vals { - converted[i] = &otlpcommonv1.AnyValue{ - Value: &otlpcommonv1.AnyValue_BoolValue{ - BoolValue: v, - }, - } - } - return converted -} - -func int64SliceValues(vals []int64) []*otlpcommonv1.AnyValue { - converted := make([]*otlpcommonv1.AnyValue, len(vals)) - for i, v := range vals { - converted[i] = &otlpcommonv1.AnyValue{ - Value: &otlpcommonv1.AnyValue_IntValue{ - IntValue: v, - }, - } - } - return converted -} - -func float64SliceValues(vals []float64) []*otlpcommonv1.AnyValue { - converted := make([]*otlpcommonv1.AnyValue, len(vals)) - for i, v := range vals { - converted[i] = &otlpcommonv1.AnyValue{ - Value: &otlpcommonv1.AnyValue_DoubleValue{ - DoubleValue: v, - }, - } - } - return converted -} - -func stringSliceValues(vals []string) []*otlpcommonv1.AnyValue { - converted := make([]*otlpcommonv1.AnyValue, len(vals)) - for i, v := range vals { - converted[i] = &otlpcommonv1.AnyValue{ - Value: &otlpcommonv1.AnyValue_StringValue{ - StringValue: v, - }, - } - } - return converted -} - -// SpansFromPB transforms a slice of OTLP ResourceSpans into a slice of -// ReadOnlySpans. -func SpansFromPB(sdl []*otlptracev1.ResourceSpans) []sdktrace.ReadOnlySpan { - if len(sdl) == 0 { - return nil - } - - var out []sdktrace.ReadOnlySpan - - for _, sd := range sdl { - if sd == nil { - continue - } - - for _, sdi := range sd.ScopeSpans { - if sdi == nil { - continue - } - sda := make([]sdktrace.ReadOnlySpan, 0, len(sdi.Spans)) - for _, s := range sdi.Spans { - if s == nil { - continue - } - sda = append(sda, &readOnlySpan{ - pb: s, - is: sdi.Scope, - resource: sd.Resource, - schemaURL: sd.SchemaUrl, - }) - } - out = append(out, sda...) - } - } - - return out -} - -// SpansToPB transforms a slice of OpenTelemetry spans into a slice of OTLP -// ResourceSpans. -func SpansToPB(sdl []sdktrace.ReadOnlySpan) []*otlptracev1.ResourceSpans { - if len(sdl) == 0 { - return nil - } - - rsm := make(map[attribute.Distinct]*otlptracev1.ResourceSpans) - - type key struct { - r attribute.Distinct - is instrumentation.Scope - } - ssm := make(map[key]*otlptracev1.ScopeSpans) - - var resources int - for _, sd := range sdl { - if sd == nil { - continue - } - - rKey := sd.Resource().Equivalent() - k := key{ - r: rKey, - is: sd.InstrumentationScope(), - } - scopeSpan, iOk := ssm[k] - if !iOk { - // Either the resource or instrumentation scope were unknown. - scopeSpan = &otlptracev1.ScopeSpans{ - Scope: InstrumentationScopeToPB(sd.InstrumentationScope()), - Spans: []*otlptracev1.Span{}, - SchemaUrl: sd.InstrumentationScope().SchemaURL, - } - } - scopeSpan.Spans = append(scopeSpan.Spans, spanToPB(sd)) - ssm[k] = scopeSpan - - rs, rOk := rsm[rKey] - if !rOk { - resources++ - // The resource was unknown. - rs = &otlptracev1.ResourceSpans{ - Resource: ResourcePtrToPB(sd.Resource()), - ScopeSpans: []*otlptracev1.ScopeSpans{scopeSpan}, - SchemaUrl: sd.Resource().SchemaURL(), - } - rsm[rKey] = rs - continue - } - - // The resource has been seen before. Check if the instrumentation - // library lookup was unknown because if so we need to add it to the - // ResourceSpans. Otherwise, the instrumentation library has already - // been seen and the append we did above will be included it in the - // ScopeSpans reference. - if !iOk { - rs.ScopeSpans = append(rs.ScopeSpans, scopeSpan) - } - } - - // Transform the categorized map into a slice - rss := make([]*otlptracev1.ResourceSpans, 0, resources) - for _, rs := range rsm { - rss = append(rss, rs) - } - return rss -} - -// spanToPB transforms a Span into an OTLP span. -func spanToPB(sd sdktrace.ReadOnlySpan) *otlptracev1.Span { - if sd == nil { - return nil - } - - tid := sd.SpanContext().TraceID() - sid := sd.SpanContext().SpanID() - - s := &otlptracev1.Span{ - TraceId: tid[:], - SpanId: sid[:], - TraceState: sd.SpanContext().TraceState().String(), - Status: status(sd.Status().Code, sd.Status().Description), - StartTimeUnixNano: uint64(sd.StartTime().UnixNano()), - EndTimeUnixNano: uint64(sd.EndTime().UnixNano()), - Links: SpanLinksToPB(sd.Links()), - Kind: spanKindToPB(sd.SpanKind()), - Name: sd.Name(), - Attributes: KeyValues(sd.Attributes()), - Events: SpanEventsToPB(sd.Events()), - DroppedAttributesCount: uint32(sd.DroppedAttributes()), - DroppedEventsCount: uint32(sd.DroppedEvents()), - DroppedLinksCount: uint32(sd.DroppedLinks()), - } - - if psid := sd.Parent().SpanID(); psid.IsValid() { - s.ParentSpanId = psid[:] - } - s.Flags = buildSpanFlags(sd.Parent()) - - return s -} - -// status transform a span code and message into an OTLP span status. -func status(status codes.Code, message string) *otlptracev1.Status { - var c otlptracev1.Status_StatusCode - switch status { - case codes.Ok: - c = otlptracev1.Status_STATUS_CODE_OK - case codes.Error: - c = otlptracev1.Status_STATUS_CODE_ERROR - default: - c = otlptracev1.Status_STATUS_CODE_UNSET - } - return &otlptracev1.Status{ - Code: c, - Message: message, - } -} - -// KeyValues transforms a slice of attribute KeyValues into OTLP key-values. -func KeyValues(attrs []attribute.KeyValue) []*otlpcommonv1.KeyValue { - if len(attrs) == 0 { - return nil - } - - out := make([]*otlpcommonv1.KeyValue, 0, len(attrs)) - for _, kv := range attrs { - out = append(out, keyValueToPB(kv)) - } - return out -} - -// linksFromPB transforms span Links to OTLP span linksFromPB. -func SpanLinksToPB(links []sdktrace.Link) []*otlptracev1.Span_Link { - if len(links) == 0 { - return nil - } - - sl := make([]*otlptracev1.Span_Link, 0, len(links)) - for _, otLink := range links { - // This redefinition is necessary to prevent otLink.*ID[:] copies - // being reused -- in short we need a new otLink per iteration. - otLink := otLink - - tid := otLink.SpanContext.TraceID() - sid := otLink.SpanContext.SpanID() - - flags := buildSpanFlags(otLink.SpanContext) - - sl = append(sl, &otlptracev1.Span_Link{ - TraceId: tid[:], - SpanId: sid[:], - Attributes: KeyValues(otLink.Attributes), - DroppedAttributesCount: uint32(otLink.DroppedAttributeCount), - Flags: flags, - }) - } - return sl -} - -func buildSpanFlags(sc trace.SpanContext) uint32 { - flags := otlptracev1.SpanFlags_SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK - if sc.IsRemote() { - flags |= otlptracev1.SpanFlags_SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK - } - - return uint32(flags) -} - -// SpanEventsToPB transforms span Events to an OTLP span events. -func SpanEventsToPB(es []sdktrace.Event) []*otlptracev1.Span_Event { - if len(es) == 0 { - return nil - } - - events := make([]*otlptracev1.Span_Event, len(es)) - // Transform message events - for i := 0; i < len(es); i++ { - events[i] = &otlptracev1.Span_Event{ - Name: es[i].Name, - TimeUnixNano: uint64(es[i].Time.UnixNano()), - Attributes: KeyValues(es[i].Attributes), - DroppedAttributesCount: uint32(es[i].DroppedAttributeCount), - } - } - return events -} - -// spanKindToPB transforms a SpanKind to an OTLP span kind. -func spanKindToPB(kind trace.SpanKind) otlptracev1.Span_SpanKind { - switch kind { - case trace.SpanKindInternal: - return otlptracev1.Span_SPAN_KIND_INTERNAL - case trace.SpanKindClient: - return otlptracev1.Span_SPAN_KIND_CLIENT - case trace.SpanKindServer: - return otlptracev1.Span_SPAN_KIND_SERVER - case trace.SpanKindProducer: - return otlptracev1.Span_SPAN_KIND_PRODUCER - case trace.SpanKindConsumer: - return otlptracev1.Span_SPAN_KIND_CONSUMER - default: - return otlptracev1.Span_SPAN_KIND_UNSPECIFIED - } -} - -type readOnlySpan struct { - // Embed the interface to implement the private method. - sdktrace.ReadOnlySpan - - pb *otlptracev1.Span - is *otlpcommonv1.InstrumentationScope - resource *otlpresourcev1.Resource - schemaURL string -} - -func (s *readOnlySpan) Name() string { - return s.pb.Name -} - -func (s *readOnlySpan) SpanContext() trace.SpanContext { - var tid trace.TraceID - copy(tid[:], s.pb.TraceId) - var sid trace.SpanID - copy(sid[:], s.pb.SpanId) - - st, _ := trace.ParseTraceState(s.pb.TraceState) - - return trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - TraceState: st, - TraceFlags: trace.FlagsSampled, - }) -} - -func (s *readOnlySpan) Parent() trace.SpanContext { - if len(s.pb.ParentSpanId) == 0 { - return trace.SpanContext{} - } - var tid trace.TraceID - copy(tid[:], s.pb.TraceId) - var psid trace.SpanID - copy(psid[:], s.pb.ParentSpanId) - return trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: psid, - }) -} - -func (s *readOnlySpan) SpanKind() trace.SpanKind { - return spanKindFromPB(s.pb.Kind) -} - -func (s *readOnlySpan) StartTime() time.Time { - return time.Unix(0, int64(s.pb.StartTimeUnixNano)) -} - -func (s *readOnlySpan) EndTime() time.Time { - return time.Unix(0, int64(s.pb.EndTimeUnixNano)) -} - -func (s *readOnlySpan) Attributes() []attribute.KeyValue { - return AttributesFromProto(s.pb.Attributes) -} - -func (s *readOnlySpan) Links() []sdktrace.Link { - return SpanLinksFromPB(s.pb.Links) -} - -func (s *readOnlySpan) Events() []sdktrace.Event { - return SpanEventsFromPB(s.pb.Events) -} - -func (s *readOnlySpan) Status() sdktrace.Status { - return sdktrace.Status{ - Code: StatusCodeFromPB(s.pb.Status), - Description: s.pb.Status.GetMessage(), - } -} - -func (s *readOnlySpan) InstrumentationScope() instrumentation.Scope { - return InstrumentationScopeFromPB(s.is) -} - -// Deprecated: use InstrumentationScope. -func (s *readOnlySpan) InstrumentationLibrary() instrumentation.Library { - return s.InstrumentationScope() -} - -// Resource returns information about the entity that produced the span. -func (s *readOnlySpan) Resource() *resource.Resource { - return ResourceFromPB(s.schemaURL, s.resource) -} - -// DroppedAttributes returns the number of attributes dropped by the span -// due to limits being reached. -func (s *readOnlySpan) DroppedAttributes() int { - return int(s.pb.DroppedAttributesCount) -} - -// DroppedLinks returns the number of links dropped by the span due to -// limits being reached. -func (s *readOnlySpan) DroppedLinks() int { - return int(s.pb.DroppedLinksCount) -} - -// DroppedEvents returns the number of events dropped by the span due to -// limits being reached. -func (s *readOnlySpan) DroppedEvents() int { - return int(s.pb.DroppedEventsCount) -} - -// ChildSpanCount returns the count of spans that consider the span a -// direct parent. -func (s *readOnlySpan) ChildSpanCount() int { - return 0 -} - -var _ sdktrace.ReadOnlySpan = &readOnlySpan{} - -// status transform a OTLP span status into span code. -func StatusCodeFromPB(st *otlptracev1.Status) codes.Code { - if st == nil { - return codes.Unset - } - switch st.Code { - case otlptracev1.Status_STATUS_CODE_ERROR: - return codes.Error - default: - return codes.Ok - } -} - -// SpanLinksFromPB transforms OTLP span links to span Links. -func SpanLinksFromPB(links []*otlptracev1.Span_Link) []sdktrace.Link { - if len(links) == 0 { - return nil - } - - sl := make([]sdktrace.Link, 0, len(links)) - for _, otLink := range links { - if otLink == nil { - continue - } - // This redefinition is necessary to prevent otLink.*ID[:] copies - // being reused -- in short we need a new otLink per iteration. - otLink := otLink - - var tid trace.TraceID - copy(tid[:], otLink.TraceId) - var sid trace.SpanID - copy(sid[:], otLink.SpanId) - - sctx := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - }) - - sl = append(sl, sdktrace.Link{ - SpanContext: sctx, - Attributes: AttributesFromProto(otLink.Attributes), - }) - } - return sl -} - -// SpanEventsFromPB transforms OTLP span events to span Events. -func SpanEventsFromPB(es []*otlptracev1.Span_Event) []sdktrace.Event { - if len(es) == 0 { - return nil - } - - evCount := len(es) - events := make([]sdktrace.Event, 0, evCount) - messageEvents := 0 - - // Transform message events - for _, e := range es { - if e == nil { - continue - } - messageEvents++ - events = append(events, - sdktrace.Event{ - Name: e.Name, - Time: time.Unix(0, int64(e.TimeUnixNano)), - Attributes: AttributesFromProto(e.Attributes), - DroppedAttributeCount: int(e.DroppedAttributesCount), - }, - ) - } - - return events -} - -// spanKindFromPB transforms a an OTLP span kind to SpanKind. -func spanKindFromPB(kind otlptracev1.Span_SpanKind) trace.SpanKind { - switch kind { - case otlptracev1.Span_SPAN_KIND_INTERNAL: - return trace.SpanKindInternal - case otlptracev1.Span_SPAN_KIND_CLIENT: - return trace.SpanKindClient - case otlptracev1.Span_SPAN_KIND_SERVER: - return trace.SpanKindServer - case otlptracev1.Span_SPAN_KIND_PRODUCER: - return trace.SpanKindProducer - case otlptracev1.Span_SPAN_KIND_CONSUMER: - return trace.SpanKindConsumer - default: - return trace.SpanKindUnspecified - } -} - -// AttributesFromProto transforms a slice of OTLP attribute key-values into a slice of KeyValues -func AttributesFromProto(attrs []*otlpcommonv1.KeyValue) []attribute.KeyValue { - if len(attrs) == 0 { - return nil - } - - out := make([]attribute.KeyValue, 0, len(attrs)) - for _, a := range attrs { - if a == nil { - continue - } - kv := attribute.KeyValue{ - Key: attribute.Key(a.Key), - Value: attrValue(a.Value), - } - out = append(out, kv) - } - return out -} - -func boolArray(kv []*otlpcommonv1.AnyValue) attribute.Value { - arr := make([]bool, len(kv)) - for i, v := range kv { - if v != nil { - arr[i] = v.GetBoolValue() - } - } - return attribute.BoolSliceValue(arr) -} - -func intArray(kv []*otlpcommonv1.AnyValue) attribute.Value { - arr := make([]int64, len(kv)) - for i, v := range kv { - if v != nil { - arr[i] = v.GetIntValue() - } - } - return attribute.Int64SliceValue(arr) -} - -func doubleArray(kv []*otlpcommonv1.AnyValue) attribute.Value { - arr := make([]float64, len(kv)) - for i, v := range kv { - if v != nil { - arr[i] = v.GetDoubleValue() - } - } - return attribute.Float64SliceValue(arr) -} - -func stringArray(kv []*otlpcommonv1.AnyValue) attribute.Value { - arr := make([]string, len(kv)) - for i, v := range kv { - if v != nil { - arr[i] = v.GetStringValue() - } - } - return attribute.StringSliceValue(arr) -} - -func anyArrayToAttrValue(anyVals []*otlpcommonv1.AnyValue) attribute.Value { - vals := make([]attribute.Value, 0, len(anyVals)) - types := map[attribute.Type]int{} - for _, v := range anyVals { - val := attrValue(v) - types[val.Type()]++ - vals = append(vals, val) - } - - var arrType attribute.Type - switch len(types) { - case 0: - // empty; assume string slice - return attribute.StringSliceValue(nil) - case 1: - for arrType = range types { - } - default: - slog.Error("anyArrayToAttrValue: mixed types in Any array", - "types", fmt.Sprintf("%v", types)) - return attribute.StringValue(fmt.Sprintf("%v", vals)) - } - - switch arrType { - case attribute.STRING: - return stringArray(anyVals) - case attribute.INT64: - return intArray(anyVals) - case attribute.FLOAT64: - return doubleArray(anyVals) - case attribute.BOOL: - return boolArray(anyVals) - default: - slog.Error("anyArrayToAttrValue: unhandled array value type conversion", "type", arrType) - return attribute.StringValue(fmt.Sprintf("UNHANDLED ARRAY ELEM TYPE: %+v (%s)", vals, arrType)) - } -} - -func InstrumentationScopeFromPB(is *otlpcommonv1.InstrumentationScope) instrumentation.Scope { - if is == nil { - return instrumentation.Scope{} - } - return instrumentation.Scope{ - Name: is.Name, - Version: is.Version, - } -} - -func LogsFromPB(resLogs []*otlplogsv1.ResourceLogs) []sdklog.Record { - logs := []sdklog.Record{} - for _, rl := range resLogs { - for _, scopeLog := range rl.GetScopeLogs() { - for _, rec := range scopeLog.GetLogRecords() { - var logRec sdklog.Record - logRec.SetTraceID(trace.TraceID(rec.GetTraceId())) - logRec.SetSpanID(trace.SpanID(rec.GetSpanId())) - logRec.SetTimestamp(time.Unix(0, int64(rec.GetTimeUnixNano()))) - logRec.SetBody(LogValueFromPB(rec.GetBody())) - logRec.SetSeverity(log.Severity(rec.GetSeverityNumber())) - logRec.SetSeverityText(rec.GetSeverityText()) - logRec.SetObservedTimestamp(time.Unix(0, int64(rec.GetObservedTimeUnixNano()))) - logRec.SetAttributes(LogKeyValuesFromPB(rec.GetAttributes())...) - logs = append(logs, logRec) - } - } - } - return logs -} - -func LogKeyValuesFromPB(kvs []*otlpcommonv1.KeyValue) []log.KeyValue { - res := make([]log.KeyValue, len(kvs)) - for i, kv := range kvs { - res[i] = logKeyValue(kv) - } - return res -} - -func logKeyValue(v *otlpcommonv1.KeyValue) log.KeyValue { - return log.KeyValue{ - Key: v.GetKey(), - Value: LogValueFromPB(v.GetValue()), - } -} - -func attrValue(v *otlpcommonv1.AnyValue) attribute.Value { - switch x := v.Value.(type) { - case *otlpcommonv1.AnyValue_StringValue: - return attribute.StringValue(v.GetStringValue()) - case *otlpcommonv1.AnyValue_DoubleValue: - return attribute.Float64Value(v.GetDoubleValue()) - case *otlpcommonv1.AnyValue_IntValue: - return attribute.Int64Value(v.GetIntValue()) - case *otlpcommonv1.AnyValue_BoolValue: - return attribute.BoolValue(v.GetBoolValue()) - case *otlpcommonv1.AnyValue_ArrayValue: - return anyArrayToAttrValue(x.ArrayValue.GetValues()) - case *otlpcommonv1.AnyValue_BytesValue: - return attribute.StringValue(string(x.BytesValue)) - default: - slog.Error("otlpcommonv1.AnyValue -> attribute.Value: unhandled type conversion", "type", fmt.Sprintf("%T", x)) - return attribute.StringValue(fmt.Sprintf("UNHANDLED ATTR TYPE: %v (%T)", x, x)) - } -} - -func LogValueFromPB(v *otlpcommonv1.AnyValue) log.Value { - switch x := v.Value.(type) { - case *otlpcommonv1.AnyValue_StringValue: - return log.StringValue(v.GetStringValue()) - case *otlpcommonv1.AnyValue_DoubleValue: - return log.Float64Value(v.GetDoubleValue()) - case *otlpcommonv1.AnyValue_IntValue: - return log.Int64Value(v.GetIntValue()) - case *otlpcommonv1.AnyValue_BoolValue: - return log.BoolValue(v.GetBoolValue()) - case *otlpcommonv1.AnyValue_KvlistValue: - kvs := make([]log.KeyValue, 0, len(x.KvlistValue.GetValues())) - for _, kv := range x.KvlistValue.GetValues() { - kvs = append(kvs, logKeyValue(kv)) - } - return log.MapValue(kvs...) - case *otlpcommonv1.AnyValue_ArrayValue: - vals := make([]log.Value, 0, len(x.ArrayValue.GetValues())) - for _, v := range x.ArrayValue.GetValues() { - vals = append(vals, LogValueFromPB(v)) - } - return log.SliceValue(vals...) - case *otlpcommonv1.AnyValue_BytesValue: - return log.BytesValue(x.BytesValue) - default: - slog.Error("unhandled otlpcommonv1.AnyValue -> log.Value conversion", "type", fmt.Sprintf("%T", x)) - return log.StringValue(fmt.Sprintf("UNHANDLED LOG VALUE TYPE: %v (%T)", x, x)) - } -} - -// Value transforms an attribute Value into an OTLP AnyValue. -func LogValueToPB(v log.Value) *otlpcommonv1.AnyValue { - av := new(otlpcommonv1.AnyValue) - switch v.Kind() { - case log.KindBool: - av.Value = &otlpcommonv1.AnyValue_BoolValue{ - BoolValue: v.AsBool(), - } - case log.KindInt64: - av.Value = &otlpcommonv1.AnyValue_IntValue{ - IntValue: v.AsInt64(), - } - case log.KindFloat64: - av.Value = &otlpcommonv1.AnyValue_DoubleValue{ - DoubleValue: v.AsFloat64(), - } - case log.KindString: - av.Value = &otlpcommonv1.AnyValue_StringValue{ - StringValue: v.AsString(), - } - case log.KindSlice: - array := &otlpcommonv1.ArrayValue{} - for _, e := range v.AsSlice() { - array.Values = append(array.Values, LogValueToPB(e)) - } - av.Value = &otlpcommonv1.AnyValue_ArrayValue{ - ArrayValue: array, - } - case log.KindMap: - kvList := &otlpcommonv1.KeyValueList{} - for _, e := range v.AsMap() { - kvList.Values = append(kvList.Values, &otlpcommonv1.KeyValue{ - Key: e.Key, - Value: LogValueToPB(e.Value), - }) - } - av.Value = &otlpcommonv1.AnyValue_KvlistValue{ - KvlistValue: kvList, - } - default: - av.Value = &otlpcommonv1.AnyValue_StringValue{ - StringValue: "INVALID", - } - } - return av -} diff --git a/main.go b/main.go deleted file mode 100644 index 1a8a7677..00000000 --- a/main.go +++ /dev/null @@ -1,133 +0,0 @@ -package main - -import ( - "context" - "fmt" - "github.com/goharbor/harbor-cli/internal/dagger" - "log" -) - -const ( - GO_VERSION = "1.22.5" - SYFT_VERSION = "v1.9.0" - GORELEASER_VERSION = "v2.1.0" - APP_NAME = "dagger-harbor-cli" - PUBLISH_ADDRESS = "demo.goharbor.io/library/harbor-cli:0.0.3" -) - -type HarborCli struct{} - -func (m *HarborCli) Build( - ctx context.Context, - // +optional - // +defaultPath="./" - source *dagger.Directory) *dagger.Directory { - - fmt.Println("🛠️ Building with Dagger...") - oses := []string{"linux", "darwin", "windows"} - arches := []string{"amd64", "arm64"} - outputs := dag.Directory() - for _, goos := range oses { - for _, goarch := range arches { - bin_path := fmt.Sprintf("build/%s/%s/", goos, goarch) - builder := dag.Container(). - From("golang:"+GO_VERSION+"-alpine"). - WithMountedDirectory("/src", source). - WithWorkdir("/src"). - WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). - WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). - WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). - WithEnvVariable("GOCACHE", "/go/build-cache"). - WithEnvVariable("GOOS", goos). - WithEnvVariable("GOARCH", goarch). - WithExec([]string{"go", "build", "-o", bin_path + "harbor", "/src/cmd/harbor/main.go"}) - // Get reference to build output directory in container - outputs = outputs.WithDirectory(bin_path, builder.Directory(bin_path)) - } - } - return outputs -} - -func (m *HarborCli) Lint( - ctx context.Context, - // +optional - // +defaultPath="./" - source *dagger.Directory, -) *dagger.Container { - fmt.Println("👀 Running linter with Dagger...") - return dag.Container(). - From("golangci/golangci-lint:v1.59.1-alpine"). - WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). - WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). - WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). - WithEnvVariable("GOCACHE", "/go/build-cache"). - WithMountedDirectory("/src", source). - WithWorkdir("/src"). - WithExec([]string{"golangci-lint", "run", "--timeout", "5m"}) - -} - -func (m *HarborCli) PullRequest(ctx context.Context, directoryArg *dagger.Directory, githubToken string) { - goreleaser := goreleaserContainer(directoryArg, githubToken).WithExec([]string{"release", "--snapshot", "--clean"}) - _, err := goreleaser.Stderr(ctx) - if err != nil { - log.Printf("❌ Error occured during snapshot release for the recently merged pull-request: %s", err) - return - } - log.Println("Pull-Request tasks completed successfully 🎉") -} - -func (m *HarborCli) Release(ctx context.Context, directoryArg *dagger.Directory, githubToken string) { - goreleaser := goreleaserContainer(directoryArg, githubToken).WithExec([]string{"release", "--clean"}) - _, err := goreleaser.Stderr(ctx) - if err != nil { - log.Printf("Error occured during release: %s", err) - return - } - log.Println("Release tasks completed successfully 🎉") -} - -func (m *HarborCli) PublishImage( - ctx context.Context, - // +optional - // +defaultPath="./" - source *dagger.Directory, - cosignKey *dagger.Secret, - cosignPassword string, - regUsername string, - regPassword string, -) string { - - builder := m.Build(ctx, source) - // Create a minimal cli_runtime container - cli_runtime := dag.Container(). - From("alpine:latest"). - WithWorkdir("/root/"). - WithFile("/root/harbor", builder.File("/")). - WithEntrypoint([]string{"./harbor"}) - - addr, _ := cli_runtime.Publish(ctx, PUBLISH_ADDRESS) - cosign_password := dag.SetSecret("cosign_password", cosignPassword) - regpassword := dag.SetSecret("reg_password", regPassword) - _, err := dag.Cosign().Sign(ctx, cosignKey, cosign_password, []string{addr}, dagger.CosignSignOpts{RegistryUsername: regUsername, RegistryPassword: regpassword}) - if err != nil { - panic(err) - } - fmt.Printf("Published to %s 🎉\n", addr) - return addr -} - -func goreleaserContainer(directoryArg *dagger.Directory, githubToken string) *dagger.Container { - token := dag.SetSecret("github_token", githubToken) - - // Export the syft binary from the syft container as a file to generate SBOM - syft := dag.Container().From(fmt.Sprintf("anchore/syft:%s", SYFT_VERSION)). - WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). - File("/syft") - return dag.Container().From(fmt.Sprintf("goreleaser/goreleaser:%s", GORELEASER_VERSION)). - WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). - WithFile("/bin/syft", syft). - WithMountedDirectory("/src", directoryArg).WithWorkdir("/src"). - WithEnvVariable("TINI_SUBREAPER", "true"). - WithSecretVariable("GITHUB_TOKEN", token) -} From d311555016c244fc794754e0f353e2792eada0b9 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Fri, 4 Oct 2024 21:44:39 -0400 Subject: [PATCH 14/21] reestablish existing functions; add cosign plugin Signed-off-by: Tyler Auerbeck --- dagger.json | 6 ++ dagger/main.go | 145 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 127 insertions(+), 24 deletions(-) diff --git a/dagger.json b/dagger.json index ae93ae20..584417de 100644 --- a/dagger.json +++ b/dagger.json @@ -1,6 +1,12 @@ { "name": "harbor-cli", "sdk": "go", + "dependencies": [ + { + "name": "cosign", + "source": "github.com/scottames/daggerverse/cosign@8359122a7b90f2c8c6f3165570fdcbec6e923023" + } + ], "source": "dagger", "engineVersion": "v0.13.3" } diff --git a/dagger/main.go b/dagger/main.go index 82de09e9..a6b89f63 100644 --- a/dagger/main.go +++ b/dagger/main.go @@ -1,37 +1,134 @@ -// A generated module for HarborCli functions -// -// This module has been generated via dagger init and serves as a reference to -// basic module structure as you get started with Dagger. -// -// Two functions have been pre-created. You can modify, delete, or add to them, -// as needed. They demonstrate usage of arguments and return types using simple -// echo and grep commands. The functions can be called from the dagger CLI or -// from one of the SDKs. -// -// The first line in this comment block is a short description line and the -// rest is a long description with more detail on the module's purpose or usage, -// if appropriate. All modules should have a short description. - package main import ( "context" - "dagger/harbor-cli/internal/dagger" + "fmt" + "log" + "dagger/harbor-cli/internal/dagger" + +) + +const ( + GO_VERSION = "1.22.5" + SYFT_VERSION = "v1.9.0" + GORELEASER_VERSION = "v2.1.0" + APP_NAME = "dagger-harbor-cli" + PUBLISH_ADDRESS = "demo.goharbor.io/library/harbor-cli:0.0.3" ) type HarborCli struct{} -// Returns a container that echoes whatever string argument is provided -func (m *HarborCli) ContainerEcho(stringArg string) *dagger.Container { - return dag.Container().From("alpine:latest").WithExec([]string{"echo", stringArg}) +func (m *HarborCli) Build( + ctx context.Context, + // +optional + // +defaultPath="./" + source *dagger.Directory) *dagger.Directory { + + fmt.Println("🛠️ Building with Dagger...") + oses := []string{"linux", "darwin", "windows"} + arches := []string{"amd64", "arm64"} + outputs := dag.Directory() + for _, goos := range oses { + for _, goarch := range arches { + bin_path := fmt.Sprintf("build/%s/%s/", goos, goarch) + builder := dag.Container(). + From("golang:"+GO_VERSION+"-alpine"). + WithMountedDirectory("/src", source). + WithWorkdir("/src"). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). + WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). + WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). + WithEnvVariable("GOCACHE", "/go/build-cache"). + WithEnvVariable("GOOS", goos). + WithEnvVariable("GOARCH", goarch). + WithExec([]string{"go", "build", "-o", bin_path + "harbor", "/src/cmd/harbor/main.go"}) + // Get reference to build output directory in container + outputs = outputs.WithDirectory(bin_path, builder.Directory(bin_path)) + } + } + return outputs } -// Returns lines that match a pattern in the files of the provided Directory -func (m *HarborCli) GrepDir(ctx context.Context, directoryArg *dagger.Directory, pattern string) (string, error) { +func (m *HarborCli) Lint( + ctx context.Context, + // +optional + // +defaultPath="./" + source *dagger.Directory, +) *dagger.Container { + fmt.Println("👀 Running linter with Dagger...") return dag.Container(). + From("golangci/golangci-lint:v1.59.1-alpine"). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). + WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). + WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). + WithEnvVariable("GOCACHE", "/go/build-cache"). + WithMountedDirectory("/src", source). + WithWorkdir("/src"). + WithExec([]string{"golangci-lint", "run", "--timeout", "5m"}) + +} + +func (m *HarborCli) PullRequest(ctx context.Context, directoryArg *dagger.Directory, githubToken string) { + goreleaser := goreleaserContainer(directoryArg, githubToken).WithExec([]string{"release", "--snapshot", "--clean"}) + _, err := goreleaser.Stderr(ctx) + if err != nil { + log.Printf("❌ Error occured during snapshot release for the recently merged pull-request: %s", err) + return + } + log.Println("Pull-Request tasks completed successfully 🎉") +} + +func (m *HarborCli) Release(ctx context.Context, directoryArg *dagger.Directory, githubToken string) { + goreleaser := goreleaserContainer(directoryArg, githubToken).WithExec([]string{"release", "--clean"}) + _, err := goreleaser.Stderr(ctx) + if err != nil { + log.Printf("Error occured during release: %s", err) + return + } + log.Println("Release tasks completed successfully 🎉") +} + +func (m *HarborCli) PublishImage( + ctx context.Context, + // +optional + // +defaultPath="./" + source *dagger.Directory, + cosignKey *dagger.Secret, + cosignPassword string, + regUsername string, + regPassword string, +) string { + + builder := m.Build(ctx, source) + // Create a minimal cli_runtime container + cli_runtime := dag.Container(). From("alpine:latest"). - WithMountedDirectory("/mnt", directoryArg). - WithWorkdir("/mnt"). - WithExec([]string{"grep", "-R", pattern, "."}). - Stdout(ctx) + WithWorkdir("/root/"). + WithFile("/root/harbor", builder.File("/")). + WithEntrypoint([]string{"./harbor"}) + + addr, _ := cli_runtime.Publish(ctx, PUBLISH_ADDRESS) + cosign_password := dag.SetSecret("cosign_password", cosignPassword) + regpassword := dag.SetSecret("reg_password", regPassword) + _, err := dag.Cosign().Sign(ctx, cosignKey, cosign_password, []string{addr}, dagger.CosignSignOpts{RegistryUsername: regUsername, RegistryPassword: regpassword}) + if err != nil { + panic(err) + } + fmt.Printf("Published to %s 🎉\n", addr) + return addr +} + +func goreleaserContainer(directoryArg *dagger.Directory, githubToken string) *dagger.Container { + token := dag.SetSecret("github_token", githubToken) + + // Export the syft binary from the syft container as a file to generate SBOM + syft := dag.Container().From(fmt.Sprintf("anchore/syft:%s", SYFT_VERSION)). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). + File("/syft") + return dag.Container().From(fmt.Sprintf("goreleaser/goreleaser:%s", GORELEASER_VERSION)). + WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). + WithFile("/bin/syft", syft). + WithMountedDirectory("/src", directoryArg).WithWorkdir("/src"). + WithEnvVariable("TINI_SUBREAPER", "true"). + WithSecretVariable("GITHUB_TOKEN", token) } From 3ea1c258edcb3c41a5d7f5531b9a58a462335d06 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Thu, 10 Oct 2024 16:13:53 -0400 Subject: [PATCH 15/21] Bump golangci-lint to latest Signed-off-by: Tyler Auerbeck --- dagger/main.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dagger/main.go b/dagger/main.go index a6b89f63..8ac01ade 100644 --- a/dagger/main.go +++ b/dagger/main.go @@ -2,18 +2,18 @@ package main import ( "context" + "dagger/harbor-cli/internal/dagger" "fmt" "log" - "dagger/harbor-cli/internal/dagger" - ) const ( - GO_VERSION = "1.22.5" - SYFT_VERSION = "v1.9.0" - GORELEASER_VERSION = "v2.1.0" - APP_NAME = "dagger-harbor-cli" - PUBLISH_ADDRESS = "demo.goharbor.io/library/harbor-cli:0.0.3" + GOLANGCILINT_VERSION = "v1.61.0" + GO_VERSION = "1.22.5" + SYFT_VERSION = "v1.9.0" + GORELEASER_VERSION = "v2.1.0" + APP_NAME = "dagger-harbor-cli" + PUBLISH_ADDRESS = "demo.goharbor.io/library/harbor-cli:0.0.3" ) type HarborCli struct{} @@ -57,7 +57,7 @@ func (m *HarborCli) Lint( ) *dagger.Container { fmt.Println("👀 Running linter with Dagger...") return dag.Container(). - From("golangci/golangci-lint:v1.59.1-alpine"). + From("golangci/golangci-lint:"+GOLANGCILINT_VERSION+"-alpine"). WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). From 12316580a598c1a746fc6f387498bf4f56272e6c Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Mon, 14 Oct 2024 23:38:09 -0400 Subject: [PATCH 16/21] Trigger docker-publish workflow only on release or tag events Signed-off-by: Tyler Auerbeck --- .github/workflows/docker_publish.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker_publish.yml b/.github/workflows/docker_publish.yml index 6be0df9f..ffa3dedd 100644 --- a/.github/workflows/docker_publish.yml +++ b/.github/workflows/docker_publish.yml @@ -1,11 +1,11 @@ name: Docker Publish on: + release: + types: [published] push: - branches: [docker-publish] - pull_request: - paths-ignore: - - '*.md' + tags: + - "v*" jobs: docker-publish: From 097795afedb9f1bd3f692ac0859b23c5e5633184 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Mon, 14 Oct 2024 23:45:27 -0400 Subject: [PATCH 17/21] bumps core GHA dependencies Signed-off-by: Tyler Auerbeck --- .github/workflows/docker_publish.yml | 2 +- .github/workflows/publish_release.yml | 6 +++--- .github/workflows/pull-request.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker_publish.yml b/.github/workflows/docker_publish.yml index 6be0df9f..4e9bec30 100644 --- a/.github/workflows/docker_publish.yml +++ b/.github/workflows/docker_publish.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 38ea2e60..71a54903 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -16,11 +16,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.22.5" cache: true @@ -33,4 +33,4 @@ jobs: version: "latest" verb: call module: github.com/bishal7679/harbor-cli@v0.6.1 - args: release --directory-arg=. --github-token=${{ env.GITHUB_TOKEN }} \ No newline at end of file + args: release --directory-arg=. --github-token=${{ env.GITHUB_TOKEN }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 39dbed83..a5878522 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -18,12 +18,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.22.5" cache: true From 3fe21c67a63c9692c68092f38d873c25ce06c9c7 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Mon, 14 Oct 2024 23:49:12 -0400 Subject: [PATCH 18/21] use local dagger module in pull-request workflow Signed-off-by: Tyler Auerbeck --- .github/workflows/pull-request.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 39dbed83..637e6198 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -39,7 +39,6 @@ jobs: with: version: "latest" verb: call - module: github.com/bishal7679/harbor-cli@v0.6.1 args: lint-code --directory-arg=. - name: Call Pull-Request Function @@ -50,5 +49,4 @@ jobs: with: version: "latest" verb: call - module: github.com/bishal7679/harbor-cli@v0.6.1 args: pull-request --directory-arg=. --github-token=${{ env.GITHUB_TOKEN }} From b9db117d25540cd414c1c0c3af84eabe441c8d81 Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Tue, 15 Oct 2024 00:00:50 -0400 Subject: [PATCH 19/21] update lint action name Signed-off-by: Tyler Auerbeck --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 637e6198..a6fc6771 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -39,7 +39,7 @@ jobs: with: version: "latest" verb: call - args: lint-code --directory-arg=. + args: lint --directory-arg=. - name: Call Pull-Request Function uses: dagger/dagger-for-github@v6.1.0 From 4db4e38709e2fe9c1f13fe8df522d6438c319b5a Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Tue, 15 Oct 2024 00:05:52 -0400 Subject: [PATCH 20/21] fix parameter name for lint Signed-off-by: Tyler Auerbeck --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index a6fc6771..c35f7896 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -39,7 +39,7 @@ jobs: with: version: "latest" verb: call - args: lint --directory-arg=. + args: lint --source=. - name: Call Pull-Request Function uses: dagger/dagger-for-github@v6.1.0 From f04a029a1e432589652c68a6b12dfb04358758fd Mon Sep 17 00:00:00 2001 From: Tyler Auerbeck Date: Tue, 15 Oct 2024 00:15:10 -0400 Subject: [PATCH 21/21] remove remaining external module callouts; update functions to use common source param Signed-off-by: Tyler Auerbeck --- .github/workflows/docker_publish.yml | 3 +-- .github/workflows/publish_release.yml | 3 +-- dagger/main.go | 12 ++++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker_publish.yml b/.github/workflows/docker_publish.yml index 6be0df9f..c9ea12c1 100644 --- a/.github/workflows/docker_publish.yml +++ b/.github/workflows/docker_publish.yml @@ -21,5 +21,4 @@ jobs: with: version: "latest" verb: call - module: github.com/bishal7679/harbor-cli@v0.6.4 - args: docker-publish --directory-arg=. --cosign-key=${{ secrets.COSIGN_KEY }} --cosign-password=${{ env.COSIGN_PASSWORD }} --reg-username=${{ env.REGISTRY_USERNAME }} --reg-password=${{ env.REGISTRY_PASSWORD }} + args: publish-image --source=. --cosign-key=${{ secrets.COSIGN_KEY }} --cosign-password=${{ env.COSIGN_PASSWORD }} --reg-username=${{ env.REGISTRY_USERNAME }} --reg-password=${{ env.REGISTRY_PASSWORD }} diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 38ea2e60..7423d063 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -32,5 +32,4 @@ jobs: with: version: "latest" verb: call - module: github.com/bishal7679/harbor-cli@v0.6.1 - args: release --directory-arg=. --github-token=${{ env.GITHUB_TOKEN }} \ No newline at end of file + args: release --source=. --github-token=${{ env.GITHUB_TOKEN }} diff --git a/dagger/main.go b/dagger/main.go index a6b89f63..80bde24a 100644 --- a/dagger/main.go +++ b/dagger/main.go @@ -2,10 +2,9 @@ package main import ( "context" + "dagger/harbor-cli/internal/dagger" "fmt" "log" - "dagger/harbor-cli/internal/dagger" - ) const ( @@ -78,8 +77,13 @@ func (m *HarborCli) PullRequest(ctx context.Context, directoryArg *dagger.Direct log.Println("Pull-Request tasks completed successfully 🎉") } -func (m *HarborCli) Release(ctx context.Context, directoryArg *dagger.Directory, githubToken string) { - goreleaser := goreleaserContainer(directoryArg, githubToken).WithExec([]string{"release", "--clean"}) +func (m *HarborCli) Release( + ctx context.Context, + // +optional + // +defaultPath="./" + source *dagger.Directory, + githubToken string) { + goreleaser := goreleaserContainer(source, githubToken).WithExec([]string{"release", "--clean"}) _, err := goreleaser.Stderr(ctx) if err != nil { log.Printf("Error occured during release: %s", err)