tabry 0.1.5 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/tabry-bash +2 -29
  3. data/bin/tabry-generate-bash-complete +31 -0
  4. data/bin/tabry-help +1 -1
  5. data/bin/tabry-test-options +1 -1
  6. data/bin/tabry-test-parse +1 -1
  7. data/lib/tabry/cli/all_in_one.rb +98 -0
  8. data/lib/tabry/cli/arg_proxy.rb +4 -4
  9. data/lib/tabry/cli/builder.rb +9 -7
  10. data/lib/tabry/cli/internals.rb +1 -1
  11. data/lib/tabry/cli/util.rb +23 -10
  12. data/lib/tabry/config_builder/arg_or_flag_builder.rb +39 -0
  13. data/lib/tabry/config_builder/flagarg_builder.rb +14 -0
  14. data/lib/tabry/config_builder/generic_builder.rb +103 -0
  15. data/lib/tabry/config_builder/sub_builder.rb +27 -0
  16. data/lib/tabry/config_builder/top_level_builder.rb +31 -0
  17. data/lib/tabry/config_builder.rb +16 -0
  18. data/lib/tabry/models/config_list.rb +2 -2
  19. data/lib/tabry/models/config_string_hash.rb +2 -2
  20. data/lib/tabry/runner.rb +6 -2
  21. data/lib/tabry/shells/bash/wrapper.rb +38 -0
  22. data/lib/tabry/shells/bash.rb +46 -9
  23. data/sh/bash/tabry_bash.sh +1 -1
  24. data/sh/bash/tabry_bash_core.sh +3 -2
  25. data/spec/fixtures/config_builder/args.rb +49 -0
  26. data/spec/fixtures/config_builder/args.tabry +32 -0
  27. data/spec/fixtures/config_builder/args.yml +63 -0
  28. data/spec/fixtures/config_builder/defs.rb +33 -0
  29. data/spec/fixtures/config_builder/defs.tabry +21 -0
  30. data/spec/fixtures/config_builder/defs.yml +33 -0
  31. data/spec/fixtures/config_builder/flags.rb +26 -0
  32. data/spec/fixtures/config_builder/flags.tabry +13 -0
  33. data/spec/fixtures/config_builder/flags.yml +27 -0
  34. data/spec/fixtures/config_builder/subs.rb +34 -0
  35. data/spec/fixtures/config_builder/subs.tabry +25 -0
  36. data/spec/fixtures/config_builder/subs.yml +46 -0
  37. data/spec/fixtures/config_builder/underscoresdashes.rb +30 -0
  38. data/spec/fixtures/config_builder/underscoresdashes.tabry +18 -0
  39. data/spec/fixtures/config_builder/underscoresdashes.yml +39 -0
  40. data/spec/tabry/cli/all_in_one_spec.rb +141 -0
  41. data/spec/tabry/cli/arg_proxy_spec.rb +2 -2
  42. data/spec/tabry/cli/builder_spec.rb +5 -5
  43. data/spec/tabry/cli/util_spec.rb +125 -0
  44. data/spec/tabry/config_builder_spec.rb +64 -0
  45. data/spec/tabry/runner_spec.rb +1 -1
  46. data/spec/tabry/shell_splitter_spec.rb +7 -5
  47. data/spec/tabry/shells/bash_spec.rb +44 -0
  48. data/tabry.gemspec +1 -1
  49. metadata +31 -3
  50. 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(args.reqd).to receive(:exit).with(1)
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(args.reqd).to receive(:exit).with(1)
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(config_name: "theconfigname").and_return runner
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(builder).to receive(:exit).with(1)
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(builder).to receive(:exit).with(0)
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(builder).to receive(:exit).with(1)
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(builder).to receive(:exit).with(1)
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
@@ -4,7 +4,7 @@ require_relative "../../lib/tabry/runner"
4
4
 
5
5
  describe Tabry::Runner do
6
6
  subject do
7
- described_class.new(config_name: "configname")
7
+ described_class.new(config: "configname")
8
8
  end
9
9
 
10
10
  let(:config) { instance_double(Tabry::Models::Config) }
@@ -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
- "waz",
15
- ["ab c d", "ef g"],
16
- "hi jk"
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.1.5"
9
+ s.version = "0.2.1"
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.1.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Battaglia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-21 00:00:00.000000000 Z
11
+ date: 2023-03-10 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