Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testscript: add env convenience functions #96

Merged
merged 1 commit into from May 6, 2020

Conversation

twpayne
Copy link
Contributor

@twpayne twpayne commented May 4, 2020

Manipulating Env.Vars is not completely trivial: you need to handle last-entry-wins, invalid entries, and key normalization.

This PR adds Getenv, LookupEnv, and Setenv method to Env that function identically to their counterparts in the standard os package.

Example use:

func TestFoo(t *testing.T) {
	testscript.Run(t, testscript.Params{
		Dir: "testdata",
		Setup: func(e *Env) error {
			e.Setenv("HOME", "/home/user")
			e.Setenv("PATH", "/home/user/bin:" + e.Getenv("PATH"))
		},
	})
}

Copy link
Owner

@rogpeppe rogpeppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice idea, thanks, but I think the API could be a little tighter here.

// If the variable is present in the environment the value (which may be empty)
// is returned and the boolean is true. Otherwise the returned value will be
// empty and the boolean will be false.
func (e *Env) LookupEnv(key string) (value string, found bool) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering about the use case for these methods. In general we're not working with an arbitrary set of environment variables here. I don't really see the use case for LookupEnv - it didn't even exist in the standard library for ages. How about just providing Getenv and Setenv?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// empty and the boolean will be false.
func (e *Env) LookupEnv(key string) (value string, found bool) {
key = envvarname(key)
for _, v := range e.Vars {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about iterating in reverse just to make things a bit clearer?

    for i := len(e.Vars)-1; i >= 0; i-- {
          if pair := strings.SplitN(v, "=", 2); len(pair) == 2 && envvarname(pair[0]) == key {
               return pair[1]
         }
    }
    return ""

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// Setenv sets the value of the environment variable named by the key. It
// returns an error, if any.
func (e *Env) Setenv(key, value string) error {
if key == "" || strings.IndexByte(key, '=') != -1 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't the os package. I'd suggest just panicking in this case, which avoids the need to decide what kind of error to return here (I'm not that keen on the syscall import).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@twpayne
Copy link
Contributor Author

twpayne commented May 5, 2020

Thanks for the review. All comments addressed and PR updated.

@twpayne twpayne force-pushed the testscript-env branch 2 times, most recently from 2141521 to 1137e5e Compare May 5, 2020 15:04
Manipulating Env.Vars is not completely trivial: you need to handle
last-entry-wins, invalid entries, and key normalization.

This commit adds Getenv and Setenv method to Env that function
identically to their counterparts in the standard os package.
Copy link
Owner

@rogpeppe rogpeppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants