Skip to content

Commit 9160bcc

Browse files
committed
refactor: set command shell environment variables from hook options
1 parent 2324d5f commit 9160bcc

3 files changed

Lines changed: 45 additions & 69 deletions

File tree

internal/hooks/hooks.go

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ package hooks
1616

1717
import (
1818
"context"
19-
"os"
2019
"strings"
2120

2221
"github.com/slackapi/slack-cli/internal/goutils"
2322
"github.com/slackapi/slack-cli/internal/iostreams"
24-
"github.com/slackapi/slack-cli/internal/slackdotenv"
2523
"github.com/spf13/afero"
2624
)
2725

@@ -57,39 +55,7 @@ func processExecOpts(ctx context.Context, opts HookExecOpts, fs afero.Fs, io ios
5755
var cmdArgVars = cmdArgs[1:] // omit the first item because that is the command name
5856
cmdArgVars = append(cmdArgVars, goutils.MapToStringSlice(opts.Args, "--")...)
5957

60-
// Load .env file variables
61-
dotEnv, err := slackdotenv.Read(fs)
62-
if err != nil {
63-
io.PrintDebug(ctx, "Warning: failed to parse .env file: %s", err)
64-
}
65-
if len(dotEnv) > 0 {
66-
keys := make([]string, 0, len(dotEnv))
67-
for k := range dotEnv {
68-
keys = append(keys, k)
69-
}
70-
io.PrintDebug(ctx, "loaded variables from .env file: %s", strings.Join(keys, ", "))
71-
}
72-
73-
// Whatever cmd.Env is set to will be the ONLY environment variables that the `cmd` will have access to when it runs.
74-
//
75-
// Order of precedence from lowest to highest:
76-
// 1. Provided "opts.Env" variables
77-
// 2. Saved ".env" file
78-
// 3. Existing shell environment
79-
//
80-
// > Each entry is of the form "key=value".
81-
// > ...
82-
// > If Env contains duplicate environment keys, only the last value in the slice for each duplicate key is used.
83-
//
84-
// https://pkg.go.dev/os/exec#Cmd.Env
85-
var cmdEnvVars []string
86-
for name, value := range opts.Env {
87-
cmdEnvVars = append(cmdEnvVars, name+"="+value)
88-
}
89-
for k, v := range dotEnv {
90-
cmdEnvVars = append(cmdEnvVars, k+"="+v)
91-
}
92-
cmdEnvVars = append(cmdEnvVars, os.Environ()...)
58+
cmdEnvVars := opts.ShellEnv(ctx, fs, io)
9359

9460
return cmdArgs, cmdArgVars, cmdEnvVars, nil
9561
}

internal/hooks/shell.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
package hooks
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"io"
2021
"os"
2122
"os/exec"
2223
"runtime"
2324
"strings"
25+
26+
"github.com/slackapi/slack-cli/internal/iostreams"
27+
"github.com/slackapi/slack-cli/internal/slackdotenv"
28+
"github.com/spf13/afero"
2429
)
2530

