Skip to content

Commit 2a07116

Browse files
committed
chore: use radix-cli as a module dependency
fix: imporve login flow
1 parent 806dd0b commit 2a07116

11 files changed

Lines changed: 1361 additions & 47 deletions

File tree

applicationDashboard/applicationDashboard.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ func (m Model) Init() tea.Cmd {
1212
m.applicationsTable.Init(),
1313
m.pipelineTable.Init(),
1414
m.enviromentTable.Init(),
15-
commands.GetApplications,
16-
m.spinner.Tick,
15+
commands.CheckAuth(),
16+
m.spinner.Tick, // spinner will be visible only when we choose to render it
1717
getContext,
1818
)
1919
}
@@ -22,6 +22,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
2222
var cmds []tea.Cmd
2323

2424
switch msg := msg.(type) {
25+
case commands.AuthWaiting:
26+
// Show waiting for auth (no spinner), and trigger interactive login
27+
m.hasAuthRedirect = true
28+
return m, commands.LoginInteractive()
29+
30+
case commands.LoggedIn, commands.AuthOK:
31+
// After login or when already authenticated, start loading applications
32+
m.hasAuthRedirect = false
33+
return m, commands.GetApplications
2534

2635
case tea.KeyMsg:
2736
switch msg.String() {
@@ -54,7 +63,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
5463
}
5564

5665
case commands.Applications:
66+
// Loaded apps → clear any implicit auth-waiting state
5767
m.applications = msg
68+
m.hasAuthRedirect = false
5869

5970
case Context:
6071
m.context = string(msg)
@@ -105,6 +116,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
105116
}
106117

