Skip to content

Commit

Permalink
feat(docs+cmd): document bootstrap feature, add template list (#456)
Browse files Browse the repository at this point in the history
* chore(lk): show template tags in list

* chore(docs): add instructions for bootstrapping an app from template

* feat(cmd): add `lk app list-templates` and update README

* chore(cmd): show default project with '*'

* chore(cmd): bump package version

* chore(cmd): use vars and add util tests

* chore(cmd): prettify `lk app list-templates` output
  • Loading branch information
rektdeckard authored Dec 10, 2024
1 parent 77f1841 commit 20a1b8d
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 15 deletions.
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@

This package includes command line utilities that interacts with LiveKit. It allows you to:

- Bootstrap new applications from templates
- Create access tokens
- Access LiveKit APIs, create, delete rooms, etc.
- Access LiveKit APIs, create and delete rooms, etc.
- Join a room as a participant, inspecting in-room events
- Start and manage Egress
- Start and manage Egresses
- Perform load testing, efficiently simulating real-world load

# Installation
Expand Down Expand Up @@ -55,7 +56,7 @@ make install

# Usage

See `lk --help` for a complete list of subcommands.
See `lk --help` for a complete list of subcommands. The `--help` flag can also be used on any subcommand for more information.

## Set up your project (new)

Expand Down Expand Up @@ -86,6 +87,24 @@ lk project list
lk project set-default <project_name>
```

## Bootstrapping an application

The LiveKit CLI can help you bootstrap applications from a number of convenient template repositories, using your project credentials to set up required environment variables and other configuration automatically. To create an application from a template, run the following:

```shell
lk app create --template <template_name> my-app
```

Then follow the CLI prompts to finish your setup.

For a list of all available templates, run:

```shell
lk app list-templates
```

See the [LiveKit Templates Index](https://github.com/livekit-examples/index?tab=readme-ov-file) for details about templates, and for instructions on how to contribute your own.

## Publishing to a room

### Publish demo video track
Expand Down
36 changes: 35 additions & 1 deletion cmd/lk/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"os"
"regexp"
"strings"

"github.com/charmbracelet/huh"
"github.com/charmbracelet/huh/spinner"
Expand Down Expand Up @@ -78,6 +79,12 @@ var (
},
},
},
{
Name: "list-templates",
Usage: "List available templates to bootstrap a new application",
Flags: []cli.Flag{jsonFlag},
Action: listTemplates,
},
{
Hidden: true,
Name: "install",
Expand Down Expand Up @@ -175,6 +182,31 @@ func requireProject(ctx context.Context, cmd *cli.Command) error {
return err
}

func listTemplates(ctx context.Context, cmd *cli.Command) error {
templates, err := bootstrap.FetchTemplates(ctx)
if err != nil {
return err
}

if cmd.Bool("json") {
PrintJSON(templates)
} else {
const maxDescLength = 64
table := CreateTable().Headers("Template", "Description").BorderRow(true)
for _, t := range templates {
desc := strings.Join(wrapToLines(t.Desc, maxDescLength), "\n")
url := theme.Focused.Title.Render(t.URL)
tags := theme.Help.ShortDesc.Render("#" + strings.Join(t.Tags, " #"))
table.Row(
t.Name,
desc+"\n\n"+url+"\n"+tags,
)
}
fmt.Println(table)
}
return nil
}

func setupTemplate(ctx context.Context, cmd *cli.Command) error {
verbose := cmd.Bool("verbose")
install := cmd.Bool("install")
Expand Down Expand Up @@ -218,7 +250,9 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error {
WithTheme(theme)
var options []huh.Option[string]
for _, t := range templateOptions {
options = append(options, huh.NewOption(t.Name, t.URL))
descStyle := theme.Help.ShortDesc
optionText := t.Name + " " + descStyle.Render("#"+strings.Join(t.Tags, " #"))
options = append(options, huh.NewOption(optionText, t.URL))
}
templateSelect.(*huh.Select[string]).Options(options...)
preinstallPrompts = append(preinstallPrompts, templateSelect)
Expand Down
10 changes: 8 additions & 2 deletions cmd/lk/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,15 @@ func listProjects(ctx context.Context, cmd *cli.Command) error {
return baseStyle
}
}).
Headers("Name", "URL", "API Key", "Default")
Headers("Name", "URL", "API Key")
for _, p := range cliConfig.Projects {
table.Row(p.Name, p.URL, p.APIKey, fmt.Sprint(p.Name == cliConfig.DefaultProject))
var pName string
if p.Name == cliConfig.DefaultProject {
pName = "* " + p.Name
} else {
pName = " " + p.Name
}
table.Row(pName, p.URL, p.APIKey)
}
fmt.Println(table)
}
Expand Down
32 changes: 32 additions & 0 deletions cmd/lk/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,38 @@ func wrapWith(wrap string) func(string) string {
}
}

func ellipsizeTo(str string, maxLength int) string {
if len(str) <= maxLength {
return str
}
ellipsis := "..."
contentLen := max(0, min(len(str), maxLength-len(ellipsis)))
return str[:contentLen] + ellipsis
}

func wrapToLines(input string, maxLineLength int) []string {
words := strings.Fields(input)
var lines []string
var currentLine strings.Builder

for _, word := range words {
if currentLine.Len()+len(word)+1 > maxLineLength {
lines = append(lines, currentLine.String())
currentLine.Reset()
}
if currentLine.Len() > 0 {
currentLine.WriteString(" ")
}
currentLine.WriteString(word)
}

if currentLine.Len() > 0 {
lines = append(lines, currentLine.String())
}

return lines
}

// Provides a temporary path, a function to relocate it to a permanent path,
// and a function to clean up the temporary path that should always be deferred
// in the case of a failure to relocate.
Expand Down
31 changes: 31 additions & 0 deletions cmd/lk/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,34 @@ func TestMapStrings(t *testing.T) {
t.Error("mapStrings should apply the function to all elements")
}
}

func TestEllipziseTo(t *testing.T) {
str := "This is some long string that should be ellipsized"
ellipsized := ellipsizeTo(str, 12)
if len(ellipsized) != 12 {
t.Error("ellipsizeTo should return a string of the specified length")
}
if ellipsized != "This is s..." {
t.Error("ellipsizeTo should ellipsize the string")
}
}

func TestWrapToLines(t *testing.T) {
str := "This is a long string that should be wrapped to multiple lines"
wrapped := wrapToLines(str, 10)
if len(wrapped) != 8 {
t.Error("wrapToLines should return a slice of lines")
}
if !slices.Equal([]string{
"This is a",
"long",
"string",
"that",
"should be",
"wrapped to",
"multiple",
"lines",
}, wrapped) {
t.Error("wrapToLines should wrap the string to the specified width")
}
}
17 changes: 9 additions & 8 deletions pkg/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ var templateIgnoreFiles = []string{
}

type Template struct {
Name string `yaml:"name" json:"name"`
Desc string `yaml:"desc" json:"description,omitempty"`
URL string `yaml:"url" json:"url,omitempty"`
Docs string `yaml:"docs" json:"docs_url,omitempty"`
Image string `yaml:"image" json:"image_ref,omitempty"`
Tags []string `yaml:"tags" json:"tags,omitempty"`
Requires []string `yaml:"requires" json:"requires,omitempty"`
IsSandbox bool `yaml:"is_sandbox" json:"is_sandbox,omitempty"`
Name string `yaml:"name" json:"name"`
Desc string `yaml:"desc" json:"description,omitempty"`
URL string `yaml:"url" json:"url,omitempty"`
Docs string `yaml:"docs" json:"docs_url,omitempty"`
Image string `yaml:"image" json:"image_ref,omitempty"`
Tags []string `yaml:"tags" json:"tags,omitempty"`
Attrs map[string]string `yaml:"attrs" json:"attrs,omitempty"`
Requires []string `yaml:"requires" json:"requires,omitempty"`
IsSandbox bool `yaml:"is_sandbox" json:"is_sandbox,omitempty"`
}

type SandboxDetails struct {
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
package livekitcli

const (
Version = "2.2.1"
Version = "2.3.0"
)

0 comments on commit 20a1b8d

Please sign in to comment.