Files
Sourcetrail/src/lib/utility/commandline/CommandLineParser.cpp
T

268 lines
5.4 KiB
C++

#include "utility/commandline/CommandLineParser.h"
#include <iostream>
#include <fstream>
#include <utility>
#include "boost/program_options.hpp"
#include "utility/commandline/CommandlineHelper.h"
#include "utility/commandline/commands/CommandlineCommandConfig.h"
#include "utility/commandline/commands/CommandlineCommandIndex.h"
#include "utility/ConfigManager.h"
#include "utility/text/TextAccess.h"
#include "utility/utilityString.h"
#include "License.h"
#include "PublicKey.h"
namespace po = boost::program_options;
namespace commandline
{
CommandLineParser::CommandLineParser(const std::string& version)
: m_version(version)
{
setup();
}
void CommandLineParser::setup()
{
po::options_description options("Sourcetrail Options");
options.add_options()
("help,h", "Print this help message")
("version,v", "Version of Sourcetrail")
("project-file", po::value<std::string>(), "Open Sourcetrail with this project (.srctrlprj)")
;
m_options.add(options);
m_positional.add("project-file", 1);
addCommand(std::make_unique<commandline::CommandConfig>(this));
addCommand(std::make_unique<commandline::CommandIndex>(this));
for ( auto& command : m_commands)
{
command->setup();
}
}
void CommandLineParser::setProjectFile(const FilePath &filepath)
{
m_projectFile = filepath;
processProjectfile();
}
void CommandLineParser::addCommand(std::unique_ptr<Command> command)
{
m_commands.push_back(std::move(command));
}
void CommandLineParser::preparse(int argc, char** argv)
{
// put argv into a string vector
std::vector<std::string> args;
for(int i = 1; i < argc; i++)
{
args.push_back(std::string(argv[i]));
}
preparse(args);
}
void CommandLineParser::preparse(std::vector<std::string>& args)
{
if (args.size() < 1)
{
return;
}
m_args = std::move(args);
try
{
// parsing for all commands
for ( auto& command : m_commands)
{
if ( m_args[0] == command->name())
{
m_withoutGUI = true;
return;
}
}
po::variables_map vm;
po::positional_options_description positional;
positional.add("project-file",1);
po::store(po::command_line_parser(m_args).options(m_options).positional(positional).allow_unregistered().run(), vm);
po::notify(vm);
if (vm.count("version"))
{
std::cout << "Sourcetrail Version " << m_version << std::endl;
m_quit = true;
return;
}
if (vm.count("help"))
{
printHelp();
m_quit = true;
}
if (vm.count("project-file"))
{
m_projectFile = FilePath(vm["project-file"].as<std::string>());
processProjectfile();
}
}
catch(boost::program_options::error& e)
{
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << m_options << std::endl;
}
}
void CommandLineParser::parse()
{
if (m_args.size() < 1)
{
return;
}
try
{
// parsing for all commands
for ( auto& command : m_commands)
{
if ( m_args[0] == command->name())
{
m_args.erase(m_args.begin());
ReturnStatus status = command->parse(m_args);
if (status == ReturnStatus::CMD_QUIT
|| status == ReturnStatus::CMD_FAILURE)
{
m_quit = true;
}
}
}
}
catch(boost::program_options::error& e)
{
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << m_options << std::endl;
}
}
License* CommandLineParser::getLicensePtr()
{
return &m_license;
}
void CommandLineParser::printHelp() const
{
std::cout << "Usage:\n Sourcetrail [command] [option...] [positional arguments]\n\n";
// Commands
std::cout << "Commands:\n";
for (auto& Command : m_commands)
{
std::cout << " " << Command->name() << "\n";
}
std::cout << "\n * Each command has its own --help\n";
std::cout << m_options << std::endl;
if (m_positional.max_total_count() > 0)
{
std::cout << "Positional Arguments: ";
for (unsigned int i = 0; i < m_positional.max_total_count(); i++)
{
std::cout << "\n " << i+1 << ": " << m_positional.name_for_position(i);
}
std::cout << std::endl;
}
}
bool CommandLineParser::hasError()
{
return !m_errorString.empty();
}
std::string CommandLineParser::getError()
{
return m_errorString;
}
CommandLineParser::~CommandLineParser()
{
}
bool CommandLineParser::runWithoutGUI()
{
return m_withoutGUI;
}
bool CommandLineParser::exitApplication()
{
return m_quit;
}
bool CommandLineParser::startedWithLicense()
{
if (m_license.getUser().empty())
{
return false;
}
return m_license.isValid();
}
void CommandLineParser::processProjectfile()
{
m_projectFile = m_projectFile.absolute();
const std::string errorstring =
"Provided Projectfile is not valid:\n* Provided Projectfile('" + m_projectFile.fileName() + "') ";
if (!m_projectFile.exists())
{
m_errorString = errorstring + " does not exist";
m_projectFile = FilePath();
return;
}
if (m_projectFile.extension() != ".srctrlprj" && m_projectFile.extension() != ".coatiproject")
{
m_errorString = errorstring + " has a wrong file ending";
m_projectFile = FilePath();
return;
}
std::shared_ptr<ConfigManager> configManager = ConfigManager::createEmpty();
if (!configManager->load(TextAccess::createFromFile(m_projectFile)))
{
m_errorString = errorstring + " could not be loaded (invalid)";
m_projectFile = FilePath();
return;
}
}
License CommandLineParser::getLicense()
{
return m_license;
}
void CommandLineParser::force()
{
m_force = true;
}
const FilePath& CommandLineParser::getProjectFilePath() const
{
return m_projectFile;
}
bool CommandLineParser::getFullProjectRefresh() const
{
return m_force;
}
} // namespace cmd