TINKERPOP-1879 Fixed gremlin.sh handling of = in flags
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/352d06e5 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/352d06e5 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/352d06e5 Branch: refs/heads/TINKERPOP-1857 Commit: 352d06e5a9bcbd34e6082a8e2092584cf3a5ea41 Parents: 0bcab7f Author: Stephen Mallette <[email protected]> Authored: Thu Jan 25 08:17:52 2018 -0500 Committer: Stephen Mallette <[email protected]> Committed: Thu Jan 25 08:17:52 2018 -0500 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + .../tinkerpop/gremlin/console/Console.groovy | 24 +++++++++--- .../src/test/python/tests/test_console.py | 40 ++++++++++++++------ 3 files changed, 47 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/352d06e5/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 7377d24..0179cb6 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -27,6 +27,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Removed hardcoded expectation in metrics serialization test suite as different providers may have different outputs. * Added `IndexedTraverserSet` which indexes on the value of a `Traverser` thus improving performance when used. * Utilized `IndexedTraverserSet` in `TraversalVertexProgram` to avoid extra iteration when doing `Vertex` lookups. +* Fixed a bug in Gremlin Console which prevented handling of `gremlin.sh` flags that had an "=" between the flag and its arguments. * Fixed a bug in `ComputerAwareStep` that didn't handle `reset()` properly and thus occasionally produced some extra traversers. [[release-3-2-7]] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/352d06e5/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy ---------------------------------------------------------------------- diff --git a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy index 5eb5039..fe9e613 100644 --- a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy +++ b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy @@ -489,21 +489,22 @@ class Console { */ private static List<List<String>> parseArgs(final List<String> options, final String[] args, final CliBuilder cli) { def parsed = [] - for (int ix = 0; ix < args.length; ix++) { - if (args[ix] in options) { + def normalizedArgs = normalizeArgs(options, args) + for (int ix = 0; ix < normalizedArgs.length; ix++) { + if (normalizedArgs[ix] in options) { // increment the counter to move past the option that was found. should now be positioned on the // first argument to that option ix++ def parsedSet = [] - for (ix; ix < args.length; ix++) { + for (ix; ix < normalizedArgs.length; ix++) { // this is a do nothing as there's no arguments to the option or it's the start of a new option - if (cli.options.options.any { "-" + it.opt == args[ix] || "--" + it.longOpt == args[ix] }) { + if (cli.options.options.any { "-" + it.opt == normalizedArgs[ix] || "--" + it.longOpt == normalizedArgs[ix] }) { // rollback the counter now that we hit the next option ix-- - break; + break } - parsedSet << args[ix] + parsedSet << normalizedArgs[ix] } if (!parsedSet.isEmpty()) { @@ -518,4 +519,15 @@ class Console { return parsed } + + /** + * The {@code args} value contains the individual flagged parameters provided on the command line which may come + * with or without an "=" to separate the flag from the argument to the flag. This method normalizes these values + * to split the flag from the argument so that it can be evaluated in a consistent way by {@code parseArgs()}. + */ + private static def normalizeArgs(final List<String> options, final String[] args) { + return args.collect{ arg -> options.any{ + arg.startsWith(it) } ? arg.split("=", 2) : arg + }.flatten().toArray() + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/352d06e5/gremlin-console/src/test/python/tests/test_console.py ---------------------------------------------------------------------- diff --git a/gremlin-console/src/test/python/tests/test_console.py b/gremlin-console/src/test/python/tests/test_console.py index 67e1a9e..88c1a05 100644 --- a/gremlin-console/src/test/python/tests/test_console.py +++ b/gremlin-console/src/test/python/tests/test_console.py @@ -41,6 +41,14 @@ class TestConsole(object): TestConsole._expect_prompt(child) TestConsole._close(child) + def test_just_dash_i_with_equals(self): + child = pexpect.spawn(TestConsole.gremlinsh + "-i=x.script") + TestConsole._expect_gremlin_header(child) + TestConsole._send(child, "x") + child.expect("==>2\r\n") + TestConsole._expect_prompt(child) + TestConsole._close(child) + def test_just_dash_dash_interactive(self): child = pexpect.spawn(TestConsole.gremlinsh + "--interactive x.script") TestConsole._expect_gremlin_header(child) @@ -65,8 +73,16 @@ class TestConsole(object): TestConsole._expect_prompt(child) TestConsole._close(child) + def test_dash_dash_interactive_with_args_and_equals(self): + child = pexpect.spawn(TestConsole.gremlinsh + "--interactive=\"y.script 1 2 3\"") + TestConsole._expect_gremlin_header(child) + TestConsole._send(child, "y") + child.expect("==>6\r\n") + TestConsole._expect_prompt(child) + TestConsole._close(child) + def test_dash_i_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "-i y.script 1 2 3 -i x.script -i \"z.script x -i --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "-i y.script 1 2 3 -i x.script -i \"z.script x -i = --color -D\"") TestConsole._expect_gremlin_header(child) TestConsole._send(child, "y") child.expect("==>6\r\n") @@ -75,12 +91,12 @@ class TestConsole(object): child.expect("==>2\r\n") TestConsole._expect_prompt(child) TestConsole._send(child, "z") - child.expect("==>argument=\[x, -i, --color, -D\]\r\n") + child.expect("==>argument=\[x, -i, =, --color, -D\]\r\n") TestConsole._expect_prompt(child) TestConsole._close(child) def test_dash_dash_interactive_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "--interactive y.script 1 2 3 --interactive x.script -i \"z.script x -i --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "--interactive y.script 1 2 3 --interactive x.script -i \"z.script x -i = --color -D\"") TestConsole._expect_gremlin_header(child) TestConsole._send(child, "y") child.expect("==>6\r\n") @@ -89,12 +105,12 @@ class TestConsole(object): child.expect("==>2\r\n") TestConsole._expect_prompt(child) TestConsole._send(child, "z") - child.expect("==>argument=\[x, -i, --color, -D\]\r\n") + child.expect("==>argument=\[x, -i, =, --color, -D\]\r\n") TestConsole._expect_prompt(child) TestConsole._close(child) def test_mixed_interactive_long_short_opts_with_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "--interactive y.script 1 2 3 --interactive x.script -i \"z.script x -i --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "--interactive y.script 1 2 3 --interactive x.script -i \"z.script x -i = --color -D\"") TestConsole._expect_gremlin_header(child) TestConsole._send(child, "y") child.expect("==>6\r\n") @@ -103,7 +119,7 @@ class TestConsole(object): child.expect("==>2\r\n") TestConsole._expect_prompt(child) TestConsole._send(child, "z") - child.expect("==>argument=\[x, -i, --color, -D\]\r\n") + child.expect("==>argument=\[x, -i, =, --color, -D\]\r\n") TestConsole._expect_prompt(child) TestConsole._close(child) @@ -128,24 +144,24 @@ class TestConsole(object): TestConsole._close(child) def test_dash_e_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "-e y-printed.script 1 2 3 -e x-printed.script -e \"z-printed.script x -e --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "-e y-printed.script 1 2 3 -e x-printed.script -e \"z-printed.script x -e = --color -D\"") child.expect("6\r\n") child.expect("2\r\n") - child.expect("argument=\[x, -e, --color, -D\]\r\n") + child.expect("argument=\[x, -e, =, --color, -D\]\r\n") TestConsole._close(child) def test_dash_dash_execute_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "--execute y-printed.script 1 2 3 --execute x-printed.script --execute \"z-printed.script x -e --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "--execute y-printed.script 1 2 3 --execute x-printed.script --execute \"z-printed.script x -e = --color -D\"") child.expect("6\r\n") child.expect("2\r\n") - child.expect("argument=\[x, -e, --color, -D\]\r\n") + child.expect("argument=\[x, -e, =, --color, -D\]\r\n") TestConsole._close(child) def test_mixed_execute_long_short_opts_with_multiple_scripts(self): - child = pexpect.spawn(TestConsole.gremlinsh + "--execute y-printed.script 1 2 3 -e x-printed.script --execute \"z-printed.script x -e --color -D\"") + child = pexpect.spawn(TestConsole.gremlinsh + "--execute y-printed.script 1 2 3 -e x-printed.script --execute \"z-printed.script x -e = --color -D\"") child.expect("6\r\n") child.expect("2\r\n") - child.expect("argument=\[x, -e, --color, -D\]\r\n") + child.expect("argument=\[x, -e, =, --color, -D\]\r\n") TestConsole._close(child) def test_no_mix_dash_i_and_dash_e(self):
