Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 59 additions & 18 deletions cmd/lk/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ import (
)

var (
template *bootstrap.Template
templateName string
templateURL string
sandboxID string
appName string
appNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]*$`)
project *config.ProjectConfig
AppCommands = []*cli.Command{
template *bootstrap.Template
templateName string
templateURL string
sandboxID string
appName string
appNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]*$`)
outputFile string
exampleFile string
skipLiveKitKeys bool
project *config.ProjectConfig
AppCommands = []*cli.Command{
{
Name: "app",
Category: "Core",
Expand Down Expand Up @@ -109,6 +112,24 @@ var (
Aliases: []string{"write"},
Usage: "Write environment variables to .env.local file",
},
&cli.StringFlag{
Name: "output",
Usage: "Specify a custom file name for the environment variables file",
Value: ".env.local",
Destination: &outputFile,
},
&cli.StringFlag{
Name: "example",
Usage: "Specify a custom file name for the environment variables template file",
Value: ".env.example",
Destination: &exampleFile,
},
&cli.BoolFlag{
Name: "skip-livekit-keys",
Usage: "Don't add LiveKit API keys to the environment",
Value: false,
Destination: &skipLiveKitKeys,
},
},
ArgsUsage: "[DIR] location of the project directory (default: current directory)",
Before: requireProject,
Expand Down Expand Up @@ -291,13 +312,28 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error {
return err
}

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

fmt.Println("Instantiating environment...")
addlEnv := &map[string]string{"LIVEKIT_SANDBOX_ID": sandboxID}
env, err := instantiateEnv(ctx, cmd, appName, addlEnv)
envOutputFile := ".env.local"
if customOutput, ok := tf.Vars.Get("env_file").Value.(string); ok {
envOutputFile = customOutput
}
envExampleFile := ".env.example"
if customExample, ok := tf.Vars.Get("env_example").Value.(string); ok {
envExampleFile = customExample
}
skipLiveKitKeys := tf.Vars.Get("env_no_livekit_keys").Value.(bool)
env, err := instantiateEnv(ctx, cmd, appName, addlEnv, envExampleFile, skipLiveKitKeys)
if err != nil {
return err
}
bootstrap.WriteDotEnv(appName, env)

bootstrap.WriteDotEnv(appName, envOutputFile, env)

if install {
fmt.Println("Installing template...")
Expand Down Expand Up @@ -354,24 +390,29 @@ func manageEnv(ctx context.Context, cmd *cli.Command) error {
rootDir = "."
}

env, err := instantiateEnv(ctx, cmd, rootDir, nil)
env, err := instantiateEnv(ctx, cmd, rootDir, nil, exampleFile, skipLiveKitKeys)
if err != nil {
return err
}

if cmd.Bool("write") {
return bootstrap.WriteDotEnv(rootDir, env)
return bootstrap.WriteDotEnv(rootDir, outputFile, env)
} else {
return bootstrap.PrintDotEnv(env)
}
}

func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string) (map[string]string, error) {
env := map[string]string{
"LIVEKIT_API_KEY": project.APIKey,
"LIVEKIT_API_SECRET": project.APISecret,
"LIVEKIT_URL": project.URL,
func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string, exampleFile string, skipLiveKitKeys bool) (map[string]string, error) {
env := map[string]string{}

if !skipLiveKitKeys {
env = map[string]string{
"LIVEKIT_API_KEY": project.APIKey,
"LIVEKIT_API_SECRET": project.APISecret,
"LIVEKIT_URL": project.URL,
}
}

if addlEnv != nil {
for k, v := range *addlEnv {
env[k] = v
Expand All @@ -392,7 +433,7 @@ func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addl
return newValue, nil
}

return bootstrap.InstantiateDotEnv(ctx, rootPath, env, cmd.Bool("verbose"), prompt)
return bootstrap.InstantiateDotEnv(ctx, rootPath, exampleFile, env, cmd.Bool("verbose"), prompt)
}

func installTemplate(ctx context.Context, cmd *cli.Command) error {
Expand Down
12 changes: 5 additions & 7 deletions pkg/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import (
)

const (
EnvExampleFile = ".env.example"
EnvLocalFile = ".env.local"
TaskFile = "taskfile.yaml"
TemplateIndexFile = "templates.yaml"
TemplateIndexURL = "https://raw.githubusercontent.com/livekit-examples/index/main"
Expand Down Expand Up @@ -190,16 +188,16 @@ type PromptFunc func(key string, value string) (string, error)

// Read .env.example file if present in rootDir, replacing all `substitutions`,
// prompting for others, and returning the result as a map.
func InstantiateDotEnv(ctx context.Context, rootDir string, substitutions map[string]string, verbose bool, prompt PromptFunc) (map[string]string, error) {
func InstantiateDotEnv(ctx context.Context, rootDir string, exampleFilePath string, substitutions map[string]string, verbose bool, prompt PromptFunc) (map[string]string, error) {
promptedVars := map[string]string{}
envExamplePath := path.Join(rootDir, EnvExampleFile)
envExamplePath := path.Join(rootDir, exampleFilePath)

stat, err := os.Stat(envExamplePath)
if err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
} else if stat != nil {
if stat.IsDir() {
return nil, errors.New("env.example file is a directory")
return nil, errors.New(".env.example file is a directory")
}

envMap, err := godotenv.Read(envExamplePath)
Expand Down Expand Up @@ -239,12 +237,12 @@ func PrintDotEnv(envMap map[string]string) error {
return err
}

func WriteDotEnv(rootDir string, envMap map[string]string) error {
func WriteDotEnv(rootDir string, filePath string, envMap map[string]string) error {
envContents, err := godotenv.Marshal(envMap)
if err != nil {
return err
}
envLocalPath := path.Join(rootDir, EnvLocalFile)
envLocalPath := path.Join(rootDir, filePath)
return os.WriteFile(envLocalPath, []byte(envContents+"\n"), 0700)
}

Expand Down
Loading