tabry 0.1.5 → 0.2.2

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.
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 +24 -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.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.1.5
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: 2022-10-21 00:00:00.000000000 Z
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