@@ -11,6 +11,7 @@ import (
1111 "connectrpc.com/connect"
1212 "github.com/charmbracelet/bubbles/list"
1313 tea "github.com/charmbracelet/bubbletea"
14+ "github.com/charmbracelet/huh"
1415 "github.com/charmbracelet/lipgloss"
1516 "github.com/depot/cli/pkg/api"
1617 "github.com/depot/cli/pkg/project"
@@ -124,25 +125,23 @@ func (p *SelectedProject) SaveAs(configFilePath string) error {
124125}
125126
126127func ProjectExists (ctx context.Context , token , projectID string ) (* SelectedProject , error ) {
127- client := api .NewProjectsClient ()
128- req := cliv1beta1.ListProjectsRequest {}
129- projects , err := client .ListProjects (ctx , api .WithAuthentication (connect .NewRequest (& req ), token ))
128+ projects , err := RetrieveProjects (ctx , token )
130129 if err != nil {
131130 return nil , err
132131 }
133132
134133 // In the case that the user specified a project id on the command line with `--project`,
135134 // we check to see if the project exists. If it does not, we return an error.
136135 var selectedProject * cliv1beta1.ListProjectsResponse_Project
137- for _ , p := range projects .Msg . Projects {
136+ for _ , p := range projects .Projects {
138137 if p .Id == projectID {
139138 selectedProject = p
140139 break
141140 }
142141 }
143142
144143 if selectedProject == nil {
145- return nil , fmt .Errorf ("Project with ID %s not found" , projectID )
144+ return nil , fmt .Errorf ("project with ID %s not found" , projectID )
146145 }
147146
148147 return & SelectedProject {
@@ -153,32 +152,29 @@ func ProjectExists(ctx context.Context, token, projectID string) (*SelectedProje
153152}
154153
155154func InitializeProject (ctx context.Context , token , projectID string ) (* SelectedProject , error ) {
156- client := api .NewProjectsClient ()
157-
158- req := cliv1beta1.ListProjectsRequest {}
159- projects , err := client .ListProjects (ctx , api .WithAuthentication (connect .NewRequest (& req ), token ))
155+ projects , err := RetrieveProjects (ctx , token )
160156 if err != nil {
161157 return nil , err
162158 }
163159
164- if len (projects .Msg . Projects ) == 0 {
165- return nil , fmt .Errorf ("No projects found. Please create a project first. " )
160+ if len (projects .Projects ) == 0 {
161+ return nil , fmt .Errorf ("no projects found. Please create a project first" )
166162 }
167163
168164 // If we're not in a terminal, just print the projects and exit as we need
169165 // user intervention to pick a project.
170166 if ! IsTerminal () {
171- err := printProjectsCSV (projects .Msg . Projects )
167+ err := printProjectsCSV (projects .Projects )
172168 if err != nil {
173169 return nil , err
174170 }
175171 return nil , fmt .Errorf ("missing project ID; please run `depot init` or `depot build --project <id>`" )
176172 }
177173
178174 if projectID == "" {
179- projectID , err = chooseProjectID (projects . Msg )
175+ projectID , err = chooseProjectID (projects )
180176 if err != nil {
181- return nil , fmt .Errorf ("No project selected; please run `depot init`" )
177+ return nil , fmt .Errorf ("no project selected; please run `depot init`" )
182178 }
183179 }
184180
@@ -288,3 +284,47 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
288284func (m model ) View () string {
289285 return docStyle .Render (m .list .View ())
290286}
287+
288+ // SelectProject allows selecting a project using huh library
289+ func SelectProject (projects []* cliv1beta1.ListProjectsResponse_Project ) (string , error ) {
290+ if len (projects ) == 0 {
291+ return "" , fmt .Errorf ("no projects found" )
292+ }
293+
294+ var options []huh.Option [string ]
295+ for _ , p := range projects {
296+ options = append (options , huh .NewOption (fmt .Sprintf ("%s (%s)" , p .Name , p .OrgName ), p .Id ))
297+ }
298+
299+ var selectedID string
300+ form := huh .NewForm (
301+ huh .NewGroup (
302+ huh .NewSelect [string ]().
303+ Title ("Choose a project" ).
304+ Options (options ... ).
305+ Value (& selectedID ),
306+ ),
307+ )
308+
309+ err := form .Run ()
310+ if err != nil {
311+ return "" , fmt .Errorf ("error selecting project: %w" , err )
312+ }
313+
314+ if selectedID == "" {
315+ return "" , fmt .Errorf ("no project selected" )
316+ }
317+
318+ return selectedID , nil
319+ }
320+
321+ // RetrieveProjects calls the API to get the list of projects
322+ func RetrieveProjects (ctx context.Context , token string ) (* cliv1beta1.ListProjectsResponse , error ) {
323+ client := api .NewProjectsClient ()
324+ req := cliv1beta1.ListProjectsRequest {}
325+ resp , err := client .ListProjects (ctx , api .WithAuthentication (connect .NewRequest (& req ), token ))
326+ if err != nil {
327+ return nil , fmt .Errorf ("error retrieving projects: %w" , err )
328+ }
329+ return resp .Msg , nil
330+ }
0 commit comments