Skip to content

Commit 1fc8002

Browse files
Delta456maaslalani
andauthored
cmd: add support for ENV command (#469)
* cmd: start initial work on env key val * restore demo gif * restore * oops * add comments * readme: add env command instructions * Update command.go * Update README.md * Apply suggestions from code review * Update command.go * Update command.go --------- Co-authored-by: Maas Lalani <[email protected]>
1 parent ed69431 commit 1fc8002

File tree

6 files changed

+49
-2
lines changed

6 files changed

+49
-2
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ There are a few basic types of VHS commands:
221221
* [`Screenshot`](#screenshot): screenshot the current frame
222222
* [`Copy/Paste`](#copy--paste): copy and paste text from clipboard.
223223
* [`Source`](#source): source commands from another tape
224+
* [`Env <Key> Value`](#env): set environment variables
224225

225226
### Output
226227

@@ -738,6 +739,18 @@ Sleep 500ms
738739
Paste
739740
```
740741

742+
### Env
743+
744+
`Env` command sets the environment variable via key-value pair.
745+
746+
```elixir
747+
Env HELLO WORLD
748+
749+
Type "echo $HELLO"
750+
Enter
751+
Sleep 3s
752+
```
753+
741754

742755
### Source
743756

command.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ var CommandFuncs = map[parser.CommandType]CommandFunc{
6464
token.SCREENSHOT: ExecuteScreenshot,
6565
token.COPY: ExecuteCopy,
6666
token.PASTE: ExecutePaste,
67+
token.ENV: ExecuteEnv,
6768
}
6869

6970
// ExecuteNoop is a no-op command that does nothing.
@@ -248,6 +249,11 @@ func ExecuteCopy(c parser.Command, _ *VHS) {
248249
_ = clipboard.WriteAll(c.Args)
249250
}
250251

252+
// ExecuteEnv sets env with given key-value pair.
253+
func ExecuteEnv(c parser.Command, _ *VHS) {
254+
_ = os.Setenv(c.Options, c.Args)
255+
}
256+
251257
// ExecutePaste pastes text from the clipboard.
252258
func ExecutePaste(_ parser.Command, v *VHS) {
253259
clip, err := clipboard.ReadAll()

command_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import (
88
)
99

1010
func TestCommand(t *testing.T) {
11-
const numberOfCommands = 27
11+
const numberOfCommands = 28
1212
if len(parser.CommandTypes) != numberOfCommands {
1313
t.Errorf("Expected %d commands, got %d", numberOfCommands, len(parser.CommandTypes))
1414
}
1515

16-
const numberOfCommandFuncs = 27
16+
const numberOfCommandFuncs = 28
1717
if len(CommandFuncs) != numberOfCommandFuncs {
1818
t.Errorf("Expected %d commands, got %d", numberOfCommandFuncs, len(CommandFuncs))
1919
}

evaluator.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ func Evaluate(ctx context.Context, tape string, out io.Writer, opts ...Evaluator
3232
if cmd.Type == token.SET && cmd.Options == "Shell" {
3333
Execute(cmd, &v)
3434
}
35+
if cmd.Type == token.ENV {
36+
Execute(cmd, &v)
37+
}
3538
}
3639

3740
// Start things up

parser/parser.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var CommandTypes = []CommandType{ //nolint: deadcode
5151
token.SCREENSHOT,
5252
token.COPY,
5353
token.PASTE,
54+
token.ENV,
5455
}
5556

5657
// String returns the string representation of the command.
@@ -177,6 +178,8 @@ func (p *Parser) parseCommand() Command {
177178
return p.parseCopy()
178179
case token.PASTE:
179180
return p.parsePaste()
181+
case token.ENV:
182+
return p.parseEnv()
180183
default:
181184
p.errors = append(p.errors, NewError(p.cur, "Invalid command: "+p.cur.Literal))
182185
return Command{Type: token.ILLEGAL}
@@ -577,6 +580,26 @@ func (p *Parser) parsePaste() Command {
577580
return cmd
578581
}
579582

583+
// parseEnv parses Env command
584+
// Env command takes in a key-value pair which is set.
585+
//
586+
// Env key "value"
587+
func (p *Parser) parseEnv() Command {
588+
cmd := Command{Type: token.ENV}
589+
590+
cmd.Options = p.peek.Literal
591+
p.nextToken()
592+
593+
if p.peek.Type != token.STRING {
594+
p.errors = append(p.errors, NewError(p.peek, p.cur.Literal+" expects string"))
595+
}
596+
597+
cmd.Args = p.peek.Literal
598+
p.nextToken()
599+
600+
return cmd
601+
}
602+
580603
// parseSource parses source command.
581604
// Source command takes a tape path to include in current tape.
582605
//

token/token.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ const (
7272
COPY = "COPY"
7373
PASTE = "PASTE"
7474
SHELL = "SHELL"
75+
ENV = "ENV"
7576
FONT_FAMILY = "FONT_FAMILY" //nolint:revive
7677
FONT_SIZE = "FONT_SIZE" //nolint:revive
7778
FRAMERATE = "FRAMERATE"
@@ -148,6 +149,7 @@ var Keywords = map[string]Type{
148149
"Screenshot": SCREENSHOT,
149150
"Copy": COPY,
150151
"Paste": PASTE,
152+
"Env": ENV,
151153
}
152154

153155
// IsSetting returns whether a token is a setting.

0 commit comments

Comments
 (0)