Skip to content

Commit

Permalink
feat(cmd): add next steps hint after template install (#417)
Browse files Browse the repository at this point in the history
* style(cmd): revert to using terminal colors

* feat(cmd): add next steps hint after template install

* chore(cmd): remove unused theme vars

* feat(cmd): select task
  • Loading branch information
rektdeckard authored Sep 17, 2024
1 parent d28c597 commit 003645a
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 74 deletions.
44 changes: 30 additions & 14 deletions cmd/lk/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,17 @@ var (
{
Name: "install",
Usage: "Execute installation defined in " + bootstrap.TaskFile,
ArgsUsage: "`DIR` location or the project directory (default: current directory)",
ArgsUsage: "[DIR] location of the project directory (default: current directory)",
Before: requireProject,
Action: installTemplate,
},
{
Hidden: true,
Name: "run",
Usage: "Execute a task defined in " + bootstrap.TaskFile,
ArgsUsage: "[TASK] to run in the project's taskfile.yaml",
Action: runTask,
},
{
Name: "env",
Usage: "Manage environment variables",
Expand All @@ -100,12 +107,6 @@ var (
return instantiateEnv(ctx, cmd, ".")
},
},
{
Name: "run",
Usage: "Execute a task defined in " + bootstrap.TaskFile,
ArgsUsage: "`DIR` location or the project directory (default: current directory)",
Action: runTask,
},
},
},
}
Expand Down Expand Up @@ -253,7 +254,7 @@ func setupSandboxTemplate(ctx context.Context, cmd *cli.Command) error {
return errors.New("sandbox ID is required")
}

_, token, err := requireToken(ctx, cmd)
token, err := requireToken(ctx, cmd)
if err != nil {
return err
}
Expand Down Expand Up @@ -364,25 +365,40 @@ func doInstall(ctx context.Context, task bootstrap.KnownTask, rootPath string, v

fullPath, err := filepath.Abs(rootPath)
if fullPath != "" {
fmt.Println("Installed template to " + fullPath)
fmt.Println("Installed template to " + fullPath + ". To start your sandbox:\n")
fmt.Println(" cd " + fullPath)
fmt.Println(" lk app run dev_sandbox")
fmt.Println("")
}

return err
}