2631
// ExecInterface is an interface for running shell commands in the OS
@@ -92,3 +97,41 @@ type HookExecOpts struct {
9297
Stderr io.Writer
9398
Exec ExecInterface
9499
}
100+
101+
// ShellEnv builds the environment variables for a hook command.
102+
func (opts HookExecOpts) ShellEnv(ctx context.Context, fs afero.Fs, io iostreams.IOStreamer) []string {
103+
// Gather environment variables saved to the project ".env" file
104+
dotEnv, err := slackdotenv.Read(fs)
105+
if err != nil {
106+
io.PrintDebug(ctx, "Warning: failed to parse .env file: %s", err)
107+
}
108+
if len(dotEnv) > 0 {
109+
keys := make([]string, 0, len(dotEnv))
110+
for k := range dotEnv {
111+
keys = append(keys, k)
112+
}
113+
io.PrintDebug(ctx, "Loaded variables from .env file: %s", strings.Join(keys, ", "))
114+
}
115+
116+
// Whatever cmd.Env is set to will be the ONLY environment variables that the `cmd` will have access to when it runs.
117+
//
118+
// Order of precedence from lowest to highest:
119+
// 1. Provided "opts.Env" variables
120+
// 2. Saved ".env" file
121+
// 3. Existing shell environment
122+
//
123+
// > Each entry is of the form "key=value".
124+
// > ...
125+
// > If Env contains duplicate environment keys, only the last value in the slice for each duplicate key is used.
126+
//
127+
// https://pkg.go.dev/os/exec#Cmd.Env
128+
var cmdEnvVars []string
129+
for name, value := range opts.Env {
130+
cmdEnvVars = append(cmdEnvVars, name+"="+value)
131+
}
132+
for k, v := range dotEnv {
133+
cmdEnvVars = append(cmdEnvVars, k+"="+v)
134+
}
135+
cmdEnvVars = append(cmdEnvVars, os.Environ()...)
136+
return cmdEnvVars
137+
}

internal/pkg/platform/localserver.go

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"github.com/slackapi/slack-cli/internal/pkg/apps"
3636
"github.com/slackapi/slack-cli/internal/shared"
3737
"github.com/slackapi/slack-cli/internal/shared/types"
38-
"github.com/slackapi/slack-cli/internal/slackdotenv"
3938
"github.com/slackapi/slack-cli/internal/slackerror"
4039
"github.com/slackapi/slack-cli/internal/slacktrace"
4140
"github.com/slackapi/slack-cli/internal/style"
@@ -309,39 +308,7 @@ func (r *LocalServer) StartDelegate(ctx context.Context) error {
309308
cmdArgs := strings.Fields(cmdStr)
310309
var cmdArgVars = cmdArgs[1:] // omit the first item because that is the command name
311310

312-
// Load .env file variables
313-
dotEnv, err := slackdotenv.Read(r.clients.Fs)
314-
if err != nil {
315-
r.clients.IO.PrintDebug(ctx, "Warning: failed to parse .env file: %s", err)
316-
}
317-
if len(dotEnv) > 0 {
318-
keys := make([]string, 0, len(dotEnv))
319-
for k := range dotEnv {
320-
keys = append(keys, k)
321-
}
322-
r.clients.IO.PrintDebug(ctx, "Loaded variables from .env file: %s", strings.Join(keys, ", "))
323-
}
324-
325-
// Whatever cmd.Env is set to will be the ONLY environment variables that the `cmd` will have access to when it runs.
326-
//
327-
// Order of precedence from lowest to highest:
328-
// 1. Provided "opts.Env" variables
329-
// 2. Saved ".env" file
330-
// 3. Existing shell environment
331-
//
332-
// > Each entry is of the form "key=value".
333-
// > ...
334-
// > If Env contains duplicate environment keys, only the last value in the slice for each duplicate key is used.
335-
//
336-
// https://pkg.go.dev/os/exec#Cmd.Env
337-
var cmdEnvVars []string
338-
for k, v := range sdkManagedConnectionStartHookOpts.Env {
339-
cmdEnvVars = append(cmdEnvVars, k+"="+v)
340-
}
341-
for k, v := range dotEnv {
342-
cmdEnvVars = append(cmdEnvVars, k+"="+v)
343-
}
344-
cmdEnvVars = append(cmdEnvVars, os.Environ()...)
311+
cmdEnvVars := sdkManagedConnectionStartHookOpts.ShellEnv(ctx, r.clients.Fs, r.clients.IO)
345312
cmd := sdkManagedConnectionStartHookOpts.Exec.Command(cmdEnvVars, os.Stdout, os.Stderr, nil, cmdArgs[0], cmdArgVars...)
346313

347314
// Store command reference for lifecycle management

0 commit comments

Comments
 (0)