mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 12:22:15 +08:00
228 lines
5.4 KiB
Go
228 lines
5.4 KiB
Go
package pipeline
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"dagger.io/dagger"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/cliutil"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
var (
|
|
ErrorFlagNotProvided = errors.New("flag not provided, ex: '--go-version=1.21.0'")
|
|
)
|
|
|
|
type ArgumentType int
|
|
|
|
const (
|
|
ArgumentTypeString ArgumentType = iota
|
|
ArgumentTypeInt64
|
|
ArgumentTypeDirectory
|
|
ArgumentTypeCacheVolume
|
|
ArgumentTypeFile
|
|
ArgumentTypeBool
|
|
)
|
|
|
|
type ArgumentOpts struct {
|
|
Log *slog.Logger
|
|
CLIContext cliutil.CLIContext
|
|
Client *dagger.Client
|
|
State StateHandler
|
|
Platform dagger.Platform
|
|
}
|
|
|
|
type ArgumentValueFunc func(ctx context.Context, opts *ArgumentOpts) (any, error)
|
|
|
|
// An Argument is an input to a artifact command.
|
|
// It wraps the concept of a general CLI "Flag" to allow it to
|
|
// All arguments are required.
|
|
type Argument struct {
|
|
ArgumentType ArgumentType
|
|
Name string
|
|
Description string
|
|
|
|
// ValueFunc defines the behavior for how this artifact is populated.
|
|
// Maybe this could be an interface instead.
|
|
ValueFunc ArgumentValueFunc
|
|
|
|
// If Flags are set here, then it is safe to assume that these flags will be globally set and any other pipeline / artifact using this
|
|
// argument will be able to use these same flags.
|
|
// Example: `--grafana-dir`, `--grafana-ref`, etc.
|
|
Flags []cli.Flag
|
|
|
|
// Some arguments require other arguments to be set in order to derive their value.
|
|
// For example, the "version" argument(s) require the GrafanaDir (if the --version flag) was not set.
|
|
Requires []Argument
|
|
}
|
|
|
|
func (a Argument) Directory(ctx context.Context, opts *ArgumentOpts) (*dagger.Directory, error) {
|
|
if a.ValueFunc == nil {
|
|
return nil, fmt.Errorf("error: %w. Flag missing: %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dir, ok := value.(*dagger.Directory)
|
|
if !ok {
|
|
return nil, errors.New("value returned by valuefunc is not a *dagger.Directory")
|
|
}
|
|
|
|
return dir, nil
|
|
}
|
|
|
|
func (a Argument) MustDirectory(ctx context.Context, opts *ArgumentOpts) *dagger.Directory {
|
|
v, err := a.Directory(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func (a Argument) String(ctx context.Context, opts *ArgumentOpts) (string, error) {
|
|
if a.ValueFunc == nil {
|
|
return "", fmt.Errorf("error: %w. %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
v, ok := value.(string)
|
|
if !ok {
|
|
return "", errors.New("value returned by valuefunc is not a string")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func (a Argument) MustString(ctx context.Context, opts *ArgumentOpts) string {
|
|
v, err := a.String(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func (a Argument) Int64(ctx context.Context, opts *ArgumentOpts) (int64, error) {
|
|
if a.ValueFunc == nil {
|
|
return 0, fmt.Errorf("error: %w. %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
v, ok := value.(int64)
|
|
if !ok {
|
|
return 0, errors.New("value returned by valuefunc is not an int64")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func (a Argument) MustInt64(ctx context.Context, opts *ArgumentOpts) int64 {
|
|
v, err := a.Int64(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func (a Argument) Bool(ctx context.Context, opts *ArgumentOpts) (bool, error) {
|
|
if a.ValueFunc == nil {
|
|
return false, fmt.Errorf("error: %w. %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
v, ok := value.(bool)
|
|
if !ok {
|
|
return false, errors.New("value returned by valuefunc is not a bool")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func (a Argument) MustBool(ctx context.Context, opts *ArgumentOpts) bool {
|
|
v, err := a.Bool(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func (a Argument) File(ctx context.Context, opts *ArgumentOpts) (*dagger.File, error) {
|
|
if a.ValueFunc == nil {
|
|
return nil, fmt.Errorf("error: %w. %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dir, ok := value.(*dagger.File)
|
|
if !ok {
|
|
return nil, errors.New("value returned by valuefunc is not a *dagger.File")
|
|
}
|
|
|
|
return dir, nil
|
|
}
|
|
|
|
func (a Argument) MustFile(ctx context.Context, opts *ArgumentOpts) *dagger.File {
|
|
v, err := a.File(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func (a Argument) CacheVolume(ctx context.Context, opts *ArgumentOpts) (*dagger.CacheVolume, error) {
|
|
if a.ValueFunc == nil {
|
|
return nil, fmt.Errorf("error: %w. %s (%s)", ErrorFlagNotProvided, a.Name, a.Description)
|
|
}
|
|
value, err := a.ValueFunc(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dir, ok := value.(*dagger.CacheVolume)
|
|
if !ok {
|
|
return nil, errors.New("value returned by valuefunc is not a *dagger.File")
|
|
}
|
|
|
|
return dir, nil
|
|
}
|
|
|
|
func (a Argument) MustCacheVolume(ctx context.Context, opts *ArgumentOpts) *dagger.CacheVolume {
|
|
v, err := a.CacheVolume(ctx, opts)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
func StringFlagValueFunc(f *cli.StringFlag) func(context.Context, *ArgumentOpts) (any, error) {
|
|
return func(ctx context.Context, opts *ArgumentOpts) (any, error) {
|
|
return opts.CLIContext.String(f.Name), nil
|
|
}
|
|
}
|
|
|
|
func NewStringFlagArgument(flag *cli.StringFlag) Argument {
|
|
return Argument{
|
|
Name: flag.Name,
|
|
Description: flag.Usage,
|
|
Flags: []cli.Flag{
|
|
flag,
|
|
},
|
|
ValueFunc: StringFlagValueFunc(flag),
|
|
}
|
|
}
|