Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
36a0e2a
added application add command to create applications
vipul-rawat Dec 11, 2024
7bc24e2
fix linters
vipul-rawat Dec 11, 2024
650e5e0
fix tests for application
vipul-rawat Dec 12, 2024
c91263e
Merge branch 'main' of github.com:zopdev/zop-cli into add-application
vipul-rawat Dec 12, 2024
6b4f023
add application lister command to display all applications and enviro…
vipul-rawat Dec 12, 2024
dbd42c3
modify the application list output
vipul-rawat Dec 12, 2024
59e1868
modify the application list output
vipul-rawat Dec 12, 2024
e1bbd86
add environment creation
vipul-rawat Dec 12, 2024
3b195d1
fix linter errors
vipul-rawat Dec 16, 2024
cacd5d7
list all environments for an application
vipul-rawat Dec 16, 2024
f340f10
fix linter errors
vipul-rawat Dec 16, 2024
f96bba3
Merge branch 'main' of github.com:zopdev/zop-cli into list-application
vipul-rawat Dec 16, 2024
27f51a5
rename methods according to the convention
vipul-rawat Dec 16, 2024
40ffbb7
add test for list function
vipul-rawat Dec 16, 2024
5259853
Merge branch 'list-application' of github.com:zopdev/zop-cli into add…
vipul-rawat Dec 16, 2024
dec59de
refactor application lister interface
vipul-rawat Dec 16, 2024
9819d9d
Merge branch 'add-environment' of github.com:zopdev/zop-cli into list…
vipul-rawat Dec 16, 2024
f65bf72
add godoc for environment implementation
vipul-rawat Dec 16, 2024
ffee13c
Merge branch 'main' of github.com:zopdev/zop-cli into add-environment
vipul-rawat Dec 16, 2024
03d74fd
add table printing for the envs
vipul-rawat Dec 17, 2024
63705c5
refactor list generation for recurring use
vipul-rawat Dec 17, 2024
3bc5719
Merge branch 'add-environment' of github.com:zopdev/zop-cli into list…
vipul-rawat Dec 17, 2024
94c51df
change list styles to match zopdev theme
vipul-rawat Dec 17, 2024
ed5a56c
Merge branch 'main' of github.com:zopdev/zop-cli into list-environments
vipul-rawat Dec 17, 2024
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
41 changes: 39 additions & 2 deletions environment/handler/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@
package handler

import (
"bytes"
"fmt"
"sort"
"text/tabwriter"

"gofr.dev/pkg/gofr"
)

const padding = 2

// Handler is responsible for managing environment-related operations.
type Handler struct {
envSvc EnvAdder
envSvc EnvironmentService
}

