tabry 0.1.5 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/tabry-bash +2 -29
- data/bin/tabry-generate-bash-complete +31 -0
- data/bin/tabry-help +1 -1
- data/bin/tabry-test-options +1 -1
- data/bin/tabry-test-parse +1 -1
- data/lib/tabry/cli/all_in_one.rb +98 -0
- data/lib/tabry/cli/arg_proxy.rb +4 -4
- data/lib/tabry/cli/builder.rb +9 -7
- data/lib/tabry/cli/internals.rb +1 -1
- data/lib/tabry/cli/util.rb +24 -10
- data/lib/tabry/config_builder/arg_or_flag_builder.rb +39 -0
- data/lib/tabry/config_builder/flagarg_builder.rb +14 -0
- data/lib/tabry/config_builder/generic_builder.rb +103 -0
- data/lib/tabry/config_builder/sub_builder.rb +27 -0
- data/lib/tabry/config_builder/top_level_builder.rb +31 -0
- data/lib/tabry/config_builder.rb +16 -0
- data/lib/tabry/models/config_list.rb +2 -2
- data/lib/tabry/models/config_string_hash.rb +2 -2
- data/lib/tabry/runner.rb +6 -2
- data/lib/tabry/shells/bash/wrapper.rb +38 -0
- data/lib/tabry/shells/bash.rb +46 -9
- data/sh/bash/tabry_bash.sh +1 -1
- data/sh/bash/tabry_bash_core.sh +3 -2
- data/spec/fixtures/config_builder/args.rb +49 -0
- data/spec/fixtures/config_builder/args.tabry +32 -0
- data/spec/fixtures/config_builder/args.yml +63 -0
- data/spec/fixtures/config_builder/defs.rb +33 -0
- data/spec/fixtures/config_builder/defs.tabry +21 -0
- data/spec/fixtures/config_builder/defs.yml +33 -0
- data/spec/fixtures/config_builder/flags.rb +26 -0
- data/spec/fixtures/config_builder/flags.tabry +13 -0
- data/spec/fixtures/config_builder/flags.yml +27 -0
- data/spec/fixtures/config_builder/subs.rb +34 -0
- data/spec/fixtures/config_builder/subs.tabry +25 -0
- data/spec/fixtures/config_builder/subs.yml +46 -0
- data/spec/fixtures/config_builder/underscoresdashes.rb +30 -0
- data/spec/fixtures/config_builder/underscoresdashes.tabry +18 -0
- data/spec/fixtures/config_builder/underscoresdashes.yml +39 -0
- data/spec/tabry/cli/all_in_one_spec.rb +141 -0
- data/spec/tabry/cli/arg_proxy_spec.rb +2 -2
- data/spec/tabry/cli/builder_spec.rb +5 -5
- data/spec/tabry/cli/util_spec.rb +125 -0
- data/spec/tabry/config_builder_spec.rb +64 -0
- data/spec/tabry/runner_spec.rb +1 -1
- data/spec/tabry/shell_splitter_spec.rb +7 -5
- data/spec/tabry/shells/bash_spec.rb +44 -0
- data/tabry.gemspec +1 -1
- metadata +31 -3
- data/spec/lib/tabry/cli/util_spec.rb +0 -60
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../lib/tabry/cli/all_in_one"
|
4
|
+
require_relative "../../../lib/tabry/shells/bash"
|
5
|
+
require_relative "../../../lib/tabry/shells/bash/wrapper"
|
6
|
+
|
7
|
+
module Tabry::Spec
|
8
|
+
module Cli
|
9
|
+
module AllInOneSpec
|
10
|
+
class << self
|
11
|
+
attr_accessor :log
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Tabry::CLI::AllInOne do
|
18
|
+
before do
|
19
|
+
Tabry::Spec::Cli::AllInOneSpec.log = []
|
20
|
+
allow(Kernel).to receive(:exit).and_raise(StandardError.new("exit called"))
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".build" do
|
24
|
+
let(:cli) do
|
25
|
+
described_class.build do
|
26
|
+
config do
|
27
|
+
completion
|
28
|
+
|
29
|
+
cmd :abc
|
30
|
+
|
31
|
+
sub :foo do
|
32
|
+
arg :bar
|
33
|
+
end
|
34
|
+
|
35
|
+
sub :foo2 do
|
36
|
+
sub :bar2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Tabry::Spec::Cli::AllInOneSpec.log << :after_config
|
41
|
+
|
42
|
+
def foo
|
43
|
+
Tabry::Spec::Cli::AllInOneSpec.log << [:foo, args.bar]
|
44
|
+
end
|
45
|
+
|
46
|
+
def foo2__bar2
|
47
|
+
Tabry::Spec::Cli::AllInOneSpec.log << [:foo2__bar2]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "creates a builder with CLI" do
|
53
|
+
expect(cli).to be_a(Tabry::CLI::Builder)
|
54
|
+
expect(cli.cli_class).to be_a(Class)
|
55
|
+
expect(cli.cli_class).to be < Tabry::CLI::Base
|
56
|
+
end
|
57
|
+
|
58
|
+
it "makes the config using the config block" do
|
59
|
+
conf = cli.runner.config
|
60
|
+
expect(conf).to be_a(Tabry::Models::Config)
|
61
|
+
expect(conf.main.subs.by_name.keys).to include("foo2")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "makes a CLI with the methods in the block" do
|
65
|
+
cli.run(["foo", "bararg"])
|
66
|
+
expect(Tabry::Spec::Cli::AllInOneSpec.log).to eq [
|
67
|
+
:after_config,
|
68
|
+
[:foo, "bararg"],
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "creates a #completion__bash method which generates completion" do
|
73
|
+
expect(Tabry::Shells::Bash).to receive(:generate_self).and_return("bash completion stuff")
|
74
|
+
expect_any_instance_of(Kernel).to receive(:puts).with("bash completion stuff")
|
75
|
+
cli.run(["completion", "bash"])
|
76
|
+
end
|
77
|
+
|
78
|
+
it "creates a #completion method which generates options" do
|
79
|
+
expect(Tabry::Bash::Wrapper).to receive(:run).with("cmd line", "6", config: instance_of(Tabry::Models::Config))
|
80
|
+
cli.run(["completion", "cmd line", "6"])
|
81
|
+
end
|
82
|
+
|
83
|
+
it "quits the block early after loading config and the subcommand to be run is #complete" do
|
84
|
+
allow(Tabry::Bash::Wrapper).to receive(:run)
|
85
|
+
expect(Tabry::Spec::Cli::AllInOneSpec.log).to eq([])
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can take a config object passed in to config" do
|
89
|
+
conf = Tabry::ConfigBuilder.build { sub :bar }
|
90
|
+
cli = described_class.build do
|
91
|
+
config conf
|
92
|
+
|
93
|
+
def bar; end
|
94
|
+
end
|
95
|
+
|
96
|
+
expect(cli.runner.config).to eq(conf)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#run" do
|
101
|
+
it "runs build and then runs the builder with ARGV" do
|
102
|
+
stub_const("ARGV", ["abc", "def"])
|
103
|
+
test_blk = proc { completion }
|
104
|
+
test_builder = instance_double(Tabry::CLI::Builder)
|
105
|
+
expect(described_class).to receive(:build) do |**kwargs, &blk|
|
106
|
+
expect(blk).to eql(test_blk)
|
107
|
+
expect(kwargs).to eq({ cli: "fake cli", config: "fake config" })
|
108
|
+
test_builder
|
109
|
+
end
|
110
|
+
expect(test_builder).to receive(:run).with(%w[abc def])
|
111
|
+
described_class.run(cli: "fake cli", config: "fake config", &test_blk)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#completion_only" do
|
116
|
+
it "creates a #completion__bash method which generates completion" do
|
117
|
+
stub_const("ARGV", %w[completion bash])
|
118
|
+
expect(Tabry::Shells::Bash).to receive(:generate_self).with(cmd_name: "foo").and_return("bash completion stuff")
|
119
|
+
expect_any_instance_of(Kernel).to receive(:puts).with("bash completion stuff")
|
120
|
+
|
121
|
+
described_class.completion_only do
|
122
|
+
cmd :foo
|
123
|
+
sub :bar
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "creates a #completion method which generates options" do
|
128
|
+
stub_const("ARGV", ["completion", "cmd line", "6"])
|
129
|
+
expect(Tabry::Bash::Wrapper).to receive(:run) do |cmd_line, comp_point, config:|
|
130
|
+
expect(cmd_line).to eq("cmd line")
|
131
|
+
expect(comp_point).to eq("6")
|
132
|
+
expect(config.cmd).to eq("foo")
|
133
|
+
expect(config.main.subs.by_name.keys).to eq(["bar"])
|
134
|
+
end
|
135
|
+
described_class.completion_only do
|
136
|
+
cmd :foo
|
137
|
+
sub :bar
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -49,14 +49,14 @@ describe Tabry::CLI::ArgProxy do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "prints an error and exits if read thru reqd and the argument (name) is not found" do
|
52
|
-
expect(
|
52
|
+
expect(Kernel).to receive(:exit).with(1)
|
53
53
|
expect do
|
54
54
|
args.reqd.foo
|
55
55
|
end.to output(/FATAL: Missing required argument foo/).to_stderr
|
56
56
|
end
|
57
57
|
|
58
58
|
it "prints an error and exits if read thru reqd and the argument (index) is not found" do
|
59
|
-
expect(
|
59
|
+
expect(Kernel).to receive(:exit).with(1)
|
60
60
|
expect do
|
61
61
|
args.reqd[3]
|
62
62
|
end.to output(/FATAL: Missing required argument number 4/).to_stderr
|
@@ -97,7 +97,7 @@ describe Tabry::CLI::Builder do
|
|
97
97
|
|
98
98
|
before do
|
99
99
|
runner = instance_double(Tabry::Runner)
|
100
|
-
allow(Tabry::Runner).to receive(:new).with(
|
100
|
+
allow(Tabry::Runner).to receive(:new).with(config: "theconfigname").and_return runner
|
101
101
|
allow(runner).to receive(:parse).with(%w[the raw args]).and_return result
|
102
102
|
end
|
103
103
|
|
@@ -215,7 +215,7 @@ describe Tabry::CLI::Builder do
|
|
215
215
|
|
216
216
|
it "quits and shows an error and usage info if there is incorrect usage" do
|
217
217
|
expect(result).to receive(:usage).and_return "example command usage"
|
218
|
-
expect(
|
218
|
+
expect(Kernel).to receive(:exit).with(1)
|
219
219
|
expect do
|
220
220
|
subject
|
221
221
|
end.to output(
|
@@ -229,7 +229,7 @@ describe Tabry::CLI::Builder do
|
|
229
229
|
|
230
230
|
it "quits and shows usage if help is passed in" do
|
231
231
|
expect(result).to receive(:usage).and_return "example command usage"
|
232
|
-
expect(
|
232
|
+
expect(Kernel).to receive(:exit).with(0)
|
233
233
|
expect { subject }.to output(/example command usage/).to_stdout
|
234
234
|
end
|
235
235
|
end
|
@@ -239,7 +239,7 @@ describe Tabry::CLI::Builder do
|
|
239
239
|
let(:state) { { subcommand_stack: %w[wombat] } }
|
240
240
|
|
241
241
|
it "quits and shows an error if there is the command is valid but the CLI class doesn't implement it" do
|
242
|
-
expect(
|
242
|
+
expect(Kernel).to receive(:exit).with(1)
|
243
243
|
expect { subject }.to output(/FATAL: CLI does not support command wombat/).to_stderr
|
244
244
|
end
|
245
245
|
end
|
@@ -248,7 +248,7 @@ describe Tabry::CLI::Builder do
|
|
248
248
|
let(:state) { { subcommand_stack: %w[foo] } }
|
249
249
|
|
250
250
|
it "quits and shows an error" do
|
251
|
-
expect(
|
251
|
+
expect(Kernel).to receive(:exit).with(1)
|
252
252
|
expect { subject }.to output(/FATAL: CLI does not support command main/).to_stderr
|
253
253
|
end
|
254
254
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../lib/tabry/cli/util"
|
4
|
+
|
5
|
+
describe Tabry::CLI::Util do
|
6
|
+
describe ".make_cmdline" do
|
7
|
+
it "escapes a single string" do
|
8
|
+
expect(described_class.make_cmdline(
|
9
|
+
"hello %s", "world;abc"
|
10
|
+
)).to eq(
|
11
|
+
"hello world\\;abc"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "escapes multiple string arguments" do
|
16
|
+
expect(described_class.make_cmdline(
|
17
|
+
"hello %s hi %s", "world;abc", "def;ghi"
|
18
|
+
)).to eq(
|
19
|
+
"hello world\\;abc hi def\\;ghi"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "escapes array arguments" do
|
24
|
+
# args is an array of strings and arrays
|
25
|
+
expect(described_class.make_cmdline(
|
26
|
+
"hello %s hi %s", "world;abc", ["foo;bar", "waz;ok"]
|
27
|
+
)).to eq(
|
28
|
+
"hello world\\;abc hi foo\\;bar waz\\;ok"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "treats a single array of strings as a list of args, not as one array arg" do
|
33
|
+
# args is an array with one array of strings
|
34
|
+
# an improvement might be to figure out how
|
35
|
+
# many '%s's there are in the cmdline
|
36
|
+
expect(described_class.make_cmdline(
|
37
|
+
"hello %s hi %s", ["world;abc", "foo;bar"]
|
38
|
+
)).to eq(
|
39
|
+
"hello world\\;abc hi foo\\;bar"
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "escapes arrays if given one array of mixed strings and arrays" do
|
44
|
+
expect(described_class.make_cmdline(
|
45
|
+
"hello %s hi %s", [["world;abc", "foo;bar"], "waz;ok"]
|
46
|
+
)).to eq(
|
47
|
+
"hello world\\;abc foo\\;bar hi waz\\;ok"
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can send a single array argument by wrapping in an array" do
|
52
|
+
# args is an array with one array of one array
|
53
|
+
expect(described_class.make_cmdline(
|
54
|
+
"hello %s hi", [["foo;bar", "waz;ok"]]
|
55
|
+
)).to eq(
|
56
|
+
"hello foo\\;bar waz\\;ok hi"
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can merge_stderr" do
|
61
|
+
expect(described_class.make_cmdline(
|
62
|
+
"echo %s | cat", "a", merge_stderr: true
|
63
|
+
)).to eq(
|
64
|
+
"{ echo a | cat ;} 2>&1"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "open_web_page" do
|
70
|
+
it 'uses "xdg-open" when on Linux' do
|
71
|
+
stub_const("RUBY_PLATFORM", "x86_64-linux")
|
72
|
+
expect(Kernel).to receive("system") do |cmdline|
|
73
|
+
expect(cmdline).to include("(xdg-open ")
|
74
|
+
end
|
75
|
+
described_class.open_web_page("http://example.com")
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'uses "open" when on Darwin' do
|
79
|
+
stub_const("RUBY_PLATFORM", "x86_64-darwin")
|
80
|
+
expect(Kernel).to receive("system") do |cmdline|
|
81
|
+
expect(cmdline).to include("(open ")
|
82
|
+
end
|
83
|
+
described_class.open_web_page("http://example.com")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "backtick_or_die" do
|
88
|
+
before do
|
89
|
+
allow(Kernel).to receive(:exit)
|
90
|
+
allow(Kernel).to receive(:warn)
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the command returns a non-zero status code" do
|
94
|
+
before do
|
95
|
+
described_class.backtick_or_die("echo abc && echo def && echo ghi && false")
|
96
|
+
end
|
97
|
+
|
98
|
+
it "prints out the output" do
|
99
|
+
expect(Kernel).to have_received(:warn).with(
|
100
|
+
a_string_including("\ndef\n")
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "exits with a non-zero status code" do
|
105
|
+
expect(Kernel).to have_received(:exit).with(1)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when the command does not exist" do
|
110
|
+
before do
|
111
|
+
described_class.backtick_or_die("theresnowayanyonehasthiscommandinstalled-randomstuff-2390832190832jk4398190fdlksjhfdsalkjlkfdsaj43098432908fd")
|
112
|
+
end
|
113
|
+
|
114
|
+
it "exits with a non-zero status code" do
|
115
|
+
expect(Kernel).to have_received(:exit).with(1)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "says that the command does not exist" do
|
119
|
+
expect(Kernel).to have_received(:warn).with(
|
120
|
+
a_string_including("command does not exist")
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "json"
|
5
|
+
require_relative "../../lib/tabry/config_builder"
|
6
|
+
|
7
|
+
describe Tabry::ConfigBuilder do
|
8
|
+
def sort_nested_hashes(object)
|
9
|
+
case object
|
10
|
+
when Hash
|
11
|
+
object.sort_by { |key, _val| key }.to_h.transform_values { |val| sort_nested_hashes(val) }
|
12
|
+
when Array
|
13
|
+
object.map { |val| sort_nested_hashes(val) }
|
14
|
+
else
|
15
|
+
object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
%w[Args Defs Flags Subs Underscoresdashes].each do |fixture|
|
20
|
+
context "#{fixture} test fixture" do
|
21
|
+
it "matches what would be produced by the equivalent (old tabry language) tabry file" do
|
22
|
+
require_relative "../fixtures/config_builder/#{fixture.downcase}"
|
23
|
+
actual = Tabry::Spec::Fixtures::ConfigBuilder.const_get(fixture.to_sym)._raw
|
24
|
+
expected = YAML.load_file(File.expand_path("../fixtures/config_builder/#{fixture.downcase}.yml", __dir__))
|
25
|
+
|
26
|
+
actual = JSON.pretty_generate(sort_nested_hashes(actual))
|
27
|
+
expected = JSON.pretty_generate(sort_nested_hashes(expected))
|
28
|
+
|
29
|
+
expect(actual).to eql(expected)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "defines a 'completion' shortcut with 'completion' and 'completion__bash' subs" do
|
35
|
+
config = described_class.build do
|
36
|
+
completion
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(config._raw.dig("main", "subs")).to eq(
|
40
|
+
[
|
41
|
+
{
|
42
|
+
"description" => "Get tab completion shell config",
|
43
|
+
"name" => "completion",
|
44
|
+
"args" => [
|
45
|
+
{
|
46
|
+
"description" => "(for internal usage, when used instead of subcommand) full command line for getting completion options",
|
47
|
+
"name" => "cmd_line"
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"description" => "(for internal usage, when used instead of subcommand) comp point",
|
51
|
+
"name" => "comp_point"
|
52
|
+
}
|
53
|
+
],
|
54
|
+
"subs" => [
|
55
|
+
{
|
56
|
+
"description" => "Get tab completion for bash or zsh",
|
57
|
+
"name" => "bash"
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}
|
61
|
+
]
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
data/spec/tabry/runner_spec.rb
CHANGED
@@ -10,11 +10,13 @@ describe Tabry::ShellSplitter do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "handles quotes and backslashes like a shell" do
|
13
|
-
expect(described_class.split('"/foo bar/waz" a\'b \'c\\ d "ef g" "hi jk" lmn', 38)).to eq(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
expect(described_class.split('"/foo bar/waz" a\'b \'c\\ d "ef g" "hi jk" lmn', 38)).to eq(
|
14
|
+
[
|
15
|
+
"waz",
|
16
|
+
["ab c d", "ef g"],
|
17
|
+
"hi jk"
|
18
|
+
]
|
19
|
+
)
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../lib/tabry/shells/bash"
|
4
|
+
|
5
|
+
describe Tabry::Shells::Bash do
|
6
|
+
describe ".generate_self" do
|
7
|
+
before { @backup, $0 = $0, "/bla/waz/abc" }
|
8
|
+
after { $0 = @backup }
|
9
|
+
|
10
|
+
it "tells bash to use the currently running command plus 'completion' to get completion options" do
|
11
|
+
expect(described_class.generate_self).to match(
|
12
|
+
%r{^ *TABRY_IMPORTS_PATH='' _tabry_ABC_completions_internal /bla/waz/abc completion$}
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "uses the cmd_name given for the command name for bash's 'complete'" do
|
17
|
+
result = described_class.generate_self
|
18
|
+
expect(result).to include("\ncomplete -F _tabry_ABC_completions abc\n")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "defaults cmd_name to the basename of the currently running command" do
|
22
|
+
result = described_class.generate_self(cmd_name: 'wombat')
|
23
|
+
expect(result).to match(
|
24
|
+
%r{^ *TABRY_IMPORTS_PATH='' _tabry_WOMBAT_completions_internal /bla/waz/abc completion$}
|
25
|
+
)
|
26
|
+
expect(result).to include("\ncomplete -F _tabry_WOMBAT_completions wombat\n")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.generate' do
|
31
|
+
it 'tells bash to use tabry-bash with a import path to get completion options' do
|
32
|
+
result = described_class.generate("my-cmd", "/path/to/mycmd.tabry")
|
33
|
+
expect(result).to include("TABRY_IMPORTS_PATH=/path/to/mycmd.tabry _tabry_MY_CMD_completions_internal /home/evan/dev/tabry/bin/tabry-bash \n")
|
34
|
+
expect(result).to include("complete -F _tabry_MY_CMD_completions my-cmd\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "takes a uniq_fn_id parameter to override the default function names" do
|
38
|
+
result = described_class.generate("my-cmd", "/path/to/mycmd.tabry", uniq_fn_id: "my cmd tabryv0.2.0")
|
39
|
+
expect(result).to include("TABRY_IMPORTS_PATH=/path/to/mycmd.tabry _tabry_MY_CMD_TABRYV0_2_0_completions_internal /home/evan/dev/tabry/bin/tabry-bash \n")
|
40
|
+
expect(result).to include("complete -F _tabry_MY_CMD_TABRYV0_2_0_completions my-cmd\n")
|
41
|
+
expect(result).to include("_tabry_MY_CMD_TABRYV0_2_0_completions_internal()")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/tabry.gemspec
CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "tabry"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.2.2"
|
10
10
|
s.summary = "Tab completion and CLIs extraordinaire"
|
11
11
|
s.authors = ["Evan Battaglia"]
|
12
12
|
s.email = "battaglia.evan@gmail.com"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Battaglia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|
@@ -84,6 +84,7 @@ description:
|
|
84
84
|
email: battaglia.evan@gmail.com
|
85
85
|
executables:
|
86
86
|
- tabry-bash
|
87
|
+
- tabry-generate-bash-complete
|
87
88
|
- tabry-help
|
88
89
|
- tabry-test-options
|
89
90
|
- tabry-test-parse
|
@@ -91,9 +92,11 @@ extensions: []
|
|
91
92
|
extra_rdoc_files: []
|
92
93
|
files:
|
93
94
|
- bin/tabry-bash
|
95
|
+
- bin/tabry-generate-bash-complete
|
94
96
|
- bin/tabry-help
|
95
97
|
- bin/tabry-test-options
|
96
98
|
- bin/tabry-test-parse
|
99
|
+
- lib/tabry/cli/all_in_one.rb
|
97
100
|
- lib/tabry/cli/arg_proxy.rb
|
98
101
|
- lib/tabry/cli/base.rb
|
99
102
|
- lib/tabry/cli/builder.rb
|
@@ -101,6 +104,12 @@ files:
|
|
101
104
|
- lib/tabry/cli/internals.rb
|
102
105
|
- lib/tabry/cli/util.rb
|
103
106
|
- lib/tabry/cli/util/config.rb
|
107
|
+
- lib/tabry/config_builder.rb
|
108
|
+
- lib/tabry/config_builder/arg_or_flag_builder.rb
|
109
|
+
- lib/tabry/config_builder/flagarg_builder.rb
|
110
|
+
- lib/tabry/config_builder/generic_builder.rb
|
111
|
+
- lib/tabry/config_builder/sub_builder.rb
|
112
|
+
- lib/tabry/config_builder/top_level_builder.rb
|
104
113
|
- lib/tabry/config_loader.rb
|
105
114
|
- lib/tabry/core_ext/string/colors.rb
|
106
115
|
- lib/tabry/machine.rb
|
@@ -135,6 +144,7 @@ files:
|
|
135
144
|
- lib/tabry/runner.rb
|
136
145
|
- lib/tabry/shell_splitter.rb
|
137
146
|
- lib/tabry/shells/bash.rb
|
147
|
+
- lib/tabry/shells/bash/wrapper.rb
|
138
148
|
- lib/tabry/state.rb
|
139
149
|
- lib/tabry/usage_generator.rb
|
140
150
|
- lib/tabry/util.rb
|
@@ -148,12 +158,29 @@ files:
|
|
148
158
|
- spec/fixtures/basiccli.tabry
|
149
159
|
- spec/fixtures/basiccli2.tabry
|
150
160
|
- spec/fixtures/basiccli2.yml
|
161
|
+
- spec/fixtures/config_builder/args.rb
|
162
|
+
- spec/fixtures/config_builder/args.tabry
|
163
|
+
- spec/fixtures/config_builder/args.yml
|
164
|
+
- spec/fixtures/config_builder/defs.rb
|
165
|
+
- spec/fixtures/config_builder/defs.tabry
|
166
|
+
- spec/fixtures/config_builder/defs.yml
|
167
|
+
- spec/fixtures/config_builder/flags.rb
|
168
|
+
- spec/fixtures/config_builder/flags.tabry
|
169
|
+
- spec/fixtures/config_builder/flags.yml
|
170
|
+
- spec/fixtures/config_builder/subs.rb
|
171
|
+
- spec/fixtures/config_builder/subs.tabry
|
172
|
+
- spec/fixtures/config_builder/subs.yml
|
173
|
+
- spec/fixtures/config_builder/underscoresdashes.rb
|
174
|
+
- spec/fixtures/config_builder/underscoresdashes.tabry
|
175
|
+
- spec/fixtures/config_builder/underscoresdashes.yml
|
151
176
|
- spec/fixtures/vehicles.tabry
|
152
177
|
- spec/fixtures/vehicles.yaml
|
153
|
-
- spec/lib/tabry/cli/util_spec.rb
|
154
178
|
- spec/spec_helper.rb
|
179
|
+
- spec/tabry/cli/all_in_one_spec.rb
|
155
180
|
- spec/tabry/cli/arg_proxy_spec.rb
|
156
181
|
- spec/tabry/cli/builder_spec.rb
|
182
|
+
- spec/tabry/cli/util_spec.rb
|
183
|
+
- spec/tabry/config_builder_spec.rb
|
157
184
|
- spec/tabry/config_loader_spec.rb
|
158
185
|
- spec/tabry/machine_spec.rb
|
159
186
|
- spec/tabry/models/args_list_spec.rb
|
@@ -168,6 +195,7 @@ files:
|
|
168
195
|
- spec/tabry/result_spec.rb
|
169
196
|
- spec/tabry/runner_spec.rb
|
170
197
|
- spec/tabry/shell_splitter_spec.rb
|
198
|
+
- spec/tabry/shells/bash_spec.rb
|
171
199
|
- spec/tabry/usage_generator_spec.rb
|
172
200
|
- tabry.gemspec
|
173
201
|
- treesitter/Cargo.toml
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../../../../lib/tabry/cli/util"
|
4
|
-
|
5
|
-
describe Tabry::CLI::Util do
|
6
|
-
describe ".make_cmdline" do
|
7
|
-
it "escapes a single string" do
|
8
|
-
expect(described_class.make_cmdline(
|
9
|
-
"hello %s", "world;abc"
|
10
|
-
)).to eq(
|
11
|
-
"hello world\\;abc"
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "escapes multiple string arguments" do
|
16
|
-
expect(described_class.make_cmdline(
|
17
|
-
"hello %s hi %s", "world;abc", "def;ghi"
|
18
|
-
)).to eq(
|
19
|
-
"hello world\\;abc hi def\\;ghi"
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "escapes array arguments" do
|
24
|
-
# args is an array of strings and arrays
|
25
|
-
expect(described_class.make_cmdline(
|
26
|
-
"hello %s hi %s", "world;abc", ["foo;bar", "waz;ok"]
|
27
|
-
)).to eq(
|
28
|
-
"hello world\\;abc hi foo\\;bar waz\\;ok"
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "treats a single array of strings as a list of args, not as one array arg" do
|
33
|
-
# args is an array with one array of strings
|
34
|
-
# an improvement might be to figure out how
|
35
|
-
# many '%s's there are in the cmdline
|
36
|
-
expect(described_class.make_cmdline(
|
37
|
-
"hello %s hi %s", ["world;abc", "foo;bar"]
|
38
|
-
)).to eq(
|
39
|
-
"hello world\\;abc hi foo\\;bar"
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "escapes arrays if given one array of mixed strings and arrays" do
|
44
|
-
expect(described_class.make_cmdline(
|
45
|
-
"hello %s hi %s", [["world;abc", "foo;bar"], "waz;ok"]
|
46
|
-
)).to eq(
|
47
|
-
"hello world\\;abc foo\\;bar hi waz\\;ok"
|
48
|
-
)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "can send a single array argument by wrapping in an array" do
|
52
|
-
# args is an array with one array of one array
|
53
|
-
expect(described_class.make_cmdline(
|
54
|
-
"hello %s hi", [["foo;bar", "waz;ok"]]
|
55
|
-
)).to eq(
|
56
|
-
"hello foo\\;bar waz\\;ok hi"
|
57
|
-
)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|