ref: Replace x/devtools/internal/envutil with x/lib/envvar
A while ago I wrote envutil in the devtools repo, to make it
easier to deal with environment variables, and to make it easy
for the v23 tool to keep track of the mutations it had made.
Later on I noticed that there was similar code in x/ref in a few
places.
This CL removes envutil, and adds a new package envvar that may
be used by all other packages. It behaves similarly to envutil,
and also to the code scattered around x/ref.
In a subsequent CL I'll add cmdline support for environment
variables using envvar.
MultiPart: 2/2
Change-Id: Idd5c06ab79badf678cd5ce7e87493c04ea16204a
diff --git a/lib/exec/consts.go b/lib/exec/consts.go
index f275d78..54bb5ae 100644
--- a/lib/exec/consts.go
+++ b/lib/exec/consts.go
@@ -12,3 +12,21 @@
// of environment variables; exposing the name of this variable is intended to
// support such situations.
const ExecVersionVariable = "V23_EXEC_VERSION"
+
+const (
+ version1 = "1.0.0"
+ readyStatus = "ready::"
+ failedStatus = "failed::"
+ initStatus = "init"
+
+ // eofChar is written onto the status pipe to signal end-of-file. It
+ // should be the last byte written onto the pipe, before closing it.
+ // This signals to the reader that no more input is coming. This is
+ // needed since we cannot use the closing of the write end of the pipe
+ // to send io.EOF to the reader: since there are two write ends (one in
+ // the parent and one in the child), closing any one of the two is not
+ // going to send io.EOF to the reader.
+ // Since the data coming from the child should be valid utf-8, we pick
+ // one of the invalid utf-8 bytes for this.
+ eofChar = 0xFF
+)
diff --git a/lib/exec/parent.go b/lib/exec/parent.go
index e8747a1..230e5d0 100644
--- a/lib/exec/parent.go
+++ b/lib/exec/parent.go
@@ -18,9 +18,8 @@
"time"
"v.io/v23/verror"
-
+ "v.io/x/lib/envvar"
"v.io/x/lib/vlog"
-
"v.io/x/ref/lib/timekeeper"
)
@@ -126,22 +125,16 @@
// Start starts the child process, sharing a secret with it and
// setting up a communication channel over which to read its status.
func (p *ParentHandle) Start() error {
- // Make sure that there are no instances of the ExecVersionVariable
- // already in the environment (which can happen when a subprocess
- // creates a subprocess etc)
- nenv := make([]string, 0, len(p.c.Env)+1)
- for _, e := range p.c.Env {
- if strings.HasPrefix(e, ExecVersionVariable+"=") {
- continue
- }
- nenv = append(nenv, e)
- }
-
+ env := envvar.SliceToMap(p.c.Env)
if !p.protocol {
+ // Ensure ExecVersionVariable is not set if we're not using the protocol.
+ delete(env, ExecVersionVariable)
+ p.c.Env = envvar.MapToSlice(env)
return p.c.Start()
}
-
- p.c.Env = append(nenv, ExecVersionVariable+"="+version1)
+ // Ensure ExecVersionVariable is always set if we are using the protocol.
+ env[ExecVersionVariable] = version1
+ p.c.Env = envvar.MapToSlice(env)
// Create anonymous pipe for communicating data between the child
// and the parent.
diff --git a/lib/exec/shared.go b/lib/exec/shared.go
deleted file mode 100644
index 2baf026..0000000
--- a/lib/exec/shared.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package exec
-
-const (
- version1 = "1.0.0"
- readyStatus = "ready::"
- failedStatus = "failed::"
- initStatus = "init"
-
- // eofChar is written onto the status pipe to signal end-of-file. It
- // should be the last byte written onto the pipe, before closing it.
- // This signals to the reader that no more input is coming. This is
- // needed since we cannot use the closing of the write end of the pipe
- // to send io.EOF to the reader: since there are two write ends (one in
- // the parent and one in the child), closing any one of the two is not
- // going to send io.EOF to the reader.
- // Since the data coming from the child should be valid utf-8, we pick
- // one of the invalid utf-8 bytes for this.
- eofChar = 0xFF
-)
diff --git a/lib/exec/util.go b/lib/exec/util.go
deleted file mode 100644
index 323097b..0000000
--- a/lib/exec/util.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package exec
-
-import (
- "strings"
-
- "v.io/v23/verror"
-)
-
-var (
- errNotFound = verror.Register(pkgPath+".errNotFound", verror.NoRetry, "{1:}{2:} not found{:_}")
-)
-
-// Getenv retrieves the value of the given variable from the given
-// slice of environment variable assignments.
-func Getenv(env []string, name string) (string, error) {
- for _, v := range env {
- if strings.HasPrefix(v, name+"=") {
- return strings.TrimPrefix(v, name+"="), nil
- }
- }
- return "", verror.New(errNotFound, nil)
-}
-
-// Setenv updates / adds the value assignment for the given variable
-// in the given slice of environment variable assigments.
-func Setenv(env []string, name, value string) []string {
- newValue := name + "=" + value
- for i, v := range env {
- if strings.HasPrefix(v, name+"=") {
- env[i] = newValue
- return env
- }
- }
- return append(env, newValue)
-}
-
-// Mergeenv merges the values for the variables contained in 'other' with the
-// values contained in 'base'. If a variable exists in both, the value in
-// 'other' takes precedence.
-func Mergeenv(base, other []string) []string {
- otherValues := make(map[string]string)
- otherUsed := make(map[string]bool)
- for _, v := range other {
- if parts := strings.SplitN(v, "=", 2); len(parts) == 2 {
- otherValues[parts[0]] = parts[1]
- }
- }
- for i, v := range base {
- if parts := strings.SplitN(v, "=", 2); len(parts) == 2 {
- if otherValue, ok := otherValues[parts[0]]; ok {
- base[i] = parts[0] + "=" + otherValue
- otherUsed[parts[0]] = true
- }
- }
- }
- for k, v := range otherValues {
- if !otherUsed[k] {
- base = append(base, k+"="+v)
- }
- }
- return base
-}
diff --git a/lib/exec/util_test.go b/lib/exec/util_test.go
deleted file mode 100644
index dd97eb0..0000000
--- a/lib/exec/util_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package exec
-
-import (
- "testing"
-)
-
-func TestEnv(t *testing.T) {
- env := make([]string, 0)
- env = Setenv(env, "NAME", "VALUE1")
- if expected, got := 1, len(env); expected != got {
- t.Fatalf("Unexpected length of environment variable slice: expected %d, got %d", expected, got)
- }
- if expected, got := "NAME=VALUE1", env[0]; expected != got {
- t.Fatalf("Unexpected element in the environment variable slice: expected %q, got %q", expected, got)
- }
- env = Setenv(env, "NAME", "VALUE2")
- if expected, got := 1, len(env); expected != got {
- t.Fatalf("Unexpected length of environment variable slice: expected %d, got %d", expected, got)
- }
- if expected, got := "NAME=VALUE2", env[0]; expected != got {
- t.Fatalf("Unexpected element in the environment variable slice: expected %q, got %q", expected, got)
- }
- value, err := Getenv(env, "NAME")
- if err != nil {
- t.Fatalf("Unexpected error when looking up environment variable value: %v", err)
- }
- if expected, got := "VALUE2", value; expected != got {
- t.Fatalf("Unexpected value of an environment variable: expected %q, got %q", expected, got)
- }
- value, err = Getenv(env, "NONAME")
- if err == nil {
- t.Fatalf("Expected error when looking up environment variable value, got none (value: %q)", value)
- }
-}
-
-func TestMerge(t *testing.T) {
- env := []string{"ANIMAL=GOPHER", "METAL=CHROMIUM"}
- env = Mergeenv(env, []string{"CAR=VEYRON", "METAL=VANADIUM"})
- if want, got := 3, len(env); want != got {
- t.Fatalf("Expected %d env vars, got %d instead", want, got)
- }
- for n, want := range map[string]string{
- "ANIMAL": "GOPHER",
- "CAR": "VEYRON",
- "METAL": "VANADIUM",
- } {
- if got, err := Getenv(env, n); err != nil {
- t.Fatalf("Expected a value when looking up %q, got none", n)
- } else if got != want {
- t.Fatalf("Unexpected value of environment variable %q: expected %q, got %q", n, want, got)
- }
- }
-}