Commit 9591f314 authored by Lisa's avatar Lisa

First draft of the new command line parsing system

parent e343ac82
project(akabei)
cmake_minimum_required(VERSION 2.6)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
find_package(KDE4 REQUIRED)
find_package(AkabeiClient REQUIRED)
find_package(AkabeiCore REQUIRED)
include (KDE4Defaults)
include (MacroLibrary)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
include_directories(${QT_INCLUDES}
${CMAKE_CURRENT_BINARY_DIR}
${KDE4_INCLUDE_DIR}
${AKABEICLIENT_INCLUDE_DIR}
${AKABEICORE_INCLUDE_DIR})
set(apm_SRCS queueoperation.cpp upgradeoperation.cpp removeoperation.cpp syncoperation.cpp apm.cpp queryoperation.cpp main.cpp)
set(apm_SRCS queueoperation.cpp upgradeoperation.cpp removeoperation.cpp syncoperation.cpp apm.cpp queryoperation.cpp cmdline.cpp main.cpp)
#qt4_automoc(${guzuta_SRCS})
kde4_add_executable(akabei ${apm_SRCS})
target_link_libraries(akabei ${KDE4_KDEUI_LIBRARY} ${KDE4_KIO_LIBRARY} ${AKABEICLIENT_LIBRARIES})
......
......@@ -22,10 +22,10 @@
#include <QCoreApplication>
#include <QTimer>
APM::APM(OperationType type, QList<Operation> operations, QMultiHash<Operation, QString> options, QStringList args, QObject * parent)
OperationManager::OperationManager(APM::OperationType type, APM::OperationName operation, QHash<APM::OptionName, AkabeiOption> options, QStringList args, QObject * parent)
: QObject(parent),
m_operationType(type),
m_operations(operations),
m_type(type),
m_operation(operation),
m_options(options),
m_args(args)
{
......@@ -33,43 +33,55 @@ APM::APM(OperationType type, QList<Operation> operations, QMultiHash<Operation,
//QCoreApplication::instance()->quit();
//QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit()));
connect(AkabeiClient::Backend::instance(), SIGNAL(statusChanged(Akabei::Backend::Status)), SLOT(statusChanged(Akabei::Backend::Status)));
QString root = options.value(APM::RootDir);
QString cache = options.value(APM::CacheDir);
QString dbs = options.value(APM::DBPath);
QString root = ".";
QString cache = ".";
QString dbs = ".";
if (options.contains(APM::RootDir)) {
root = options[APM::RootDir].args[0];
}
if (options.contains(APM::CacheDir)) {
cache = options[APM::CacheDir].args[0];
}
if (options.contains(APM::DBPath)) {
dbs = options[APM::DBPath].args[0];
}
AkabeiClient::Backend::instance()->initialize(root, cache, dbs);
}
APM::~APM()
{}
OperationManager::~OperationManager()
{
}
void APM::statusChanged(Akabei::Backend::Status status)
void OperationManager::statusChanged(Akabei::Backend::Status status)
{
if (status == Akabei::Backend::StatusReady)
start();
}
void APM::start()
void OperationManager::start()
{
switch (m_operationType) {
case QueryOperationType: {
switch (m_type) {
case APM::QueryOperationType: {
QueryOperation * query = new QueryOperation(this);
query->start(m_operations, m_options, m_args);
query->start(m_operation, m_options, m_args);
break;
}
case RemoveOperationType: {
case APM::RemoveOperationType: {
RemoveOperation * remove = new RemoveOperation(this);
remove->start(m_operations, m_options, m_args);
remove->start(m_operation, m_options, m_args);
break;
}
case SyncOperationType: {
case APM::SyncOperationType: {
SyncOperation * sync = new SyncOperation(this);
sync->start(m_operations, m_options, m_args);
sync->start(m_operation, m_options, m_args);
break;
}
case UpgradeOperationType: {
case APM::UpgradeOperationType: {
UpgradeOperation * upgrade = new UpgradeOperation(this);
upgrade->start(m_operations, m_options, m_args);
upgrade->start(m_operation, m_options, m_args);
break;
}
default:
......
......@@ -15,74 +15,23 @@
#include <QtCore/QObject>
#include <QStringList>
class APM : public QObject
#include "cmdline.h"
class OperationManager : public QObject
{
Q_OBJECT
public:
enum OperationType {
NoType = 0,
DatabaseOperationType = 1,
QueryOperationType = 2,
RemoveOperationType = 3,
SyncOperationType = 4,
UpgradeOperationType = 5
};
enum Operation {
NoOperation = 0,
///Query operations
ShowChangelog,
ShowInstalledAsDeps,
ShowInstalledExplicitely,
ShowPackagesOfGroup, //Also in Sync
ShowInformation, //Also in Sync
CheckFiles,
ShowLocal,
ShowOwner,
QueryPackageFile,
SearchLocal,
ShowNotRequired,
ShowUpgradeable,
ShowLess,
///Sync operations
Install,
AsDeps,//Also in upgrade
AsExplicit,//Also in upgrade
RemoveOldPackages,
RemoveAllPackages,
SkipDependencyCheck,//Also in Remove/Upgrade
Force,//Also in upgrade
ListRepo,
Search,
DownloadOnly,
OnlyNeeded,
Ignore,
IgnoreGroup,
UpdateDatabases,
UpdateSystem,
///Remove operations
Remove,
Cascade,
DatabaseOnly,//Also in upgrade
RemoveConfig,
Recursive,
Unneeded,
///Upgrade operation makes only use of operations specified above
///Random
RootDir,
CacheDir,
DBPath
};
explicit APM(OperationType type, QList<Operation> operations, QMultiHash<Operation, QString> options, QStringList args, QObject* parent = 0);
virtual ~APM();
explicit OperationManager(APM::OperationType type, APM::OperationName operation, QHash<APM::OptionName, AkabeiOption> options, QStringList args, QObject* parent = 0);
virtual ~OperationManager();
private slots:
void statusChanged(Akabei::Backend::Status);
void start();
private:
OperationType m_operationType;
QList<Operation> m_operations;
QMultiHash<Operation, QString> m_options;
APM::OperationType m_type;
APM::OperationName m_operation;
QHash<APM::OptionName, AkabeiOption> m_options;
QStringList m_args;
};
......
/* This file is part of the Chakra project
Copyright (C) 2011 Lisa "shainer" Vitolo <shainer@chakra-project.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "cmdline.h"
#include <kaboutdata.h>
#include <klocalizedstring.h>
#include <QDebug>
/*
* Build our database of accepted operations and options with the right properties and associations
*/
CmdLine::CmdLine()
: parsed(false)
{
typechars.insert("D", APM::DatabaseOperationType);
typechars.insert("Q", APM::QueryOperationType);
typechars.insert("R", APM::RemoveOperationType);
typechars.insert("S", APM::SyncOperationType);
typechars.insert("U", APM::UpgradeOperationType);
/*
* The argument list is only meaningful after reading the command line, so for now it stays empty
*/
AkabeiOption querypkgfile(APM::QueryPackageFile, "p", "file", "Queries a package file instead of the database", true);
AkabeiOption showlocal(APM::ShowLocal, "m", "foreign", "Shows packages which were not found in the Sync-db(s)", false);
AkabeiOption showless(APM::ShowLess, "q", "quiet", "Shows less information in queries and searches", false);
AkabeiOption installasdeps(APM::InstallAsDeps, "", "asdeps", "Install all packages as non-explicit", false);
AkabeiOption installasexplicit(APM::InstallAsExplicit, "", "asexplicit", "APM::Install all packages as explicit", false);
AkabeiOption skipdependencycheck(APM::SkipDependencyCheck, "w", "nodeps", "Skip dependency check", false);
AkabeiOption force(APM::Force, "f", "force", "Force installation. Overwrite file conflicts", false);
AkabeiOption downloadonly(APM::DownloadOnly, "d", "downloadonly", "Downloads packages without installing or upgrading them", false);
AkabeiOption onlyneeded(APM::OnlyNeeded, "", "needed", "Up-to-date packages are not reinstalled", false);
AkabeiOption ignore(APM::Ignore, "", "ignore", "Ignores a certain package. Can be used more than once.", true);
AkabeiOption ignoregroup(APM::IgnoreGroup, "", "ignoregroup", "Ignores upgrade of a group", true);
AkabeiOption databaseonly(APM::DatabaseOnly, "k", "dbonly", "Only remove database entries", false);
AkabeiOption removeconfig(APM::RemoveConfig, "n", "nosave", "Also remove configuration files", false);
AkabeiOption recursive(APM::Recursive, "s", "recursive", "Remove dependencies as well. (-ss includes explicitely installed dependencies)", false);
AkabeiOption rootdir(APM::RootDir, "", "root", "Set a different root dir", true);
AkabeiOption cachedir(APM::CacheDir, "", "cachedir", "Set a different cache dir", true);
AkabeiOption dbpath(APM::DBPath, "b", "dbpath", "Set a different database dir", false);
acceptedOptions << querypkgfile << showlocal << showless << installasdeps << installasexplicit << skipdependencycheck;
acceptedOptions << force << downloadonly << onlyneeded << ignore << ignoregroup << databaseonly << removeconfig << recursive;
acceptedOptions << rootdir << cachedir << dbpath;
AkabeiOperation database(APM::DatabaseOperationType, APM::DatabaseOperation, "D", "", "", false);
AkabeiOperation changelog(APM::QueryOperationType, APM::ShowChangelog, "c", "changelog", "Shows changelog of the package", true);
changelog.addOption(querypkgfile);
AkabeiOperation installedasdeps(APM::QueryOperationType, APM::ShowInstalledAsDeps, "d", "deps", "Shows packages which got installed as dependencies", false);
installedasdeps.addOption(querypkgfile);
installedasdeps.addOption(ignore);
installedasdeps.addOption(ignoregroup);
AkabeiOperation installedexp(APM::QueryOperationType, APM::ShowInstalledExplicitely, "e", "explicit", "Shows packages which got installed explicitely", false);
installedexp.addOption(querypkgfile);
installedexp.addOption(ignore);
installedexp.addOption(ignoregroup);
AkabeiOperation checkfiles(APM::QueryOperationType, APM::CheckFiles, "k", "check", "Check if the files of the package are available", true);
checkfiles.addOption(querypkgfile);
checkfiles.addOption(showlocal);
AkabeiOperation showowner(APM::QueryOperationType, APM::ShowOwner, "o", "owns", "Returns the package which contains the file", true);
showowner.addOption(querypkgfile);
showowner.addOption(showlocal);
AkabeiOperation notrequired(APM::QueryOperationType, APM::ShowNotRequired, "t", "unrequired", "Returns packages which are not required by others", false);
notrequired.addOption(querypkgfile);
notrequired.addOption(ignore);
notrequired.addOption(ignoregroup);
AkabeiOperation upgradeable(APM::QueryOperationType, APM::ShowUpgradeable, "u", "upgrades", "Returns upgradeable packages", false);
upgradeable.addOption(querypkgfile);
upgradeable.addOption(ignore);
upgradeable.addOption(ignoregroup);
AkabeiOperation groupsl(APM::QueryOperationType, APM::ShowPackagesOfGroupLocal, "g", "groups", "Shows all packages in a package group", true);
groupsl.addOption(ignore);
AkabeiOperation infol(APM::QueryOperationType, APM::ShowInformationLocal, "i", "info", "Shows package information", true);
infol.addOption(showless);
AkabeiOperation searchl(APM::QueryOperationType, APM::SearchLocal, "s", "search", "Searches repositories for a word", true);
searchl.addOption(ignore);
searchl.addOption(ignoregroup);
AkabeiOperation remove(APM::RemoveOperationType, APM::Remove, "R", "remove", "Remove packages", true);
remove.addOption(skipdependencycheck);
remove.addOption(force);
remove.addOption(databaseonly);
remove.addOption(removeconfig);
remove.addOption(recursive);
AkabeiOperation cascade(APM::RemoveOperationType, APM::Cascade, "c", "cascade", "Remove packages with their dependencies", true);
AkabeiOperation unneeded(APM::RemoveOperationType, APM::Unneeded, "u", "unneeded", "Remove not needed packages", false);
unneeded.addOption(ignore);
unneeded.addOption(ignoregroup);
AkabeiOperation install(APM::SyncOperationType, APM::Install, "S", "install", "Install packages", true);
install.addOption(installasdeps);
install.addOption(installasexplicit);
install.addOption(skipdependencycheck);
install.addOption(force);
install.addOption(downloadonly);
install.addOption(onlyneeded);
AkabeiOperation removeold(APM::SyncOperationType, APM::RemoveOldFromCache, "c", "clean", "Remove old packages from cache", false);
AkabeiOperation removeallcache(APM::SyncOperationType, APM::RemoveAllCache, "cc", "", "Remove all packages from cache", false);
AkabeiOperation groups(APM::SyncOperationType, APM::ShowPackagesOfGroup, "g", "groups", "Shows all packages in a package group", true);
groups.addOption(ignore);
AkabeiOperation info(APM::SyncOperationType, APM::ShowInformation, "i", "info", "Shows package information", true);
info.addOption(showless);
AkabeiOperation search(APM::SyncOperationType, APM::Search, "s", "search", "Searches repositories for a word", true);
search.addOption(ignore);
search.addOption(ignoregroup);
AkabeiOperation listrepo(APM::SyncOperationType, APM::ListRepo, "l", "list", "List all packages in a repository", true);
listrepo.addOption(querypkgfile);
listrepo.addOption(showlocal);
listrepo.addOption(ignore);
listrepo.addOption(ignoregroup);
AkabeiOperation updatedb(APM::SyncOperationType, APM::UpdateDatabases, "y", "refresh", "Refresh database", false);
AkabeiOperation updatesys(APM::SyncOperationType, APM::UpdateSystem, "u", "sysupgrade", "Update system", false);
updatesys.addOption(downloadonly);
updatesys.addOption(ignore);
updatesys.addOption(ignoregroup);
AkabeiOperation updatedbandsys(APM::SyncOperationType, APM::UpdateDatabaseAndSystem, "", "", "Refresh database and update system", false);
updatedbandsys.addOption(downloadonly);
updatedbandsys.addOption(ignore);
updatedbandsys.addOption(ignoregroup);
AkabeiOperation upgrade(APM::UpgradeOperationType, APM::Upgrade, "U", "", "Upgrade operation", true);
upgrade.addOption(downloadonly);
upgrade.addOption(ignore);
upgrade.addOption(ignoregroup);
AkabeiOperation help(APM::NoType, APM::Help, "h", "help", "Shows the help message", false);
AkabeiOperation version(APM::NoType, APM::Version, "v", "version", "Shows Akabei version", false);
AkabeiOperationList tmp2;
tmp2 << removeallcache << install << remove << database << changelog << installedasdeps << installedexp;
tmp2 << checkfiles << showowner << notrequired << upgradeable << cascade;
tmp2 << removeold << groups << info << listrepo << groupsl << searchl << infol;
tmp2 << search << updatedb << updatesys << updatedbandsys << upgrade << help << version;
foreach (AkabeiOperation op, tmp2) {
/* These options are associated to every operation */
op.addOption(rootdir);
op.addOption(cachedir);
op.addOption(dbpath);
/*
* This hash associating command (often the short one) and operation is useful later because
* one command can be associated to more operations and even options
*/
QByteArray command = (op.commandShort.isEmpty()) ? op.commandLong : op.commandShort;
acceptedOperations.insertMulti(command, op);
}
}
AkabeiOption::AkabeiOption(APM::OptionName n, const char *cs, const char *cl, const char *desc, bool hasArg)
{
QStringList unused;
init(n, cs, cl, desc, hasArg, unused);
}
AkabeiOption::AkabeiOption(APM::OptionName n, const char *cs, const char *cl, const char *desc, bool hasArg, QStringList a)
{
init(n, cs, cl, desc, hasArg, a);
}
void AkabeiOption::init(APM::OptionName n, const char *cs, const char *cl, const char *desc, bool hasArg, QStringList a)
{
name = n;
commandShort = QString::fromAscii(cs).toUtf8();
commandLong = QString::fromAscii(cl).toUtf8();
description = ki18n(desc);
this->hasArg = hasArg;
this->args = a;
}
AkabeiOperation::AkabeiOperation(APM::OperationType t, APM::OperationName n, const char *cs, const char *cl, const char *desc, bool hasFreeArgs)
{
QStringList args;
init(t, n, cs, cl, desc, hasFreeArgs, args);
}
AkabeiOperation::AkabeiOperation(APM::OperationType t, APM::OperationName n, const char *cs, const char *cl, const char *desc, bool hasFreeArgs, QStringList args)
{
init(t, n, cs, cl, desc, hasFreeArgs, args);
}
AkabeiOperation::AkabeiOperation()
{
init(APM::NoType, APM::None, "", "", "", false, QStringList());
}
/*
* This requires some explanation (and maybe some polishing)
*
* 0: APM::None means no operation has still been set, so no problem here.
* 1: -S is Install, but for example -Ss is Search. Same for most removing operations. This overlapping is fine.
* 2: the elements in a hash aren't sorted, so "s" may be found before "S".
* 3: for -Scc, both "cc" and "c" are found. Only the first one is good.
* 4: -Sy is UpdateDatabases, -Su is UpdateSystem, but -Syu is APM::UpdateDatabaseAndSystem (only linked operations accepted).
* 5: All the rest is invalid
*/
void AkabeiOperation::set(AkabeiOperation& other)
{
if ((this->type == APM::SyncOperationType && other.name == APM::Install) || (this->type == APM::RemoveOperationType && other.name == APM::Remove) || (this->name == APM::RemoveAllCache && other.commandShort == "c")) {
return;
}
if (this->name == APM::None || this->name == APM::Remove || this->name == APM::Install) {
this->name = other.name;
this->type = other.type;
this->options = other.options;
this->hasFreeArgs = other.hasFreeArgs;
} else if ((this->name == APM::UpdateDatabases && other.name == APM::UpdateSystem) || (this->name == APM::UpdateSystem && other.name == APM::UpdateDatabases)) {
this->name = APM::UpdateDatabaseAndSystem;
this->type = APM::SyncOperationType;
this->hasFreeArgs = false;
} else {
throw CmdLineException("Multiple operations present.");
}
}
void AkabeiOperation::init(APM::OperationType t, APM::OperationName n, const char *cs, const char *cl, const char *desc, bool hasFreeArgs, QStringList args)
{
type = t;
name = n;
commandShort = QString::fromAscii(cs).toUtf8();
commandLong = QString::fromAscii(cl).toUtf8();
description = ki18n(desc);
this->hasFreeArgs = hasFreeArgs;
this->freeArgs = args;
}
void AkabeiOperation::addOption(AkabeiOption& opt)
{
options.insert(opt.name, opt);
}
bool AkabeiOperation::isOptionSupported(APM::OptionName name)
{
return options.contains(name);
}
/*
* Actual parsing
*/
void CmdLine::parse(int argc, char** argv)
{
KAboutData aboutData("akabei", 0, ki18n("Akabei"),
QByteArray("0.0.1"),
ki18n("Chakra's CLI package manager"),
KAboutData::License_GPL,
ki18n("(C) 2011 Lukas Appelhans"),
ki18n("<a href=\"mailto:boom1992@chakra-project.org\">boom1992@chakra-project.org</a>"));
aboutData.addAuthor(ki18n("Lukas Appelhans"), ki18n("Maintainer"), "boom1992@chakra-project.org");
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineOptions koptions;
/*
* Apparently description is mandatory, otherwise isSet doesn't find the option later
* Adds all the types
*/
koptions.add("D", ki18n("Database"));
koptions.add("S", ki18n("Install"));
koptions.add("U", ki18n("Upgrade"));
koptions.add("R", ki18n("Remove"));
koptions.add("Q", ki18n("Query"));
/*
* Adds all the operations
*/
foreach (AkabeiOperation op, acceptedOperations.values()) {
if (!op.commandLong.isEmpty()) {
if (!op.commandShort.isEmpty()) {
koptions.add(op.commandShort);
}
koptions.add(op.commandLong, op.description);
}
else {
koptions.add(op.commandShort, op.description);
}
}
/*
* Adds all the option with <argument> if they require one
* TODO: make <argument> more explicative of its nature (package, group, filename, ...)
*/
foreach (AkabeiOption opt, acceptedOptions) {
QByteArray newcomlong = opt.commandLong;
if (opt.hasArg) {
newcomlong += " <argument>";
}
if (!opt.commandShort.isEmpty()) {
koptions.add(opt.commandShort);
}
koptions.add(newcomlong, opt.description);
}
/*
* Free arguments at the end
*/
koptions.add("+[arg1]", ki18n("An optional argument 'arg1'"));
/*
* Parsing!
*/
KCmdLineArgs::addCmdLineOptions(koptions);
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
APM::OperationType type = APM::NoType;
m_operation.name = APM::None;
QList<QByteArray> checkops, checkopts;
/*
* These are considered separately and when found, they surpass any other operation that may be present.
*/
if (args->isSet("h")) {
m_operation = acceptedOperations.value("h");
} else if (args->isSet("v")) {
m_operation = acceptedOperations.value("v");
}
else {
for (QHash<QByteArray, APM::OperationType>::iterator it = typechars.begin(); it != typechars.end(); it++) {
if (args->isSet(it.key())) {
if (type != APM::NoType) {
throw CmdLineException("Multiple operations present.");
}
type = it.value();
/*
* Take in mind that more operations and more options may share the same command
* so we have to consider all the possibilities for whatever we find on the command line
*/
foreach (QByteArray command, acceptedOperations.uniqueKeys()) {
if (command.isEmpty()) {
continue;
}
/*
* Looks up all the operations with that command in search of one with the right type.
* If found, set it as operation.
*/
if (args->isSet(command)) {
bool found = false;
foreach (AkabeiOperation op, acceptedOperations.values(command)) {
if (op.type == type) {
found = true;
m_operation.set(op);
/* Save it so it isn't searched again as an option */
checkops.append(command);
}
}
/*
* If not found, that command can represent an option!
* So save it for later inspection
*/
if (!found) {
checkopts.append(command);
}
}
}
}
}
}
if (m_operation.name == APM::None) {
throw CmdLineException("No operation specified.");
}
foreach (AkabeiOption opt, acceptedOptions) {
QByteArray command = (opt.commandShort.isEmpty()) ? opt.commandLong : opt.commandShort;
/*
* If checkops contains the command, we already decided it's an operation, so go on
*/
if (!checkops.contains(command) && args->isSet(command)) {
/*
* if it was one of the commands we were unsure about, now we're sure
* (if command is not present, nothing is done anyway)
*/
checkopts.removeOne(command);
if (!m_operation.isOptionSupported(opt.name)) {
//throw CmdLineException("Invalid option for this operation.");
}
/*
* Gets arguments associated with the option
*/
QStringList optargs = args->getOptionList(command);
/*
* Remember, if it's not an option args it can be an argument to the operation
* so we're not really sure an error has been made, unless the operation doesn't admit any argument
*/
if (!optargs.isEmpty() && !opt.hasArg && !m_operation.hasFreeArgs) {
throw CmdLineException("This option must not have an argument.");
}
/*
* In this case, we're sure :)
*/
if (optargs.isEmpty() && opt.hasArg) {
throw CmdLineException("Missing argument for this option.");
}
opt.args = optargs;
m_options.insert(opt.name, opt);
}
}
/*
* If that strange command wasn't an option, then it was something wrong
*/
if (!checkopts.isEmpty()) {
throw CmdLineException("Out of context operation.");
}
for (int i = 0; i < args->count(); i++) {
m_freeArgs << args->arg(i);
}
if (!m_freeArgs.isEmpty() && !m_operation.hasFreeArgs) {
throw CmdLineException("Unexpected free arguments.");
}
if (m_freeArgs.isEmpty() && m_operation.hasFreeArgs) {
throw CmdLineException("Free arguments required but not present.");
}
args->clear(); /* frees up memory */
parsed = true;
}
APM::OperationType CmdLine::type()
{
if (!parsed) {
throw CmdLineException("Command line not parsed.");
}
qDebug() << m_operation.type;
return m_operation.type;
}
APM::OperationName CmdLine::operation()
{
if (!parsed) {
throw CmdLineException("Command line not parsed.");
}
return m_operation.name;
}
QStringList CmdLine::freeArgs()
{
if (!parsed) {
throw CmdLineException("Command line not parsed.");
}
return m_freeArgs;
}
QHash< APM::OptionName, AkabeiOption > CmdLine::options()
{
if (!parsed) {
throw CmdLineException("Command line not parsed.");
}
return m_options;
}
/* This file is part of the Chakra project
Copyright (C) 2011 Lisa "shainer" Vitolo <shainer@chakra-project.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef _CMDLINE_H
#define _CMDLINE_H
#include <QString>
#include <QList>
#include <QHash>
#include <klocalizedstring.h>
#include <kcmdlineargs.h>
#include <exception>
namespace APM
{
enum OperationType {
NoType, DatabaseOperationType, QueryOperationType, RemoveOperationType, SyncOperationType, UpgradeOperationType
};
typedef enum OperationType OperationType;
enum OptionName {
QueryPackageFile, ShowLocal, ShowLess, InstallAsDeps, InstallAsExplicit,
SkipDependencyCheck, Force, DownloadOnly, OnlyNeeded<