Version final
This commit is contained in:
1 parent
2d4b09b9ea
commit
74b7a0c448
13 files changed
+1103
-7
No files matched your search
+179
@@ -0,0 +1,179 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"registry-tui/client"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
type ViewState int
|
||||
|
||||
const (
|
||||
StateLoading ViewState = iota
|
||||
StateMainTable
|
||||
StateConfirmDelete
|
||||
StateNewTag
|
||||
StateError
|
||||
StateRegistryDown
|
||||
)
|
||||
|
||||
type AppMode int
|
||||
|
||||
const (
|
||||
ModeRegistry AppMode = iota
|
||||
ModeLocal
|
||||
)
|
||||
|
||||
type ImageRow = client.ImageRowData
|
||||
|
||||
type Model struct {
|
||||
state ViewState
|
||||
mode AppMode
|
||||
client *client.RegistryClient
|
||||
rows []ImageRow
|
||||
localRows []ImageRow
|
||||
registryRows []ImageRow
|
||||
cursor int
|
||||
err error
|
||||
statusMsg string
|
||||
textInput textinput.Model
|
||||
version string
|
||||
}
|
||||
|
||||
func NewModel(registryURL string, version string) Model {
|
||||
ti := textinput.New()
|
||||
ti.Placeholder = "ej. proyecto-web/alpine:v1.0"
|
||||
ti.CharLimit = 128
|
||||
ti.Width = 35
|
||||
|
||||
return Model{
|
||||
state: StateLoading,
|
||||
mode: ModeRegistry,
|
||||
client: client.NewRegistryClient(registryURL),
|
||||
textInput: ti,
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
func (m Model) Init() tea.Cmd {
|
||||
return fetchRegistryImagesCmd(m.client)
|
||||
}
|
||||
|
||||
type imagesMsg struct {
|
||||
rows []ImageRow
|
||||
mode AppMode
|
||||
}
|
||||
type errorMsg error
|
||||
type successMsg string
|
||||
|
||||
func fetchRegistryImagesCmd(c *client.RegistryClient) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
repos, err := c.GetCatalog()
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
|
||||
var rows []ImageRow
|
||||
for _, repo := range repos {
|
||||
tags, err := c.GetTags(repo)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var project, imageName string
|
||||
parts := strings.Split(repo, "/")
|
||||
if len(parts) > 1 {
|
||||
project = parts[0]
|
||||
imageName = strings.Join(parts[1:], "/")
|
||||
} else {
|
||||
project = ""
|
||||
imageName = repo
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
rows = append(rows, ImageRow{
|
||||
Project: project,
|
||||
RepoName: repo,
|
||||
ImageName: imageName,
|
||||
Tag: tag,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sortRows(rows)
|
||||
return imagesMsg{rows: rows, mode: ModeRegistry}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchLocalImagesCmd(c *client.RegistryClient) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
rows, err := c.GetLocalImages()
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
sortRows(rows)
|
||||
return imagesMsg{rows: rows, mode: ModeLocal}
|
||||
}
|
||||
}
|
||||
|
||||
func sortRows(rows []ImageRow) {
|
||||
sort.Slice(rows, func(i, j int) bool {
|
||||
if rows[i].Project == rows[j].Project {
|
||||
return rows[i].RepoName < rows[j].RepoName
|
||||
}
|
||||
return rows[i].Project < rows[j].Project
|
||||
})
|
||||
}
|
||||
|
||||
func deleteTagCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
err := c.DeleteManifest(repo, tag)
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
return successMsg("Tag borrado con éxito del registro")
|
||||
}
|
||||
}
|
||||
|
||||
func deleteLocalImageCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
err := c.DeleteLocalImage(repo, tag)
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
return successMsg("Imagen local borrada con éxito")
|
||||
}
|
||||
}
|
||||
|
||||
func copyImageCmd(c *client.RegistryClient, sourceRepo, sourceTag, destRepo, destTag string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
err := c.CopyManifest(sourceRepo, sourceTag, destRepo, destTag)
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
return successMsg("Imagen reestructurada con éxito en el registro")
|
||||
}
|
||||
}
|
||||
|
||||
func tagLocalImageCmd(c *client.RegistryClient, sourceRepo, sourceTag, destRepo, destTag string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
err := c.TagLocalImage(sourceRepo, sourceTag, destRepo, destTag)
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
return successMsg("Imagen local etiquetada con éxito")
|
||||
}
|
||||
}
|
||||
|
||||
func pushImageCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
err := c.PushLocalImage(repo, tag)
|
||||
if err != nil {
|
||||
return errorMsg(err)
|
||||
}
|
||||
return successMsg("Imagen subida (Push) al registro con éxito")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user