From b3bb56b2cbb5e67aa0675f4e12a0a797f3963278 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Fri, 20 Mar 2015 16:54:00 +0300 Subject: [PATCH] Mandatory arguments are displayed in [], optional in <>, option argumnets are supported as well for manage.py command (for PY-11855) --- .../commandInterface/command/Option.java | 1 + .../console/MissingArgumentDisplayer.java | 29 +++++++++++++++- .../psi/ValidationResultImpl.java | 7 ++++ .../com/jetbrains/python/PyBundle.properties | 2 +- .../gnuCommandLine/CommandLineArgsTest.java | 33 +++++++++++++++---- .../gnuCommandLine/CommandTestTools.java | 2 +- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/python/src/com/jetbrains/commandInterface/command/Option.java b/python/src/com/jetbrains/commandInterface/command/Option.java index 01f7f0e3cf69..c652d1cd951c 100644 --- a/python/src/com/jetbrains/commandInterface/command/Option.java +++ b/python/src/com/jetbrains/commandInterface/command/Option.java @@ -88,6 +88,7 @@ public final class Option { // TODO: USe "known arguments info" to prevent copy/paste /** * @return if option accepts argument -- pair of [argument_quantity, argument]. Null otherwise. + * Unlike position argument, option argument is always mandatory */ @Nullable public Pair getArgumentAndQuantity() { diff --git a/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java b/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java index bfec19aad867..9fddf05ee9de 100644 --- a/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java +++ b/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java @@ -42,6 +42,17 @@ import java.awt.*; */ final class MissingArgumentDisplayer extends JPanel implements Listener { + /** + * Braces for mandatory args are [] according to GNU/POSIX recommendations + */ + @NotNull + private static final Pair MANDATORY_ARG_BRACES = Pair.create("[", "]"); + /** + * Braces for optional args are <> according to GNU/POSIX recommendations + */ + @NotNull + private static final Pair OPTIONAL_ARG_BRACES = Pair.create("<", ">"); + /** * Number of places after end of line before argument place */ @@ -134,7 +145,23 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { final boolean required = nextArg.first; final String argumentText = nextArg.second.getHelpText(); g.setColor((required ? JBColor.red : JBColor.gray)); - g.drawString((StringUtil.isEmpty(argumentText) ? PyBundle.message("commandLine.missingArgument.defaultName") : argumentText), x, y); + final String textToShow = StringUtil.isEmpty(argumentText) ? PyBundle.message("commandLine.missingArgument.defaultName") : argumentText; + g.drawString(wrapBracesIfNeeded(required, textToShow), x, y); + } + + /** + * Adds appropriate braces to argument help text if needed + * @param required is argument required + * @param textToShow arg help text + * @return text to show + */ + @NotNull + private static String wrapBracesIfNeeded(final boolean required, @NotNull final String textToShow) { + if (textToShow.startsWith(MANDATORY_ARG_BRACES.first) || textToShow.startsWith(OPTIONAL_ARG_BRACES.first)) { + return textToShow; + } + final Pair braces = (required ? MANDATORY_ARG_BRACES : OPTIONAL_ARG_BRACES); + return String.format("%s%s%s", braces.first, textToShow, braces.second); } diff --git a/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java index 82adde5618a0..f0be669c61bf 100644 --- a/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java +++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java @@ -225,6 +225,13 @@ final class ValidationResultImpl extends CommandLineVisitor implements Validatio @Nullable @Override public Pair getNextArg() { + if (myCurrentOptionAndArgsLeft != null && myCurrentOptionAndArgsLeft.second > 0) { // Next arg is option arg + final Pair argumentAndQuantity = myCurrentOptionAndArgsLeft.first.getArgumentAndQuantity(); + if (argumentAndQuantity != null) { + // Option argument is always mandatory: https://docs.python.org/2/library/optparse.html#terminology + return Pair.create(true, argumentAndQuantity.second); + } + } return myCommand.getArgumentsInfo().getArgument(myCurrentPositionArgument); } } diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 5b7f8dae45ce..ece483d61fbb 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -871,5 +871,5 @@ commandLine.inspection.badOption=Bad or unknown option. make sure this option re commandLine.inspection.badArgument=Argument can't have this value. use autocompletion to check list of possible values. commandLine.inspection.excessArgument=Excess argument or argument is not possible here # What to display if argument is available here, but no name provided -commandLine.missingArgument.defaultName=[arguments] +commandLine.missingArgument.defaultName=arguments diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineArgsTest.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineArgsTest.java index 50234744d995..9848010fedc9 100644 --- a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineArgsTest.java +++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineArgsTest.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.Pair; import com.jetbrains.commandInterface.command.Argument; import com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile; import com.jetbrains.python.fixtures.PyTestCase; +import org.jetbrains.annotations.NotNull; import org.junit.Assert; @@ -33,13 +34,15 @@ public final class CommandLineArgsTest extends PyTestCase { */ public void testArgsRequired() throws Exception { CommandTestTools.initFileType(); - final CommandLineFile file = CommandTestTools.createFileByText(myFixture, "command"); - final ValidationResult validationResult = file.getValidationResult(); - assert validationResult != null : "validation failed"; - final Pair arg = validationResult.getNextArg(); - Assert.assertNotNull("No argument returned, but should", arg); - Assert.assertTrue("Required argument is not marked as required", arg.first); - Assert.assertEquals("Wrong argument text", "positional_argument", arg.second.getHelpText()); + validateNextArgument("command", "positional_argument"); + } + + /** + * Ensures option argument is returned if exists + */ + public void testOptionArgsRequired() throws Exception { + CommandTestTools.initFileType(); + validateNextArgument("command positional_argument --available-option", "option argument"); } /** @@ -52,4 +55,20 @@ public final class CommandLineArgsTest extends PyTestCase { assert validationResult != null : "validation failed"; Assert.assertNull("Argument returned while should not", validationResult.getNextArg()); } + + + /** + * Runs commands and checks argument is required after it + * @param commandText command text to run + * @param expectedArgumentText expected next argument help text + */ + private void validateNextArgument(@NotNull final String commandText, @NotNull final String expectedArgumentText) { + final CommandLineFile file = CommandTestTools.createFileByText(myFixture, commandText); + final ValidationResult validationResult = file.getValidationResult(); + assert validationResult != null : "validation failed"; + final Pair arg = validationResult.getNextArg(); + Assert.assertNotNull("No argument returned, but should", arg); + Assert.assertTrue("Required argument is not marked as required", arg.first); + Assert.assertEquals("Wrong argument text", expectedArgumentText, arg.second.getHelpText()); + } } diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java index 960ca996c8d0..e026f2c2823c 100644 --- a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java +++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java @@ -58,7 +58,7 @@ final class CommandTestTools { final List