Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions internal/cmd/service/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
Args: cobra.NoArgs,
Aliases: []string{"ls"},
PreRunE: util.RunEChain(
util.NeedProjectContextWhenNonInteractive(f),
util.NeedProjectContextWhenNonInteractive(f, &opts.projectID),
util.DefaultIDByContext(ctx.GetEnvironment(), &opts.environmentID),
),
RunE: func(cmd *cobra.Command, args []string) error {
return runList(f, opts)
},
}

cmd.Flags().StringVar(&opts.projectID, "project-id", opts.projectID, "Project ID")
util.AddEnvOfServiceParam(cmd, &opts.environmentID)

return cmd
Expand All @@ -49,10 +50,12 @@ func runList(f *cmdutil.Factory, opts *Options) error {
}

func runListInteractive(f *cmdutil.Factory, opts *Options) error {
// fetch project id from context
opts.projectID = f.Config.GetContext().GetProject().GetID()
// if project id is not set by flag, fetch from context
if opts.projectID == "" {
opts.projectID = f.Config.GetContext().GetProject().GetID()
}

// if project id is not set, prompt to select one
// if project id is still not set, prompt to select one
if _, err := f.ParamFiller.Project(&opts.projectID); err != nil {
return err
}
Expand Down
35 changes: 30 additions & 5 deletions internal/cmd/template/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,41 @@ func runSearch(f *cmdutil.Factory, opts Options) error {
s.Stop()

keyword := strings.ToLower(opts.keyword)
var matched model.Templates

type scoredTemplate struct {
template *model.Template
score int // higher = more relevant
}

var matched []scoredTemplate
for _, t := range allTemplates {
name := strings.ToLower(t.Name)
desc := strings.ToLower(t.Description)
if strings.Contains(name, keyword) || strings.Contains(desc, keyword) {
matched = append(matched, t)

score := 0
if strings.Contains(name, keyword) {
score = 3
} else if strings.Contains(desc, keyword) {
score = 2
} else {
for _, svc := range t.Services {
if strings.Contains(strings.ToLower(svc.Name), keyword) {
score = 1
break
}
}
}

if score > 0 {
matched = append(matched, scoredTemplate{template: t, score: score})
}
}

sort.Slice(matched, func(i, j int) bool {
return matched[i].DeploymentCnt > matched[j].DeploymentCnt
if matched[i].score != matched[j].score {
return matched[i].score > matched[j].score
}
return matched[i].template.DeploymentCnt > matched[j].template.DeploymentCnt
})

if len(matched) == 0 {
Expand All @@ -82,7 +106,8 @@ func runSearch(f *cmdutil.Factory, opts Options) error {

header := []string{"Code", "Name", "Description", "Deployments"}
rows := make([][]string, 0, len(matched))
for _, t := range matched {
for _, m := range matched {
t := m.template
rows = append(rows, []string{t.Code, t.Name, t.Description, strconv.Itoa(t.DeploymentCnt)})
}
f.Printer.Table(header, rows)
Expand Down
8 changes: 6 additions & 2 deletions internal/util/runE.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import (
"github.com/zeabur/cli/pkg/zcontext"
)

// NeedProjectContextWhenNonInteractive checks if the project context is set in the non-interactive mode
func NeedProjectContextWhenNonInteractive(f *cmdutil.Factory) CobraRunE {
// NeedProjectContextWhenNonInteractive checks if the project context is set in the non-interactive mode.
// If overrideID is provided and non-empty, the check is skipped (the caller already has a project ID from a flag).
func NeedProjectContextWhenNonInteractive(f *cmdutil.Factory, overrideID ...*string) CobraRunE {
return func(cmd *cobra.Command, args []string) error {
if len(overrideID) > 0 && overrideID[0] != nil && *overrideID[0] != "" {
return nil
}
if !f.Interactive && f.Config.GetContext().GetProject().Empty() {
return errors.New("please run <zeabur context set project> first")
}
Expand Down
22 changes: 14 additions & 8 deletions pkg/model/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@ import (
"github.com/zeabur/cli/pkg/util"
)

// TemplateServiceRef is a minimal reference to a service in a template, used for GraphQL queries.
type TemplateServiceRef struct {
Name string `graphql:"name"`
}

type Template struct {
CreatedAt time.Time `graphql:"createdAt"`
DeploymentCnt int `graphql:"deploymentCnt"`
Code string `graphql:"code"`
Description string `graphql:"description"`
Name string `graphql:"name"`
PreviewURL string `graphql:"previewURL"`
Readme string `graphql:"readme"`
Tags []string `graphql:"tags"`
CreatedAt time.Time `graphql:"createdAt"`
DeploymentCnt int `graphql:"deploymentCnt"`
Code string `graphql:"code"`
Description string `graphql:"description"`
Name string `graphql:"name"`
PreviewURL string `graphql:"previewURL"`
Readme string `graphql:"readme"`
Tags []string `graphql:"tags"`
Services []TemplateServiceRef `graphql:"services"`
}

type TemplateConnection struct {
Expand Down