Skip to content

Commit 4a41071

Browse files
authored
Allow custom env file paths (#482)
* Allow custom env file path, omitting api keys * cleanup * feedback * fix * line * nil taskfile
1 parent e43e371 commit 4a41071

File tree

2 files changed

+57
-25
lines changed

2 files changed

+57
-25
lines changed

cmd/lk/app.go

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ import (
3131
)
3232

3333
var (
34-
template *bootstrap.Template
35-
templateName string
36-
templateURL string
37-
sandboxID string
38-
appName string
39-
appNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]*$`)
40-
project *config.ProjectConfig
41-
AppCommands = []*cli.Command{
34+
template *bootstrap.Template
35+
templateName string
36+
templateURL string
37+
sandboxID string
38+
appName string
39+
appNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]*$`)
40+
destinationFile string
41+
exampleFile string
42+
project *config.ProjectConfig
43+
AppCommands = []*cli.Command{
4244
{
4345
Name: "app",
4446
Usage: "Initialize and manage applications",
@@ -102,12 +104,28 @@ var (
102104
},
103105
{
104106
Name: "env",
105-
Usage: "Expand environment variables from the current project, and if present, the .env.example file",
107+
Usage: "Fill environment variables based on .env.example (optional) and project credentials",
106108
Flags: []cli.Flag{
107109
&cli.BoolFlag{
108-
Name: "w",
109-
Aliases: []string{"write"},
110-
Usage: "Write environment variables to .env.local file",
110+
Name: "write",
111+
Aliases: []string{"w"},
112+
Usage: "Write environment variables to file",
113+
},
114+
&cli.StringFlag{
115+
Name: "destination",
116+
Aliases: []string{"d"},
117+
Usage: "Destination file path, when used with --write",
118+
Value: ".env.local",
119+
TakesFile: true,
120+
Destination: &destinationFile,
121+
},
122+
&cli.StringFlag{
123+
Name: "example",
124+
Aliases: []string{"e"},
125+
Usage: "Example file path",
126+
Value: ".env.example",
127+
TakesFile: true,
128+
Destination: &exampleFile,
111129
},
112130
},
113131
ArgsUsage: "[DIR] location of the project directory (default: current directory)",
@@ -291,16 +309,32 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error {
291309
return err
292310
}
293311

312+
tf, err := bootstrap.ParseTaskfile(appName)
313+
if err != nil {
314+
return err
315+
}
316+
294317
fmt.Println("Instantiating environment...")
295318
addlEnv := &map[string]string{
296319
"LIVEKIT_SANDBOX_ID": sandboxID,
297320
"NEXT_PUBLIC_LIVEKIT_SANDBOX_ID": sandboxID,
298321
}
299-
env, err := instantiateEnv(ctx, cmd, appName, addlEnv)
322+
envOutputFile := ".env.local"
323+
envExampleFile := ".env.example"
324+
if tf != nil {
325+
if customOutput, ok := tf.Vars.Get("env_file").Value.(string); ok {
326+
envOutputFile = customOutput
327+
}
328+
if customExample, ok := tf.Vars.Get("env_example").Value.(string); ok {
329+
envExampleFile = customExample
330+
}
331+
}
332+
env, err := instantiateEnv(ctx, cmd, appName, addlEnv, envExampleFile)
300333
if err != nil {
301334
return err
302335
}
303-
bootstrap.WriteDotEnv(appName, env)
336+
337+
bootstrap.WriteDotEnv(appName, envOutputFile, env)
304338

305339
if install {
306340
fmt.Println("Installing template...")
@@ -357,19 +391,19 @@ func manageEnv(ctx context.Context, cmd *cli.Command) error {
357391
rootDir = "."
358392
}
359393

360-
env, err := instantiateEnv(ctx, cmd, rootDir, nil)
394+
env, err := instantiateEnv(ctx, cmd, rootDir, nil, exampleFile)
361395
if err != nil {
362396
return err
363397
}
364398

365399
if cmd.Bool("write") {
366-
return bootstrap.WriteDotEnv(rootDir, env)
400+
return bootstrap.WriteDotEnv(rootDir, destinationFile, env)
367401
} else {
368402
return bootstrap.PrintDotEnv(env)
369403
}
370404
}
371405

372-
func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string) (map[string]string, error) {
406+
func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string, exampleFile string) (map[string]string, error) {
373407
env := map[string]string{
374408
"LIVEKIT_API_KEY": project.APIKey,
375409
"LIVEKIT_API_SECRET": project.APISecret,
@@ -396,7 +430,7 @@ func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addl
396430
return newValue, nil
397431
}
398432

399-
return bootstrap.InstantiateDotEnv(ctx, rootPath, env, cmd.Bool("verbose"), prompt)
433+
return bootstrap.InstantiateDotEnv(ctx, rootPath, exampleFile, env, cmd.Bool("verbose"), prompt)
400434
}
401435

402436
func installTemplate(ctx context.Context, cmd *cli.Command) error {

pkg/bootstrap/bootstrap.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ import (
4040
)
4141

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

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

197195
stat, err := os.Stat(envExamplePath)
198196
if err != nil && !errors.Is(err, fs.ErrNotExist) {
199197
return nil, err
200198
} else if stat != nil {
201199
if stat.IsDir() {
202-
return nil, errors.New("env.example file is a directory")
200+
return nil, errors.New(".env.example file is a directory")
203201
}
204202

205203
envMap, err := godotenv.Read(envExamplePath)
@@ -239,12 +237,12 @@ func PrintDotEnv(envMap map[string]string) error {
239237
return err
240238
}
241239

242-
func WriteDotEnv(rootDir string, envMap map[string]string) error {
240+
func WriteDotEnv(rootDir string, filePath string, envMap map[string]string) error {
243241
envContents, err := godotenv.Marshal(envMap)
244242
if err != nil {
245243
return err
246244
}
247-
envLocalPath := path.Join(rootDir, EnvLocalFile)
245+
envLocalPath := path.Join(rootDir, filePath)
248246
return os.WriteFile(envLocalPath, []byte(envContents+"\n"), 0700)
249247
}
250248

0 commit comments

Comments
 (0)