// New creates a new Handler with the given EnvAdder service.
func New(envSvc EnvAdder) *Handler {
func New(envSvc EnvironmentService) *Handler {
return &Handler{envSvc: envSvc}
}

Expand All @@ -34,3 +39,35 @@ func (h *Handler) Add(ctx *gofr.Context) (any, error) {

return fmt.Sprintf("%d environments added", n), nil
}

func (h *Handler) List(ctx *gofr.Context) (any, error) {
envs, err := h.envSvc.List(ctx)
if err != nil {
return nil, err
}

sort.Slice(envs, func(i, j int) bool { return envs[i].ID < envs[j].ID })

b := bytes.NewBuffer([]byte{})

// Print a table of all the environments in the application
writer := tabwriter.NewWriter(b, 0, 0, padding, ' ', tabwriter.Debug)

// Print table headers
fmt.Fprintln(writer, "Name\tLevel\tCreatedAt\tUpdatedAt")

// Print rows for each environment
for _, env := range envs {
fmt.Fprintf(writer, "%s\t%d\t%s\t%s\n",
env.Name,
env.Level,
env.CreatedAt,
env.UpdatedAt,
)
}

// Flush the writer to output the table
writer.Flush()

return b.String(), nil
}
9 changes: 7 additions & 2 deletions environment/handler/interface.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package handler

import "gofr.dev/pkg/gofr"
import (
"gofr.dev/pkg/gofr"

type EnvAdder interface {
"zop.dev/cli/zop/environment/service"
)

type EnvironmentService interface {
Add(ctx *gofr.Context) (int, error)
List(ctx *gofr.Context) ([]service.Environment, error)
}
78 changes: 52 additions & 26 deletions environment/service/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,33 @@ import (
"io"
"net/http"

"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"gofr.dev/pkg/gofr"

"zop.dev/cli/zop/utils"
)

const listTitle = "Select the application where you want to add the environment!"

var (
// ErrUnableToRenderApps is returned when the application list cannot be rendered.
ErrUnableToRenderApps = errors.New("unable to render the list of applications")

// ErrConnectingZopAPI is returned when there is an error connecting to the Zop API.
ErrConnectingZopAPI = errors.New("unable to connect to Zop API")

// ErrorAddingEnv is returned when there is an error adding an environment.
ErrorAddingEnv = errors.New("unable to add environment")

// ErrNoApplicationSelected is returned when no application is selected.
ErrNoApplicationSelected = errors.New("no application selected")

// ErrorFetchingEnvironments is returned when there is an error fetching environments for a given application.
ErrorFetchingEnvironments = errors.New("unable to fetch environments")
)

// Service represents the application service that handles application and environment operations.
type Service struct {
appGet ApplicationGetter // appGet is responsible for fetching the list of applications.
appGet ApplicationGetter
}

// New creates a new Service instance with the provided ApplicationGetter.
Expand All @@ -41,8 +49,8 @@ func (s *Service) Add(ctx *gofr.Context) (int, error) {
return 0, err
}

ctx.Out.Println("Selected application: ", app.name)
ctx.Out.Println("Please provide names of environments to be added...")
ctx.Out.Println("Selected application: ", app.Name)
ctx.Out.Println("Please provide names of environment to be added...")

var (
input string
Expand All @@ -55,14 +63,13 @@ func (s *Service) Add(ctx *gofr.Context) (int, error) {

_, _ = fmt.Scanf("%s", &input)

err = postEnvironment(ctx, &Environment{Name: input, Level: level, ApplicationID: int64(app.id)})
err = postEnvironment(ctx, &Environment{Name: input, Level: level, ApplicationID: int64(app.ID)})
if err != nil {
return level, err
}

level++

// Ask the user if they want to add more environments.
ctx.Out.Print("Do you wish to add more? (y/n) ")

_, _ = fmt.Scanf("%s", &input)
Expand All @@ -75,42 +82,60 @@ func (s *Service) Add(ctx *gofr.Context) (int, error) {
return level, nil
}

func (s *Service) List(ctx *gofr.Context) ([]Environment, error) {
app, err := s.getSelectedApplication(ctx)
if err != nil {
return nil, err
}

resp, err := ctx.GetHTTPService("api-service").
Get(ctx, fmt.Sprintf("applications/%d/environments", app.ID), nil)
if err != nil {
ctx.Logger.Errorf("unable to connect to Zop API! %v", err)

return nil, ErrConnectingZopAPI
}

var data struct {
Envs []Environment `json:"data"`
}

err = getResponse(resp, &data)
if err != nil {
ctx.Logger.Errorf("unable to fetch environments, could not unmarshall response %v", err)

return nil, ErrorFetchingEnvironments
}

return data.Envs, nil
}

// getSelectedApplication renders a list of applications for the user to select from.
// It returns the selected application or an error if no selection is made.
func (s *Service) getSelectedApplication(ctx *gofr.Context) (*item, error) {
func (s *Service) getSelectedApplication(ctx *gofr.Context) (*utils.Item, error) {
apps, err := s.appGet.List(ctx)
if err != nil {
return nil, err
}

// Prepare a list of items for the user to select from.
items := make([]list.Item, 0)
items := make([]*utils.Item, 0)

for _, app := range apps {
items = append(items, &item{app.ID, app.Name})
items = append(items, &utils.Item{ID: app.ID, Name: app.Name})
}

// Initialize the list component for application selection.
l := list.New(items, itemDelegate{}, listWidth, listHeight)
l.Title = "Select the application where you want to add the environment!"
l.SetShowStatusBar(false)
l.SetFilteringEnabled(true)
l.Styles.PaginationStyle = paginationStyle
l.Styles.HelpStyle = helpStyle
l.SetShowStatusBar(false)

m := model{list: l}
choice, err := utils.RenderList(listTitle, items)
if err != nil {
ctx.Logger.Errorf("unable to render the list of applications! %v", err)

// Render the list using the bubbletea program.
if _, er := tea.NewProgram(&m).Run(); er != nil {
ctx.Logger.Errorf("unable to render the list of applications! %v", er)
return nil, ErrUnableToRenderApps
}

if m.choice == nil {
if choice == nil {
return nil, ErrNoApplicationSelected
}

return m.choice, nil
return choice, nil
}

// postEnvironment sends a POST request to the API to add the provided environment to the application.
Expand All @@ -124,6 +149,7 @@ func postEnvironment(ctx *gofr.Context, env *Environment) error {
})
if err != nil {
ctx.Logger.Errorf("unable to connect to Zop API! %v", err)

return ErrConnectingZopAPI
}

Expand Down
57 changes: 0 additions & 57 deletions environment/service/mock_interface.go

This file was deleted.

6 changes: 6 additions & 0 deletions environment/service/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ type Environment struct {

// Name is the name of the environment.
Name string `json:"name"`

// CreatedAt is the timestamp of when the environment was created.
CreatedAt string `json:"createdAt"`

// UpdatedAt is the timestamp of when the environment was last updated.
UpdatedAt string `json:"updatedAt"`
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
_ "github.com/mattn/go-sqlite3"
"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/service"
_ "modernc.org/sqlite"

applicationHandler "zop.dev/cli/zop/application/handler"
applicationSvc "zop.dev/cli/zop/application/service"
Expand Down Expand Up @@ -65,6 +64,7 @@ func main() {
envH := envHandler.New(envSvc)

app.SubCommand("environment add", envH.Add)
app.SubCommand("environment list", envH.List)

app.Run()
}
Loading
Loading