func runTask(ctx context.Context, cmd *cli.Command) error {
verbose := cmd.Bool("verbose")
taskName := cmd.Args().First()
if taskName == "" {
return errors.New("task name is required")
}

rootDir := "."
tf, err := bootstrap.ParseTaskfile(rootDir)
if err != nil {
return err
}

taskName := cmd.Args().First()
if taskName == "" {
var options []huh.Option[string]
for _, name := range tf.Tasks.Keys() {
options = append(options, huh.NewOption(name, name))
}

if err := huh.NewSelect[string]().
Title("Select Task").
Options(options...).
Value(&taskName).
WithTheme(theme).
Run(); err != nil {
return err
}
}

task, err := bootstrap.NewTask(ctx, tf, rootDir, taskName, cmd.Bool("verbose"))
if err != nil {
return err
Expand Down
25 changes: 14 additions & 11 deletions cmd/lk/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,35 +230,38 @@ func handleAuth(ctx context.Context, cmd *cli.Command) error {
if err := loadProjectConfig(ctx, cmd); err != nil {
return err
}
cfg, token, err := requireToken(ctx, cmd)
token, err := requireToken(ctx, cmd)
if err != nil {
return err
}
return authClient.Deauthenticate(ctx, cfg.Name, token)
return authClient.Deauthenticate(ctx, project.Name, token)
}
return tryAuthIfNeeded(ctx, cmd)
}

func requireToken(_ context.Context, cmd *cli.Command) (*config.ProjectConfig, string, error) {
cfg, err := loadProjectDetails(cmd)
if err != nil {
return nil, "", err
func requireToken(_ context.Context, cmd *cli.Command) (string, error) {
if project == nil {
var err error
project, err = loadProjectDetails(cmd)
if err != nil {
return "", err
}
}

// construct a token from the chosen project, using the hashed secret as the identity
// as a means of preventing any old token generated with this key/secret pair from
// deleting it
hash, err := hashString(cfg.APISecret)
hash, err := hashString(project.APISecret)
if err != nil {
return nil, "", err
return "", err
}
at := auth.NewAccessToken(cfg.APIKey, cfg.APISecret).SetIdentity(hash)
at := auth.NewAccessToken(project.APIKey, project.APISecret).SetIdentity(hash)
token, err := at.ToJWT()
if err != nil {
return nil, "", err
return "", err
}

return cfg, token, nil
return token, nil
}

func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error {
Expand Down
1 change: 0 additions & 1 deletion cmd/lk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ func main() {
go func() {
<-ctx.Done()
stop()
fmt.Println()
}()

checkForLegacyName()
Expand Down
6 changes: 2 additions & 4 deletions cmd/lk/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"errors"
"fmt"
"net/url"
"os"
"regexp"

"github.com/charmbracelet/huh"
Expand Down Expand Up @@ -243,10 +242,9 @@ func listProjects(ctx context.Context, cmd *cli.Command) error {
return nil
}

re := lipgloss.NewRenderer(os.Stdout)
baseStyle := re.NewStyle().Padding(0, 1)
baseStyle := theme.Form.Foreground(fg).Padding(0, 1)
headerStyle := baseStyle.Bold(true)
selectedStyle := baseStyle.Foreground(cyan)
selectedStyle := theme.Focused.Title.Padding(0, 1)

table := CreateTable().
StyleFunc(func(row, col int) lipgloss.Style {
Expand Down
42 changes: 2 additions & 40 deletions cmd/lk/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,9 @@ import (
)

var (
normalFg = lipgloss.AdaptiveColor{Light: "235", Dark: "252"}
normalBg = lipgloss.AdaptiveColor{Light: "20", Dark: "0"}
dimFg = lipgloss.AdaptiveColor{Light: "", Dark: "243"}
placeholderFg = lipgloss.AdaptiveColor{Light: "248", Dark: "238"}
cyan = lipgloss.AdaptiveColor{Light: "#06B7DB", Dark: "#1FD5F9"}
red = lipgloss.AdaptiveColor{Light: "#CE4A3B", Dark: "#FF6352"}
yellow = lipgloss.AdaptiveColor{Light: "#DB9406", Dark: "#F9B11F"}
green = lipgloss.AdaptiveColor{Light: "#036D26", Dark: "#06DB4D"}

fg = lipgloss.AdaptiveColor{Light: "235", Dark: "252"}
theme = func() *huh.Theme {
t := huh.ThemeBase()

t.Focused.Base = t.Focused.Base.BorderForeground(lipgloss.Color("238"))
t.Focused.Title = t.Focused.Title.Foreground(cyan).Bold(true)
t.Focused.NoteTitle = t.Focused.NoteTitle.Foreground(cyan).Bold(true).MarginBottom(1)
t.Focused.Directory = t.Focused.Directory.Foreground(cyan)
t.Focused.Description = t.Focused.Description.Foreground(dimFg)
t.Focused.ErrorIndicator = t.Focused.ErrorIndicator.Foreground(red)
t.Focused.ErrorMessage = t.Focused.ErrorMessage.Foreground(red)
t.Focused.SelectSelector = t.Focused.SelectSelector.Foreground(yellow)
t.Focused.NextIndicator = t.Focused.NextIndicator.Foreground(yellow)
t.Focused.PrevIndicator = t.Focused.PrevIndicator.Foreground(yellow)
t.Focused.Option = t.Focused.Option.Foreground(normalFg)
t.Focused.MultiSelectSelector = t.Focused.MultiSelectSelector.Foreground(yellow)
t.Focused.SelectedOption = t.Focused.SelectedOption.Foreground(green)
t.Focused.SelectedPrefix = lipgloss.NewStyle().Foreground(green).SetString("✓ ")
t.Focused.UnselectedPrefix = lipgloss.NewStyle().Foreground(dimFg).SetString("• ")
t.Focused.UnselectedOption = t.Focused.UnselectedOption.Foreground(normalFg)
t.Focused.FocusedButton = t.Focused.FocusedButton.Foreground(normalBg).Background(cyan)
t.Focused.Next = t.Focused.FocusedButton
t.Focused.BlurredButton = t.Focused.BlurredButton.Foreground(normalFg).Background(lipgloss.AdaptiveColor{Light: "252", Dark: "237"})

// t.Focused.TextInput.Cursor = t.Focused.TextInput.Cursor.Foreground(yellow)
t.Focused.TextInput.Placeholder = t.Focused.TextInput.Placeholder.Foreground(placeholderFg)
t.Focused.TextInput.Prompt = t.Focused.TextInput.Prompt.Foreground(yellow)

t.Blurred = t.Focused
t.Blurred.Base = t.Focused.Base.BorderStyle(lipgloss.HiddenBorder())
t.Blurred.NextIndicator = lipgloss.NewStyle()
t.Blurred.PrevIndicator = lipgloss.NewStyle()

t := huh.ThemeBase16()
return t
}()
)
7 changes: 3 additions & 4 deletions cmd/lk/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ func PrintJSON(obj any) {
}

func CreateTable() *table.Table {
re := lipgloss.NewRenderer(os.Stdout)
baseStyle := re.NewStyle().Padding(0, 1)
baseStyle := theme.Form.Foreground(fg).Padding(0, 1)
headerStyle := baseStyle.Bold(true)

styleFunc := func(row, col int) lipgloss.Style {
Expand All @@ -179,7 +178,7 @@ func CreateTable() *table.Table {

t := table.New().
Border(lipgloss.NormalBorder()).
BorderStyle(re.NewStyle().Foreground(normalFg)).
BorderStyle(theme.Form.Foreground(fg)).
StyleFunc(styleFunc)

return t
Expand Down Expand Up @@ -266,7 +265,7 @@ func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConf
// load default project
dp, err := config.LoadDefaultProject()
if err == nil {
fmt.Println("Using default project", dp.Name)
fmt.Println("Using default project [" + theme.Focused.Title.Render(dp.Name) + "]")
logDetails(c, dp)
return dp, nil
}
Expand Down

0 comments on commit 003645a

Please sign in to comment.