Merge remote-tracking branch 'origin/feat/first-run' into feat/l-for-details
This commit is contained in:
commit
dee144f33f
4 files changed
+107
-1
No files matched your search
@@ -60,7 +60,8 @@ lazysecrets # start lazysecrets
|
||||
lazysecrets --demo # test with demo data
|
||||
```
|
||||
|
||||
Pick a source on the left, then a vault, then a secret. The keys you'll
|
||||
Pick a source on the left, then a vault, then a secret. With nothing
|
||||
signed in yet, the right pane says how to get started. The keys you'll
|
||||
use most:
|
||||
|
||||
| Key | Action |
|
||||
|
||||
@@ -1238,3 +1238,36 @@ func TestStatusPane(t *testing.T) {
|
||||
t.Errorf("back to %v", d.m.focus)
|
||||
}
|
||||
}
|
||||
|
||||
// empty is an account with nothing in it, like Databricks without profiles.
|
||||
type empty struct{ provider.Provider }
|
||||
|
||||
func (empty) Sources(context.Context) ([]provider.Source, error) { return nil, nil }
|
||||
|
||||
func TestGetStarted(t *testing.T) {
|
||||
t.Parallel()
|
||||
d := newDriverOpts(t, Options{}, signedOut{fake.Azure(0)}, empty{fake.Databricks(0)})
|
||||
scr := d.screen()
|
||||
for _, want := range []string{"get started", "Azure az login", "L runs it here",
|
||||
"databricks auth login --host", "lazysecrets --demo"} {
|
||||
if !strings.Contains(scr, want) {
|
||||
t.Errorf("missing %q:\n%s", want, scr)
|
||||
}
|
||||
}
|
||||
d.keys("l", "j")
|
||||
if a := d.m.loginFor(); a == nil || a.Account != "Azure · admin" {
|
||||
t.Errorf("L signs in to %+v", a)
|
||||
}
|
||||
d.keys("y")
|
||||
if got := d.clip().content; got != "az login" {
|
||||
t.Errorf("y copied %q", got)
|
||||
}
|
||||
|
||||
// Once an account has something, an empty one says what it needs.
|
||||
d = newDriverOpts(t, Options{}, fake.Azure(0), empty{fake.Databricks(0)})
|
||||
d.m.sources.SelectWhere(func(r sourceRow) bool { return r.kind == rowGroup && r.provider == fake.Databricks(0).ID() })
|
||||
d.send(nil)
|
||||
if scr := d.screen(); strings.Contains(scr, "get started") || !strings.Contains(scr, "databricks auth login") {
|
||||
t.Errorf("empty Databricks:\n%s", scr)
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,8 @@ func (m *Model) syncFields() tea.Cmd {
|
||||
case paneSources:
|
||||
r, ok := m.sources.Selected()
|
||||
switch {
|
||||
case m.nothingFound():
|
||||
m.fields.Show("get started", m.getStartedFields())
|
||||
case !ok:
|
||||
m.fields.Show("", nil)
|
||||
case m.selectedProblem() != "":
|
||||
@@ -106,6 +108,10 @@ func (m *Model) showAccount(r sourceRow) tea.Cmd {
|
||||
}
|
||||
fields = append(fields, groupFields(st)...)
|
||||
}
|
||||
if res, done := m.sourceResults[r.provider]; done && res.err == nil && len(res.sources) == 0 {
|
||||
hint := emptyHint(p.Kind())
|
||||
fields = append(fields, panes.Field{Label: "nothing", Value: "found: try", Info: true}, panes.Field{Value: hint.Value, URL: hint.URL})
|
||||
}
|
||||
m.fields.Show(p.Label(), fields)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/provider"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/ui/panes"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/update"
|
||||
)
|
||||
|
||||
// When no account has anything to show, as on a first run, the right
|
||||
// pane says how to get started: the sign-in for each kind of account
|
||||
// (y copies it, L runs az login), and the demo.
|
||||
|
||||
// nothingFound reports whether every account has loaded, with nothing.
|
||||
func (m Model) nothingFound() bool {
|
||||
if m.sourcesPending > 0 {
|
||||
return false
|
||||
}
|
||||
for _, p := range m.providers {
|
||||
if len(m.sourceResults[p.ID()].sources) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// getStartedFields are the rows saying how to get started.
|
||||
func (m Model) getStartedFields() []panes.Field {
|
||||
out := []panes.Field{{Value: "Nothing to show yet: sign in where your secrets are.", Info: true}}
|
||||
seen := map[provider.Kind]bool{}
|
||||
for _, p := range m.providers {
|
||||
if seen[p.Kind()] {
|
||||
continue
|
||||
}
|
||||
seen[p.Kind()] = true
|
||||
f := emptyHint(p.Kind())
|
||||
var auth *provider.AuthError
|
||||
switch err := m.sourceResults[p.ID()].err; {
|
||||
case errors.As(err, &auth) && len(auth.Login) > 0:
|
||||
f.Provider = p.ID() // L signs in
|
||||
out = append(out, f, panes.Field{Value: withKey(m.keys.Login, "%s runs it here"), Info: true})
|
||||
case err != nil:
|
||||
out = append(out, f, panes.Field{Value: err.Error(), Info: true, Err: true})
|
||||
default:
|
||||
out = append(out, f)
|
||||
}
|
||||
}
|
||||
return append(out,
|
||||
panes.Field{Label: "try", Value: "lazysecrets --demo"},
|
||||
panes.Field{Value: "built-in sample data, to look around", Info: true},
|
||||
panes.Field{Label: "docs", Value: "getting started", URL: update.DefaultRepo + "#get-started"},
|
||||
)
|
||||
}
|
||||
|
||||
// emptyHint is how an account of kind gets something to show.
|
||||
func emptyHint(kind provider.Kind) panes.Field {
|
||||
switch kind {
|
||||
case provider.KindDatabricks:
|
||||
return panes.Field{Label: "Databricks", Value: "databricks auth login --host https://<workspace>"}
|
||||
case provider.KindRepo:
|
||||
return panes.Field{Label: "repos", Value: "SOPS and .env files in your git repos",
|
||||
URL: update.DefaultRepo + "/src/branch/main/docs/repos.md"}
|
||||
}
|
||||
return panes.Field{Label: string(kind), Value: "az login"}
|
||||
}
|
||||
Reference in new issue
Block a user