Keep the mnemonic variables from the mnemonic command (closes #80)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The mnemonic command ran with the tool's whole environment, so a mnemonic set in KEYFUNC_MNEMONIC reached it, although the command is there to supply one of its own. It now gets the environment ssh and sftp already get, with KEYFUNC_MNEMONIC and KEYFUNC_MNEMONIC_COMMAND removed. The function that builds that environment moves from the ssh command group into internal/mnemonic, beside the two variable names, so all three programs use the one copy. The README says so. Model: opus-5-5
This commit is contained in:
@@ -63,6 +63,7 @@ func Read(ctx context.Context, command string) (string, error) {
|
||||
func run(ctx context.Context, command string) (string, error) {
|
||||
//nolint:gosec // running the user's own command is the point
|
||||
shell := exec.CommandContext(ctx, "sh", "-c", command)
|
||||
shell.Env = ChildEnv()
|
||||
|
||||
var complaint bytes.Buffer
|
||||
|
||||
@@ -83,6 +84,25 @@ func run(ctx context.Context, command string) (string, error) {
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
// ChildEnv is the tool's environment with the mnemonic variables taken
|
||||
// out, for the programs the tool starts: the mnemonic command, ssh and
|
||||
// sftp. The mnemonic, from either variable, never leaves the tool.
|
||||
func ChildEnv() []string {
|
||||
environ := os.Environ()
|
||||
kept := make([]string, 0, len(environ))
|
||||
|
||||
for _, entry := range environ {
|
||||
name, _, _ := strings.Cut(entry, "=")
|
||||
if name == Variable || name == CommandVariable {
|
||||
continue
|
||||
}
|
||||
|
||||
kept = append(kept, entry)
|
||||
}
|
||||
|
||||
return kept
|
||||
}
|
||||
|
||||
// ask prompts on the terminal with echo turned off.
|
||||
func ask() (string, error) {
|
||||
fd := int(os.Stdin.Fd())
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mnemonic_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -61,6 +63,31 @@ func TestTheMnemonicInTheEnvironmentComesLast(t *testing.T) {
|
||||
require.Equal(t, fromVariable, words)
|
||||
}
|
||||
|
||||
func TestTheMnemonicIsNotHandedToTheCommand(t *testing.T) {
|
||||
const marker = "KEYFUNC_TEST_MARKER"
|
||||
|
||||
t.Setenv(mnemonic.CommandVariable, prints(fromCommandVariable))
|
||||
t.Setenv(mnemonic.Variable, fromVariable)
|
||||
t.Setenv(marker, "reaches the command")
|
||||
|
||||
path := filepath.Join(t.TempDir(), "environment")
|
||||
|
||||
words, err := mnemonic.Read(
|
||||
t.Context(), "env > '"+path+"'; "+prints(example()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, example(), words)
|
||||
|
||||
//nolint:gosec // the path is a temporary file of the test's own
|
||||
content, err := os.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
environment := string(content)
|
||||
require.NotContains(t, environment, mnemonic.Variable+"=")
|
||||
require.NotContains(t, environment, mnemonic.CommandVariable+"=")
|
||||
require.Contains(t, environment, marker+"=")
|
||||
}
|
||||
|
||||
func TestAFailingCommandSaysWhatWentWrong(t *testing.T) {
|
||||
t.Setenv(mnemonic.CommandVariable, "")
|
||||
t.Setenv(mnemonic.Variable, "")
|
||||
|
||||
Reference in New Issue
Block a user