-
Notifications
You must be signed in to change notification settings - Fork 30
feat(charm): add lipgloss styling with Slack brand colors under charm experiment #365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0c3d9d6
e07ccae
6f4f50a
f3f150d
29b218e
3a5cc9f
faeb01c
9dc0b88
be81b3d
a440b11
4f55cfc
14b9448
06d0233
9d08b0a
92b1bf4
6f4a9ab
cd2e287
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ func HelpFunc( | |
| if help, _ := clients.Config.Flags.GetBool("help"); help { | ||
| clients.Config.LoadExperiments(ctx, clients.IO.PrintDebug) | ||
| } | ||
| style.ToggleCharm(clients.Config.WithExperimentOn(experiment.Charm)) | ||
| experiments := []string{} | ||
| for _, exp := range clients.Config.GetExperiments() { | ||
| if experiment.Includes(exp) { | ||
|
|
@@ -66,15 +67,64 @@ func PrintHelpTemplate(cmd *cobra.Command, data style.TemplateData) { | |
| cmd.PrintErrln(err) | ||
| } | ||
| cmd.Long = cmdLongF.String() | ||
| tmpl := helpTemplate | ||
| tmpl := legacyHelpTemplate | ||
| if style.IsCharmEnabled() { | ||
| tmpl = charmHelpTemplate | ||
| } | ||
| err = style.PrintTemplate(cmd.OutOrStdout(), tmpl, templateInfo{cmd, data}) | ||
| if err != nil { | ||
| cmd.PrintErrln(err) | ||
| } | ||
| } | ||
|
|
||
| // helpTemplate formats values and information for a helpful output | ||
| const helpTemplate string = `{{.Long}} | ||
| // ════════════════════════════════════════════════════════════════════════════════ | ||
| // Charm help template — lipgloss styling | ||
| // ════════════════════════════════════════════════════════════════════════════════ | ||
|
|
||
| const charmHelpTemplate string = `{{.Long | ToDescription}} | ||
|
|
||
| {{Header "Usage"}}{{if .Runnable}} | ||
| {{ToPrompt "$ "}}{{ToCommandText .UseLine}}{{end}}{{if gt (len .Aliases) 0}} | ||
|
|
||
| {{Header "Aliases"}} | ||
| {{.NameAndAliases | ToCommandText}}{{end}}{{if .HasAvailableSubCommands}} | ||
|
|
||
| {{if eq .Name (GetProcessName)}}{{Header "Commands"}}{{range .Commands}}{{if and (.HasAvailableSubCommands) (not .Hidden)}} | ||
| {{.Name | ToGroupName }}{{range .Commands}}{{if (not .Hidden)}} | ||
| {{rpad .Name .NamePadding | ToCommandText}} {{.Short | ToDescription}}{{end}}{{end}}{{end}}{{end}}{{if and (.HasAvailableSubCommands) (not .Hidden)}}{{range .Commands}}{{if and (not .HasAvailableSubCommands) (not .Hidden)}}{{if not (IsAlias .Name $.Data.Aliases)}} | ||
| {{(rpad .Name .NamePadding) | ToGroupName }}{{.Short | ToDescription}}{{end}}{{end}}{{end}}{{end}}{{else}}{{Header "Subcommands"}}{{if and (.HasAvailableSubCommands) (not .Hidden)}}{{range .Commands}}{{if not .HasAvailableSubCommands}} | ||
| {{(rpad .Name .NamePadding) | ToCommandText }} {{.Short | ToDescription}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} | ||
|
|
||
| {{Header "Flags"}} | ||
| {{.LocalFlags.FlagUsages | trimTrailingWhitespaces | ToFlags}}{{end}}{{if and (.HasAvailableSubCommands) (not .Hidden)}}{{if or (HasAliasSubcommands .Name .Data.Aliases) (eq .Name (GetProcessName))}} | ||
|
|
||
| {{Header "Global aliases"}}{{range .Commands}}{{if and (IsAlias .Name $.Data.Aliases) (not .Hidden)}} | ||
| {{(rpad .Name .NamePadding) | ToGroupName }} {{rpad (AliasParent .Name $.Data.Aliases) AliasPadding | ToAliasParent}} {{ToPrompt "❱"}} {{.Name | ToGroupName}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableInheritedFlags}} | ||
|
|
||
| {{Header "Global flags"}} | ||
| {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces | ToFlags}}{{end}}{{if .HasExample}} | ||
|
|
||
| {{Header "Example"}} | ||
| {{ Examples .Example}}{{end}}{{if and (.HasAvailableSubCommands) (not .Hidden)}} | ||
|
|
||
| {{Header "Experiments"}} | ||
| {{ Experiments .Data.Experiments }} | ||
|
|
||
| {{Header "Additional help"}} | ||
| {{ToSecondary "For more information about a specific command, run:"}} | ||
| {{ToPrompt "$ "}}{{ToCommandText .CommandPath}}{{if eq .Name (GetProcessName)}}{{ToCommandText " <command>"}}{{end}}{{ToCommandText " <subcommand> --help"}} | ||
|
|
||
| {{ToSecondary "For guides and documentation, head over to "}}{{LinkText "https://docs.slack.dev/tools/slack-cli"}}{{end}} | ||
|
|
||
| ` | ||
|
|
||
| // ════════════════════════════════════════════════════════════════════════════════ | ||
| // DEPRECATED: Legacy help template — aurora styling | ||
| // | ||
| // Delete this entire block when the charm experiment is permanently enabled. | ||
| // ════════════════════════════════════════════════════════════════════════════════ | ||
|
|
||
| const legacyHelpTemplate string = `{{.Long}} | ||
|
Comment on lines
+121
to
+127
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔍 suggestion: We should avoid changing existing code with experimental changes. I imagine we'll want to rename |
||
|
|
||
| {{Header "Usage"}}{{if .Runnable}} | ||
| $ {{.UseLine}}{{end}}{{if gt (len .Aliases) 0}} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,8 +19,8 @@ import ( | |
| "fmt" | ||
| "testing" | ||
|
|
||
| tea "github.com/charmbracelet/bubbletea" | ||
| "github.com/charmbracelet/huh" | ||
| tea "charm.land/bubbletea/v2" | ||
| huh "charm.land/huh/v2" | ||
| "github.com/charmbracelet/x/ansi" | ||
| "github.com/slackapi/slack-cli/internal/shared" | ||
| "github.com/stretchr/testify/assert" | ||
|
|
@@ -77,7 +77,7 @@ func TestBuildTemplateSelectionForm(t *testing.T) { | |
| doAllUpdates(f, f.Init()) | ||
|
|
||
| // Submit first option (Starter app -> getting-started) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
|
|
||
| view := ansi.Strip(f.View()) | ||
|
|
@@ -95,13 +95,13 @@ func TestBuildTemplateSelectionForm(t *testing.T) { | |
| doAllUpdates(f, f.Init()) | ||
|
|
||
| // Navigate down to "View more samples" (4th option, index 3) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
|
Comment on lines
97
to
+104
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🪬 thought: These changes aren't related to lipgloss which make review evermore difficult but also make me think we're testing too much related to prompts here. I'm not familiar with this implementation but I'd expect assertions that expected values are passed to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these were updated to match the new v2 syntax for key presses - i agree this PR got really big really fast. i wanted to update to v2 here to resolve the bugs we had with the huh forms which i felt were related to styling. i just didnt realize there would be so much needing changing 😭 |
||
| doAllUpdates(f, cmd) | ||
|
|
||
| assert.Equal(t, viewMoreSamples, category) | ||
|
|
@@ -119,11 +119,11 @@ func TestBuildTemplateSelectionForm(t *testing.T) { | |
| doAllUpdates(f, f.Init()) | ||
|
|
||
| // Navigate to Automation app (3rd option, index 2) and submit | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
|
|
||
| view := ansi.Strip(f.View()) | ||
|
|
@@ -140,10 +140,10 @@ func TestBuildTemplateSelectionForm(t *testing.T) { | |
| doAllUpdates(f, f.Init()) | ||
|
|
||
| // Select first category (Starter app) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| // Select first template (Bolt for JavaScript) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
|
|
||
| assert.Equal(t, "slack-cli#getting-started", category) | ||
|
|
@@ -176,10 +176,10 @@ func TestCharmPromptTemplateSelection(t *testing.T) { | |
| runForm = func(f *huh.Form) error { | ||
| doAllUpdates(f, f.Init()) | ||
| // Select first category (Starter app) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| // Select first template (Bolt for JavaScript) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| return nil | ||
| } | ||
|
|
@@ -212,16 +212,16 @@ func TestCharmPromptTemplateSelection(t *testing.T) { | |
| runForm = func(f *huh.Form) error { | ||
| doAllUpdates(f, f.Init()) | ||
| // Navigate to "View more samples" (4th option) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| // Select "Browse sample gallery..." | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| return nil | ||
| } | ||
|
|
@@ -240,12 +240,12 @@ func TestCharmPromptTemplateSelection(t *testing.T) { | |
| runForm = func(f *huh.Form) error { | ||
| doAllUpdates(f, f.Init()) | ||
| // Navigate to "AI Agent app" (2nd option) | ||
| _, cmd := f.Update(tea.KeyMsg{Type: tea.KeyDown}) | ||
| _, cmd := f.Update(tea.KeyPressMsg{Code: tea.KeyDown}) | ||
| doAllUpdates(f, cmd) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| // Select first template (Bolt for JavaScript) | ||
| _, cmd = f.Update(tea.KeyMsg{Type: tea.KeyEnter}) | ||
| _, cmd = f.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) | ||
| doAllUpdates(f, cmd) | ||
| return nil | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧪 question: Can we use
clientsto check for this experiment instead?