107118
func (m Model) View() string {
119+
// Before we get the first WindowSizeMsg, width/height can be 0; render a minimal view instead of blank.
120+
if m.width == 0 || m.height == 0 {
121+
if m.hasAuthRedirect {
122+
return "Waiting for authentication"
123+
}
124+
return "Loading applications " + m.spinner.View()
125+
}
108126
if m.width <= 110 || m.height <= 25 {
109127
return lipgloss.NewStyle().
110128
Height(m.height).
@@ -120,6 +138,16 @@ func (m Model) View() string {
120138

121139
}
122140
if len(m.applications) == 0 {
141+
if m.hasAuthRedirect {
142+
// During redirect, show text without spinner
143+
return lipgloss.NewStyle().
144+
Height(m.height).
145+
Width(m.width).
146+
AlignHorizontal(lipgloss.Center).
147+
AlignVertical(lipgloss.Center).
148+
Render("Waiting for authentication")
149+
}
150+
// Otherwise, show normal loading with spinner
123151
return lipgloss.NewStyle().
124152
Height(m.height).
125153
Width(m.width).

applicationDashboard/commands.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
package appllicationdashboard
22

33
import (
4-
"fmt"
5-
"os/exec"
6-
"regexp"
7-
84
tea "github.com/charmbracelet/bubbletea"
5+
radixconfig "github.com/equinor/radix-cli/pkg/config"
96
)
107

118
type Context string
129

1310
func getContext() tea.Msg {
14-
result := exec.Command("rx", "get", "context")
15-
regPattern := regexp.MustCompile(`'([^']*)'`)
16-
output, err := result.CombinedOutput()
17-
platform := regPattern.FindStringSubmatch(string(output))
18-
if err != nil {
19-
fmt.Println(err)
11+
// Read from radix config (same as rx uses)
12+
cfg, err := radixconfig.GetRadixConfig()
13+
if err != nil || cfg == nil || cfg.CustomConfig == nil {
14+
return Context("")
2015
}
21-
return Context(platform[1])
16+
return Context(cfg.CustomConfig.Context)
2217
}

applicationDashboard/commands/commands.go

Lines changed: 105 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package commands
22

33
import (
4-
"encoding/json"
4+
"context"
55
"fmt"
6-
"os/exec"
7-
"strings"
6+
"sort"
7+
"time"
88

9+
"github.com/FredrikMWold/radix-tui/internal/radix"
910
tea "github.com/charmbracelet/bubbletea"
11+
"github.com/equinor/radix-cli/pkg/cache"
12+
radixconfig "github.com/equinor/radix-cli/pkg/config"
1013
)
1114

1215
type SelectedApplication string
@@ -19,18 +22,58 @@ func SelectApplication(application string) tea.Cmd {
1922

2023
type Applications []string
2124

25+
// AuthWaiting indicates we expect to perform interactive login.
26+
type AuthWaiting struct{}
27+
28+
// AuthOK indicates cached provider/token is available; proceed to load apps.
29+
type AuthOK struct{}
30+
31+
// CheckAuth decides if we should show auth-waiting or start loading immediately.
32+
func CheckAuth() tea.Cmd {
33+
return func() tea.Msg {
34+
authCacheFilename := fmt.Sprintf("%s/auth.json", radixconfig.RadixConfigDir)
35+
global := cache.New(authCacheFilename, "global")
36+
if prov, ok := global.GetItem("auth_provider_type"); !ok || prov != "msal_interactive" {
37+
return AuthWaiting{}
38+
}
39+
// Check msal cache content under the interactive namespace
40+
msal := cache.New(authCacheFilename, "msal_interactive")
41+
if content, ok := msal.GetItem("msal"); !ok || len(content) == 0 {
42+
return AuthWaiting{}
43+
}
44+
_ = time.Second // reserved for future TTL checks
45+
return AuthOK{}
46+
}
47+
}
48+
49+
// LoginInteractive triggers an interactive login, then signals AuthOK.
50+
type LoggedIn struct{}
51+
52+
func LoginInteractive() tea.Cmd {
53+
return func() tea.Msg {
54+
ctx := context.Background()
55+
client, err := radix.New(false)
56+
if err == nil {
57+
_ = client.LoginInteractive(ctx)
58+
}
59+
return LoggedIn{}
60+
}
61+
}
62+
2263
func GetApplications() tea.Msg {
23-
result := exec.Command("rx", "get", "application")
24-
output, err := result.Output()
64+
ctx := context.Background()
65+
client, err := radix.New(false)
2566
if err != nil {
2667
fmt.Println(err)
68+
return Applications{}
2769
}
28-
trimmed := strings.TrimSpace(string(output))
29-
application_list := strings.Split(trimmed, "\n")
30-
if strings.Contains(application_list[0], "login.microsoft") {
31-
application_list = GetApplications().(Applications)
70+
apps, err := client.ListApplications(ctx)
71+
if err != nil {
72+
fmt.Println(err)
73+
return Applications{}
3274
}
33-
return Applications(application_list)
75+
sort.Strings(apps)
76+
return Applications(apps)
3477
}
3578

3679
type Application struct {
@@ -56,16 +99,63 @@ type Environment struct {
5699

57100
func GetApplicationData(application string) tea.Cmd {
58101
return func() tea.Msg {
59-
result := exec.Command("rx", "get", "application", "-a", application)
60-
output, err := result.Output()
102+
ctx := context.Background()
103+
client, err := radix.New(false)
61104
if err != nil {
62105
fmt.Println(err)
106+
return Application{}
63107
}
64-
var application Application
65-
err = json.Unmarshal(output, &application)
108+
app, err := client.GetApplication(ctx, application)
66109
if err != nil {
67110
fmt.Println(err)
111+
return Application{}
112+
}
113+
// Map API model to local struct expected by views
114+
var jobs []Job
115+
if app.Jobs != nil {
116+
for _, j := range app.Jobs {
117+
if j == nil {
118+
continue
119+
}
120+
jobs = append(jobs, Job{
121+
Name: stringDeref(j.Name),
122+
TriggeredBy: j.TriggeredBy,
123+
Environments: j.Environments,
124+
Pipeline: j.Pipeline,
125+
Status: j.Status,
126+
Created: func() string {
127+
if j.Created != nil {
128+
return j.Created.String()
129+
}
130+
return ""
131+
}(),
132+
})
133+
}
68134
}
69-
return application
135+
var envs []Environment
136+
if app.Environments != nil {
137+
for _, e := range app.Environments {
138+
if e == nil {
139+
continue
140+
}
141+
envs = append(envs, Environment{
142+
BranchMapping: e.BranchMapping,
143+
Name: stringDeref(e.Name),
144+
Status: e.Status,
145+
})
146+
}
147+
}
148+
return Application{
149+
Jobs: jobs,
150+
Environments: envs,
151+
Name: stringDeref(app.Name),
152+
}
153+
}
154+
}
155+
156+
func stringDeref(p *string) string {
157+
if p == nil {
158+
return ""
70159
}
160+
return *p
71161
}

applicationDashboard/model.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type Model struct {
4040
height int
4141
width int
4242
applications []string
43+
hasAuthRedirect bool
4344
}
4445

4546
func New() Model {

applicationDashboard/pipelineForms/applyConfig/commands.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package applyconfig
22

33
import (
4+
"context"
45
"fmt"
5-
"os/exec"
66

77
"github.com/FredrikMWold/radix-tui/applicationDashboard/commands"
8+
"github.com/FredrikMWold/radix-tui/internal/radix"
89
tea "github.com/charmbracelet/bubbletea"
910
)
1011

1112
func ApplyConfig(application string) tea.Cmd {
1213
return func() tea.Msg {
13-
result := exec.Command("rx", "create", "pipeline-job", "apply-config", "-a", application)
14-
_, err := result.Output()
14+
client, err := radix.New(false)
15+
if err == nil {
16+
_, err = client.TriggerApplyConfig(context.Background(), application)
17+
}
1518
if err != nil {
1619
fmt.Println(err)
1720
}

applicationDashboard/pipelineForms/buildAndDeploy/commands.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package buildanddeploy
22

33
import (
4+
"context"
45
"fmt"
5-
"os/exec"
66

77
"github.com/FredrikMWold/radix-tui/applicationDashboard/commands"
8+
"github.com/FredrikMWold/radix-tui/internal/radix"
89
tea "github.com/charmbracelet/bubbletea"
910
)
1011

1112
func BuildAndDeploy(application string, branch string) tea.Cmd {
1213
return func() tea.Msg {
13-
result := exec.Command("rx", "create", "pipeline-job", "build-deploy", "-a", application, "-b", branch)
14-
_, err := result.Output()
14+
client, err := radix.New(false)
15+
if err == nil {
16+
_, err = client.TriggerBuildDeploy(context.Background(), application, branch, "")
17+
}
1518
if err != nil {
1619
fmt.Println(err)
1720
}

applicationDashboard/pipelineTable/model.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package pipelinetable
33
import (
44
"fmt"
55
"os/exec"
6+
"runtime"
67
"time"
78

89
"github.com/FredrikMWold/radix-tui/applicationDashboard/commands"
@@ -48,5 +49,14 @@ func (m Model) openJobInBrowser() {
4849
}
4950
tableCursor := m.table.Cursor()
5051
url := fmt.Sprintf("https://console.radix.equinor.com/applications/%s/jobs/view/%s", m.application.Name, m.application.Jobs[tableCursor].Name)
51-
exec.Command("open", url).Start()
52+
var cmd *exec.Cmd
53+
switch runtime.GOOS {
54+
case "darwin":
55+
cmd = exec.Command("open", url)
56+
case "windows":
57+
cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
58+
default:
59+
cmd = exec.Command("xdg-open", url)
60+
}
61+
_ = cmd.Start()
5262
}

0 commit comments

Comments
 (0)