From d490a1ac09a1d1a3c547af2deee7f0c0b9ec2cbc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Nov 2024 09:12:00 -0800 Subject: [PATCH] QCommandLineParser: include the positional arguments' sizes in --help We were mostly ignoring them because it looks like most people's options were longer than their positional arguments. The rest must have just accepted the enforced wrapping. But if you have very short options like single-letter only ones or none at all, the positional argument wrapping is unnecessarily short. [ChangeLog][QtCore][QCommandLineParser] Made it so the positional argument descriptions are taken into account in the aligning of text for helpText(). Fixes: QTBUG-131716 Change-Id: Ib1eee62c7cf4462f6a26fffdec233ba849ebf158 Reviewed-by: David Faure (cherry picked from commit 8928b0fbb9ca4caf9b63a32b3d2a73a6da096755) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 55a46ec005894394031efbee1b9c2269bb1d8eea) --- src/corelib/tools/qcommandlineparser.cpp | 5 ++++ .../tst_qcommandlineparser.cpp | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 863cf0ca6ce..f1159fe9aa9 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -1122,6 +1122,7 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const text += nl; if (!options.isEmpty()) text += QCommandLineParser::tr("Options:") + nl; + QStringList optionNameList; optionNameList.reserve(options.size()); qsizetype longestOptionNameString = 0; @@ -1142,6 +1143,10 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const optionNameList.append(optionNamesString); longestOptionNameString = qMax(longestOptionNameString, optionNamesString.size()); } + + for (const PositionalArgumentDefinition &arg : positionalArgumentDefinitions) + longestOptionNameString = qMax(longestOptionNameString, arg.name.size()); + ++longestOptionNameString; const int optionNameMaxWidth = qMin(50, int(longestOptionNameString)); auto optionNameIterator = optionNameList.cbegin(); diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp index 812cf2d1b3d..44baba98a2f 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp @@ -101,8 +101,21 @@ void tst_QCommandLineParser::testPositionalArguments() { QCoreApplication app(empty_argc, empty_argv); QCommandLineParser parser; + const QString exeName = QCoreApplication::instance()->arguments().first(); // e.g. debug\tst_qcommandlineparser.exe on Windows + QString expectedNoPositional = + "Usage: " + exeName + "\n" + "\n"; + + QCOMPARE(parser.helpText(), expectedNoPositional); QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "file.txt")); QCOMPARE(parser.positionalArguments(), QStringList() << QStringLiteral("file.txt")); + + parser.addPositionalArgument("file", "File names", ""); + QString expected = + "Usage: " + exeName + " \n" + "\n" + "Arguments:\n" + " file File names\n"; } void tst_QCommandLineParser::testBooleanOption_data() @@ -159,7 +172,18 @@ void tst_QCommandLineParser::testOptionsAndPositional() QCoreApplication app(empty_argc, empty_argv); QCommandLineParser parser; + const QString exeName = QCoreApplication::instance()->arguments().first(); // e.g. debug\tst_qcommandlineparser.exe on Windows + const QString expectedHelpText = + "Usage: " + exeName + " [options] input\n" + "\n" + "Options:\n" + " -b a boolean option\n" + "\n" + "Arguments:\n" + " input File names\n"; + parser.setOptionsAfterPositionalArgumentsMode(parsingMode); + parser.addPositionalArgument("input", "File names"); QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("b"), QStringLiteral("a boolean option")))); QVERIFY(parser.parse(args)); QCOMPARE(parser.optionNames(), expectedOptionNames); @@ -167,6 +191,7 @@ void tst_QCommandLineParser::testOptionsAndPositional() QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not expecting values: \"b\""); QCOMPARE(parser.values("b"), QStringList()); QCOMPARE(parser.positionalArguments(), expectedPositionalArguments); + QCOMPARE(parser.helpText(), expectedHelpText); } void tst_QCommandLineParser::testMultipleNames_data()