File indexing completed on 2024-05-12 05:12:42

0001 /*
0002     Copyright (C) 2012  Kevin Krammer <krammer@kde.org>
0003 
0004     This program is free software; you can redistribute it and/or modify
0005     it under the terms of the GNU General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or
0007     (at your option) any later version.
0008 
0009     This program is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012     GNU General Public License for more details.
0013 
0014     You should have received a copy of the GNU General Public License along
0015     with this program; if not, write to the Free Software Foundation, Inc.,
0016     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0017 */
0018 
0019 #include "abstractcommand.h"
0020 #include "commandrunner.h"
0021 #include "errorreporter.h"
0022 
0023 #include <KAboutData>
0024 #include <KLocalizedString>
0025 
0026 #include <QCoreApplication>
0027 #include <QCommandLineParser>
0028 
0029 #include <iostream>
0030 
0031 #include "version.h"
0032 
0033 const char *appname = "akonadiclient";
0034 
0035 int main(int argc, char **argv)
0036 {
0037     // Need this before any use of i18n() or similar
0038     // TODO: should we allow commands to optionally support GUI?
0039     QCoreApplication application(argc, argv);
0040 
0041     KAboutData aboutData(appname,                           // componentName
0042                          i18nc("@title program name", "Akonadi Client"),        // displayName
0043 #ifdef VCS_HAVE_VERSION
0044                          (VERSION " (" VCS_TYPE_STRING " " VCS_REVISION_STRING ")"),    // version
0045 #else
0046                          VERSION,                           // version
0047 #endif
0048                          i18nc("@info:shell short description", "A command-line/shell client for Akonadi"),
0049                                                          // shortDescription
0050                          KAboutLicense::GPL);                        // licenseType
0051 
0052     aboutData.addAuthor(i18n("Kevin Krammer"), i18nc("@title about data task", "Original Author"), "krammer@kde.org");
0053     aboutData.addAuthor(i18n("Jonathan Marten"), i18nc("@title about data task", "Additions and new commands"), "jjm@keelhaul.me.uk");
0054     aboutData.addAuthor(i18n("Bhaskar Kandiyal"), i18nc("@title about data task", "New commands, GSOC 2014"), "bkandiyal@gmail.com");
0055 
0056     KAboutData::setApplicationData(aboutData);
0057 
0058     QCommandLineParser parser;
0059     parser.setApplicationDescription(aboutData.shortDescription());
0060     parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
0061     parser.addHelpOption();
0062     parser.addVersionOption();
0063 
0064     parser.addPositionalArgument("command", i18nc("@info:shell", "Command to execute"));
0065     parser.addPositionalArgument("options", i18nc("@info:shell", "Options for command"),
0066                                             i18nc("@info:shell", "[options]"));
0067     parser.addPositionalArgument("args", i18nc("@info:shell", "Arguments for command"),
0068                                          i18nc("@info:shell", "[args]"));
0069 
0070     // Just parse the command line and options, do not do any actions
0071     bool ok = parser.parse(QCoreApplication::arguments());
0072 
0073     // Handle parser errors and global application options here.
0074     // They would normally be handled automatically by QCommandLineParser::process(),
0075     // but we need to keep control so that the additional help text as below
0076     // can be displayed.
0077 
0078     if (!ok) {
0079         ErrorReporter::fatal(parser.errorText());
0080     }
0081 
0082     if (parser.isSet("help")) {
0083         std::cout << qPrintable(parser.helpText()); // does not exit application
0084         std::cout << std::endl;             // so can print extra
0085         std::cout << qPrintable(i18nc("@info:shell",
0086                                       "See '%1 help' for available commands."
0087                                       "\n"
0088                                       "See '%1 help command' for information on a specific command.",
0089                                       appname));
0090         std::cout << std::endl;
0091         return (EXIT_SUCCESS);              // and then exit
0092     }
0093 
0094     if (parser.isSet("version")) {
0095         parser.showVersion();               // exits the application
0096     }
0097 
0098     // The QCommandLineParser::positionalArguments() remaining are the
0099     // command name followed by any options or arguments.  An empty list
0100     // (no command specified) is handled by CommandFactory::checkAndHandleHelp().
0101     const QStringList args = parser.positionalArguments();
0102 
0103     CommandRunner runner(&args);
0104     int ret = runner.start();
0105     if (ret != AbstractCommand::NoError) return ret;
0106 
0107     ErrorReporter::setRunningApplication();
0108     // Something odd seems to happen here.  If the processing loop is run
0109     // with multiple (more than 1) arguments then the exit code eventually
0110     // given to QCoreApplication::exit() by CommandRunner::onCommandFinished()
0111     // is not returned by QCoreApplication::exec(), it always returns 0.
0112     // If there is only one argument then the code is returned correctly.
0113     // Retrieve the accumulated exit code directly from the CommandRunner
0114     // instead.
0115     application.exec();
0116     return (runner.exitCode());
0117 }