Skip to content

Commit b18f90e

Browse files
authored
feat(cmd): expand project env from anywhere (#475)
1 parent 20a1b8d commit b18f90e

File tree

2 files changed

+49
-44
lines changed

2 files changed

+49
-44
lines changed

cmd/lk/app.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ var (
102102
},
103103
{
104104
Name: "env",
105-
Usage: "Print project environment variables expanded from a .env.example file",
105+
Usage: "Expand environment variables from the current project, and if present, the .env.example file",
106106
Flags: []cli.Flag{
107107
&cli.BoolFlag{
108108
Name: "w",
@@ -112,22 +112,7 @@ var (
112112
},
113113
ArgsUsage: "[DIR] location of the project directory (default: current directory)",
114114
Before: requireProject,
115-
Action: func(ctx context.Context, cmd *cli.Command) error {
116-
rootDir := cmd.Args().First()
117-
if rootDir == "" {
118-
rootDir = "."
119-
}
120-
121-
env, err := instantiateEnv(ctx, cmd, rootDir, nil)
122-
if err != nil {
123-
return err
124-
}
125-
if cmd.Bool("write") {
126-
return bootstrap.WriteDotEnv(rootDir, env)
127-
} else {
128-
return bootstrap.PrintDotEnv(env)
129-
}
130-
},
115+
Action: manageEnv,
131116
},
132117
},
133118
},
@@ -363,6 +348,24 @@ func cleanupTemplate(ctx context.Context, cmd *cli.Command, appName string) erro
363348
return bootstrap.CleanupTemplate(appName)
364349
}
365350

351+
func manageEnv(ctx context.Context, cmd *cli.Command) error {
352+
rootDir := cmd.Args().First()
353+
if rootDir == "" {
354+
rootDir = "."
355+
}
356+
357+
env, err := instantiateEnv(ctx, cmd, rootDir, nil)
358+
if err != nil {
359+
return err
360+
}
361+
362+
if cmd.Bool("write") {
363+
return bootstrap.WriteDotEnv(rootDir, env)
364+
} else {
365+
return bootstrap.PrintDotEnv(env)
366+
}
367+
}
368+
366369
func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string) (map[string]string, error) {
367370
env := map[string]string{
368371
"LIVEKIT_API_KEY": project.APIKey,

pkg/bootstrap/bootstrap.go

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -192,40 +192,42 @@ type PromptFunc func(key string, value string) (string, error)
192192
// prompting for others, and returning the result as a map.
193193
func InstantiateDotEnv(ctx context.Context, rootDir string, substitutions map[string]string, verbose bool, prompt PromptFunc) (map[string]string, error) {
194194
promptedVars := map[string]string{}
195-
196195
envExamplePath := path.Join(rootDir, EnvExampleFile)
196+
197197
stat, err := os.Stat(envExamplePath)
198-
if err != nil {
198+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
199199
return nil, err
200-
}
201-
if stat.IsDir() {
202-
return nil, errors.New("env.example file is a directory")
203-
}
200+
} else if stat != nil {
201+
if stat.IsDir() {
202+
return nil, errors.New("env.example file is a directory")
203+
}
204204

205-
envMap, err := godotenv.Read(envExamplePath)
206-
if err != nil {
207-
return nil, err
208-
}
205+
envMap, err := godotenv.Read(envExamplePath)
206+
if err != nil {
207+
return nil, err
208+
}
209209

210-
for key, oldValue := range envMap {
211-
// if key is a substitution, replace it
212-
if value, ok := substitutions[key]; ok {
213-
envMap[key] = value
214-
// if key was already promped, use that value
215-
} else if alreadyPromptedValue, ok := promptedVars[key]; ok {
216-
envMap[key] = alreadyPromptedValue
217-
} else {
218-
// prompt for value
219-
newValue, err := prompt(key, oldValue)
220-
if err != nil {
221-
return nil, err
210+
for key, oldValue := range envMap {
211+
// if key is a substitution, replace it
212+
if value, ok := substitutions[key]; ok {
213+
envMap[key] = value
214+
// if key was already promped, use that value
215+
} else if alreadyPromptedValue, ok := promptedVars[key]; ok {
216+
envMap[key] = alreadyPromptedValue
217+
} else {
218+
// prompt for value
219+
newValue, err := prompt(key, oldValue)
220+
if err != nil {
221+
return nil, err
222+
}
223+
envMap[key] = newValue
224+
promptedVars[key] = newValue
222225
}
223-
envMap[key] = newValue
224-
promptedVars[key] = newValue
225226
}
227+
return envMap, nil
228+
} else {
229+
return substitutions, nil
226230
}
227-
228-
return envMap, nil
229231
}
230232

231233
func PrintDotEnv(envMap map[string]string) error {
@@ -243,7 +245,7 @@ func WriteDotEnv(rootDir string, envMap map[string]string) error {
243245
return err
244246
}
245247
envLocalPath := path.Join(rootDir, EnvLocalFile)
246-
return os.WriteFile(envLocalPath, []byte(envContents), 0700)
248+
return os.WriteFile(envLocalPath, []byte(envContents+"\n"), 0700)
247249
}
248250

249251
func CloneTemplate(url, dir string) (string, string, error) {

0 commit comments

Comments
 (0)