envo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/envo-install +18 -0
- data/bin/envo_gen_tmp_helper.rb +50 -0
- data/bin/envo_run +30 -0
- data/lib/envo.rb +45 -0
- data/lib/envo/cli/envo.bat +11 -0
- data/lib/envo/cli/envo.sh +6 -0
- data/lib/envo/cli/help.rb +20 -0
- data/lib/envo/cli/installer_bash.rb +131 -0
- data/lib/envo/cli/installer_win_cmd.rb +96 -0
- data/lib/envo/cli/runner.rb +129 -0
- data/lib/envo/cli_parser.rb +54 -0
- data/lib/envo/cmd_clean.rb +53 -0
- data/lib/envo/cmd_copy.rb +56 -0
- data/lib/envo/cmd_list.rb +50 -0
- data/lib/envo/cmd_list_add.rb +102 -0
- data/lib/envo/cmd_list_del.rb +78 -0
- data/lib/envo/cmd_path.rb +28 -0
- data/lib/envo/cmd_reset.rb +66 -0
- data/lib/envo/cmd_run.rb +68 -0
- data/lib/envo/cmd_set.rb +76 -0
- data/lib/envo/cmd_show.rb +82 -0
- data/lib/envo/cmd_swap.rb +49 -0
- data/lib/envo/cmd_unset.rb +45 -0
- data/lib/envo/context.rb +156 -0
- data/lib/envo/error.rb +7 -0
- data/lib/envo/host.rb +24 -0
- data/lib/envo/host_shell.rb +11 -0
- data/lib/envo/logger.rb +27 -0
- data/lib/envo/parse_result.rb +9 -0
- data/lib/envo/parsed_cmd.rb +10 -0
- data/lib/envo/script_parser.rb +58 -0
- data/lib/envo/shell/bash.rb +63 -0
- data/lib/envo/shell/win_cmd.rb +47 -0
- data/lib/envo/state.rb +71 -0
- data/lib/envo/val/list_val.rb +107 -0
- data/lib/envo/val/no_val.rb +35 -0
- data/lib/envo/val/path_list_val.rb +24 -0
- data/lib/envo/val/path_val.rb +41 -0
- data/lib/envo/val/string_val.rb +40 -0
- data/lib/envo/val/val_builder.rb +59 -0
- data/lib/envo/version.rb +4 -0
- metadata +89 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
module Envo
|
2
|
+
class CliParser
|
3
|
+
def self.opt?(opt)
|
4
|
+
opt =~ /^-/
|
5
|
+
end
|
6
|
+
def self.filter_opts_front(args)
|
7
|
+
front_opts = args.take_while { |a| opt?(a) }
|
8
|
+
args.shift(front_opts.size)
|
9
|
+
front_opts
|
10
|
+
end
|
11
|
+
def self.filter_opts_back(args)
|
12
|
+
back_opts = args.reverse.take_while { |a| opt?(a) }.reverse
|
13
|
+
args.pop(back_opts.size)
|
14
|
+
back_opts
|
15
|
+
end
|
16
|
+
def self.filter_opts(args)
|
17
|
+
filter_opts_front(args) + filter_opts_back(args)
|
18
|
+
end
|
19
|
+
def initialize(opts)
|
20
|
+
@known_cmds = {}
|
21
|
+
@known_opts = opts
|
22
|
+
end
|
23
|
+
def add_cmd(name, parse_func)
|
24
|
+
raise Envo::Error "cmd #{name} is already added to parser" if @known_cmds[name]
|
25
|
+
@known_cmds[name] = parse_func
|
26
|
+
end
|
27
|
+
def parse(argv)
|
28
|
+
result = ParseResult.new
|
29
|
+
cmd = nil
|
30
|
+
while !argv.empty?
|
31
|
+
arg = argv.shift
|
32
|
+
if CliParser.opt?(arg)
|
33
|
+
result.opts.merge! @known_opts.parse_cli(arg)
|
34
|
+
else
|
35
|
+
break cmd = arg
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
raise Envo::Error.new 'missing command' if !cmd
|
40
|
+
raise Envo::Error.new "unknown command '#{cmd}'" if !@known_cmds[cmd]
|
41
|
+
|
42
|
+
parsed_cmd = @known_cmds[cmd].(cmd, argv)
|
43
|
+
|
44
|
+
cmd_opts = {}
|
45
|
+
parsed_cmd.opts.each do |opt|
|
46
|
+
cmd_opts.merge! @known_opts.parse_cli(opt)
|
47
|
+
end
|
48
|
+
parsed_cmd.opts = cmd_opts
|
49
|
+
|
50
|
+
result.cmds << parsed_cmd
|
51
|
+
result
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdClean
|
3
|
+
Name = 'clean'
|
4
|
+
def self.register_help(help)
|
5
|
+
help.add_cmd "clean <name> ...", <<~EOF
|
6
|
+
cleans environent variables
|
7
|
+
unsets empty strings, non-existing paths, empty lists
|
8
|
+
removes duplicates from lists and non-existing paths from path lists
|
9
|
+
EOF
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.register_cli_parser(parser)
|
13
|
+
parser.add_cmd(Name, ->(cmd, args) { parse_cli(args) })
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register_script_parser(parser)
|
17
|
+
parser.add_cmd(Name, ->(cmd, tokens, opts) { parse_tokens(tokens, opts) })
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_cli(args)
|
21
|
+
opts = CliParser.filter_opts(args)
|
22
|
+
parse_tokens(args, opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_tokens(tokens, opts)
|
26
|
+
ParsedCmd.new(CmdClean.new(tokens), opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(names)
|
30
|
+
raise Error.new 'clean: no names provided' if names.empty?
|
31
|
+
@names = names
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :names, :show_names
|
35
|
+
|
36
|
+
def execute(ctx)
|
37
|
+
@names.each do |name|
|
38
|
+
ename = ctx.expand_name(name)
|
39
|
+
|
40
|
+
if ctx.raw?
|
41
|
+
val = ctx.raw_get(ename)
|
42
|
+
ctx.unset(ename) if val && val.empty?
|
43
|
+
else
|
44
|
+
val = ctx.smart_get(ename)
|
45
|
+
if val.type != :empty
|
46
|
+
val.clean!
|
47
|
+
ctx.smart_set(ename, val)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdCopy
|
3
|
+
Name = 'copy'
|
4
|
+
def self.register_help(help)
|
5
|
+
help.add_cmd 'copy <source-name> <target-name>', <<~EOF
|
6
|
+
copy value of source to target
|
7
|
+
shorthand: 'cp'
|
8
|
+
EOF
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register_cli_parser(parser)
|
12
|
+
parser.add_cmd(Name, ->(cmd, args) { parse_cli(args) })
|
13
|
+
parser.add_cmd('cp', ->(cmd, args) { parse_cli(args) })
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register_script_parser(parser)
|
17
|
+
parser.add_cmd(Name, ->(cmd, tokens, opts) { parse_tokens(tokens, opts) })
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_cli(args)
|
21
|
+
opts = CliParser.filter_opts(args)
|
22
|
+
parse_tokens(args, opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_tokens(tokens, opts)
|
26
|
+
raise Envo::Error.new "copy: provide two names to copy. Use 'copy <source-name> <target-name>'" if tokens.size != 2
|
27
|
+
ParsedCmd.new(CmdCopy.new(tokens[0], tokens[1]), opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(source, target)
|
31
|
+
@source = source
|
32
|
+
@target = target
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :source, :target
|
36
|
+
|
37
|
+
def execute(ctx)
|
38
|
+
esrc = ctx.expand_name(@source)
|
39
|
+
raw_src = ctx.raw_get(esrc)
|
40
|
+
raise Envo::Error.new "copy: no such var '#{esrc}'" if !raw_src && !ctx.force?
|
41
|
+
return if !raw_src
|
42
|
+
|
43
|
+
etarget = ctx.expand_name(@target)
|
44
|
+
raw_target = ctx.raw_get(etarget)
|
45
|
+
|
46
|
+
ok = !raw_target
|
47
|
+
ok ||= ctx.ask("'#{etarget}' already exists. Overwrite?")
|
48
|
+
raise Envo::Error.new "'#{etarget}' exists" if !ok
|
49
|
+
|
50
|
+
return if esrc == etarget # copy something over itself...
|
51
|
+
return if !raw_src && !raw_target # no point in doing anything if they don't exist
|
52
|
+
|
53
|
+
ctx.raw_set(etarget, raw_src)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdList
|
3
|
+
Name = 'list'
|
4
|
+
def self.register_help(help)
|
5
|
+
help.add_cmd "list <name>", "show value of list environment variable which is a list"
|
6
|
+
help.add_cmd "list <name> add <val>", <<~EOF
|
7
|
+
add value to list if it's not already inside
|
8
|
+
--front - adds value to front of list (moves it to front if it's already inside)
|
9
|
+
--back - adds value to back of list (moves it to back if it's already inside)
|
10
|
+
EOF
|
11
|
+
help.add_cmd "list <name> del <val|index>", <<~EOF
|
12
|
+
remove a value from a list
|
13
|
+
if the provided value is an integer, it's interpreted as an index in the list
|
14
|
+
EOF
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.register_cli_parser(parser)
|
18
|
+
parser.add_cmd(Name, ->(cmd, args) { parse_cli(args) })
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.parse_cli(args)
|
22
|
+
opts = CliParser.filter_opts_front(args)
|
23
|
+
raise Envo::Error.new "list: missing name. Use 'list <name> <cmd> <args>'" if args.empty?
|
24
|
+
name = args.shift
|
25
|
+
return ParsedCmd.new(CmdShow.new([name], true), opts) if args.empty? # just list <name>
|
26
|
+
|
27
|
+
cmd = args.shift
|
28
|
+
return CmdListAdd.parse_cli_args(name, args, opts) if cmd == 'add'
|
29
|
+
return CmdListDel.parse_cli_args(name, args, opts) if cmd == 'del'
|
30
|
+
|
31
|
+
raise Envo::Error.new "list: unkonwn subcommand #{cmd}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.register_script_parser(parser)
|
35
|
+
parser.add_cmd(Name, ->(cmd, tokens, opts) { parse_script(tokens, opts) })
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.parse_script(tokens, opts)
|
39
|
+
raise Envo::Error.new "list: missing name. Use 'list <name> <cmd> <args>'" if tokens.empty?
|
40
|
+
name = tokens.shift
|
41
|
+
return ParsedCmd.new(CmdShow.new([name], true), opts) if tokens.empty? # just list <name>
|
42
|
+
|
43
|
+
cmd = tokens.shift
|
44
|
+
return CmdListAdd.parse_script(name, tokens, opts) if cmd == 'add'
|
45
|
+
return CmdListDel.parse_tokens(name, tokens, opts) if cmd == 'del'
|
46
|
+
|
47
|
+
raise Envo::Error.new "list: unkonwn subcommand #{cmd}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdListAdd
|
3
|
+
def self.register_help(help)
|
4
|
+
help.add_cmd 'la <name> <val>', "shorthand for 'list <name> add <val>'"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.register_cli_parser(parser)
|
8
|
+
parser.add_cmd('la', ->(cmd, args) { parse_cli_all(args) })
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register_script_parser(parser)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse_cli_all(args)
|
15
|
+
opts = CliParser.filter_opts_front(args)
|
16
|
+
raise Envo::Error.new "list-add: missing name. Use 'la <name> <val>'" if args.empty?
|
17
|
+
parse_cli_args(args[0], args[1..], opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_script(name, tokens, opts)
|
21
|
+
pos = nil
|
22
|
+
opts.filter! do |opt|
|
23
|
+
case opt
|
24
|
+
when 'front', 'top'
|
25
|
+
pos = :front
|
26
|
+
false
|
27
|
+
when 'back', 'bottom'
|
28
|
+
pos = :back
|
29
|
+
false
|
30
|
+
else
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
ParsedCmd.new(CmdListAdd.new(name, tokens, pos), opts)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.parse_cli_args(name, args, opts)
|
39
|
+
opts += CliParser.filter_opts(args)
|
40
|
+
pos = nil
|
41
|
+
opts.filter! do |opt|
|
42
|
+
case opt
|
43
|
+
when '--front', '--top'
|
44
|
+
pos = :front
|
45
|
+
false
|
46
|
+
when '--back', '--bottom'
|
47
|
+
pos = :back
|
48
|
+
false
|
49
|
+
else
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
ParsedCmd.new(CmdListAdd.new(name, args, pos), opts)
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(name, values, pos)
|
58
|
+
raise Envo::Error.new 'list-add: no values to add provided' if values.empty?
|
59
|
+
@name = name
|
60
|
+
@values = values
|
61
|
+
@pos = pos
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_accessor :name, :values, :pos
|
65
|
+
|
66
|
+
def execute(ctx)
|
67
|
+
ename = ctx.expand_name(@name)
|
68
|
+
|
69
|
+
list = ctx.smart_get(ename)
|
70
|
+
|
71
|
+
ok = list.list?
|
72
|
+
if !ok
|
73
|
+
if list.type == :empty
|
74
|
+
ok ||= ctx.ask("#{ename} doesn't exist. Create?")
|
75
|
+
else
|
76
|
+
ok ||= ctx.ask("#{ename} is not a list, but a #{list.type}. Convert?")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
raise Envo::Error.new "list-add: adding list item to a non-list" if !ok
|
80
|
+
|
81
|
+
list = list.to_list
|
82
|
+
|
83
|
+
ordered = @pos == :front ? values.reverse : values
|
84
|
+
ordered.each do |val|
|
85
|
+
val = ctx.expand_value(val)
|
86
|
+
|
87
|
+
ok = list.accept_item?(val)
|
88
|
+
ok ||= ctx.ask("Add #{val.type} to #{list.type}?")
|
89
|
+
raise Envo::Error.new "list-add: adding #{val.type} to #{list.type}" if !ok
|
90
|
+
|
91
|
+
idesc = val.invalid_description
|
92
|
+
ok = !idesc
|
93
|
+
ok ||= ctx.ask("Add #{idesc} to #{ename}?")
|
94
|
+
raise Envo::Error.new "list-add: adding #{idesc} to #{ename}" if !ok
|
95
|
+
|
96
|
+
list.insert(val.to_s, @pos)
|
97
|
+
end
|
98
|
+
|
99
|
+
ctx.smart_set(ename, list)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdListDel
|
3
|
+
def self.register_help(help)
|
4
|
+
help.add_cmd 'ld <name> <val|index>', "shorthand for 'list <name> del <val|index>'"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.register_cli_parser(parser)
|
8
|
+
parser.add_cmd('ld', ->(cmd, args) { parse_cli_all(args) })
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register_script_parser(parser)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse_cli_all(args)
|
15
|
+
opts = CliParser.filter_opts_front(args)
|
16
|
+
raise Envo::Error.new "list-del: missing name. Use 'ld <name> <val|index>'" if args.empty?
|
17
|
+
parse_cli_args(args[0], args[1..], opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_cli_args(name, args, opts)
|
21
|
+
opts += CliParser.filter_opts(args)
|
22
|
+
parse_tokens(name, args, opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_tokens(name, tokens, opts)
|
26
|
+
raise Envo::Error.new "list-del: provide one value or index to delete. Use 'list <name> del <val|index>'" if tokens.size != 1
|
27
|
+
ParsedCmd.new(CmdListDel.new(name, tokens[0]), opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(name, value)
|
31
|
+
@name = name
|
32
|
+
@value = value
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :name, :value
|
36
|
+
|
37
|
+
def execute(ctx)
|
38
|
+
ename = ctx.expand_name(@name)
|
39
|
+
|
40
|
+
list = ctx.smart_get(ename)
|
41
|
+
|
42
|
+
if list.type == :empty
|
43
|
+
return if ctx.force?
|
44
|
+
raise Envo::Error.new "list-del: deleting an item from a non-exiting value"
|
45
|
+
end
|
46
|
+
|
47
|
+
ok = list.list?
|
48
|
+
ok ||= ctx.ask("#{ename} is not a list, but a #{list.type}. Convert?")
|
49
|
+
raise Envo::Error.new "list-del: deleting an item from a non-list" if !ok
|
50
|
+
|
51
|
+
list = list.to_list
|
52
|
+
|
53
|
+
val = ctx.expand_value(@value)
|
54
|
+
if val.list?
|
55
|
+
raise Envo::Error.new "list-del: can't delete a list from a list" if !ctx.force?
|
56
|
+
return
|
57
|
+
end
|
58
|
+
val = val.to_s
|
59
|
+
|
60
|
+
index = val.to_i
|
61
|
+
if !ctx.raw? && index.to_s == val
|
62
|
+
deleted = list.delete_at(index)
|
63
|
+
if !deleted
|
64
|
+
raise Envo::Error.new "list-del: no index #{val} in #{ename}" if !ctx.force?
|
65
|
+
return
|
66
|
+
end
|
67
|
+
else
|
68
|
+
deleted = list.delete(val)
|
69
|
+
if !deleted
|
70
|
+
raise Envo::Error.new "list-del: no item '#{val}' in #{ename}" if !deleted
|
71
|
+
return
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ctx.smart_set(ename, list)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdPath
|
3
|
+
Name = 'path'
|
4
|
+
def self.register_help(help)
|
5
|
+
help.add_cmd "path <args>", <<~EOF
|
6
|
+
shorthand for 'list @path <args>'
|
7
|
+
shorthand: 'p'
|
8
|
+
EOF
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register_cli_parser(parser)
|
12
|
+
parser.add_cmd(Name, ->(cmd, args) { parse_cli(args) })
|
13
|
+
parser.add_cmd('p', ->(cmd, args) { parse_cli(args) })
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register_script_parser(parser)
|
17
|
+
parser.add_cmd(Name, ->(cmd, tokens, opts) { parse_script(tokens, opts) })
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_cli(args)
|
21
|
+
CmdList.parse_cli(args.unshift('@path'))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_script(tokens, opts)
|
25
|
+
CmdList.parse_script(tokens.unshift('@path'), opts)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Envo
|
2
|
+
class CmdReset
|
3
|
+
Name = 'reset'
|
4
|
+
def self.register_help(help)
|
5
|
+
help.add_cmd 'reset <name>[=[<val>]]', <<~EOF
|
6
|
+
set or unset value of an existing environment variable
|
7
|
+
produce an error if the variable doesn't exist
|
8
|
+
EOF
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register_cli_parser(parser)
|
12
|
+
parser.add_cmd(Name, ->(cmd, args) { parse_cli(args) })
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.register_script_parser(parser)
|
16
|
+
parser.add_cmd(Name, ->(cmd, tokens, opts) { parse_tokens(tokens, opts) })
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.parse_cli(args)
|
20
|
+
opts = CliParser.filter_opts(args)
|
21
|
+
parse_tokens(args, opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_tokens(args, opts)
|
25
|
+
raise Envo::Error.new "reset: missing name. Use 'reset <name> [= [<val>]]'" if args.empty? || args[0][0] == '='
|
26
|
+
if args.size == 1
|
27
|
+
arg = args[0]
|
28
|
+
cnt = arg.count('=')
|
29
|
+
return ParsedCmd.new(CmdReset.new(arg, nil), opts) if cnt == 0
|
30
|
+
if cnt == 1 && arg[-1] == '='
|
31
|
+
split = arg.split('=')
|
32
|
+
return ParsedCmd.new(CmdReset.new(split[0], nil), opts) if split.size == 1
|
33
|
+
end
|
34
|
+
elsif args.size == 2
|
35
|
+
return ParsedCmd.new(CmdReset.new(args[0], nil), opts) if args[1] == '='
|
36
|
+
end
|
37
|
+
|
38
|
+
helper = CmdSet.parse_cli(args).cmd
|
39
|
+
ParsedCmd.new(CmdReset.new(helper.name, helper), opts)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.parse_script(args)
|
43
|
+
puts "#{Name} parse_script"
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(name, helper)
|
47
|
+
@name = name
|
48
|
+
@helper = helper
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :name, :helper
|
52
|
+
|
53
|
+
def execute(ctx)
|
54
|
+
ename = ctx.expand_name(@name)
|
55
|
+
|
56
|
+
raise Envo::Error.new "reset: no such var '#{ename}'" if !ctx.raw_get(ename)
|
57
|
+
|
58
|
+
if !@helper
|
59
|
+
ctx.unset(ename)
|
60
|
+
else
|
61
|
+
@helper.name = @name
|
62
|
+
@helper.execute(ctx)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|