#include "utility/commandline/CommandLineParser.h" #include #include #include #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(), "Open Sourcetrail with this project (.srctrlprj)") ; m_options.add(options); m_positional.add("project-file", 1); addCommand(std::make_unique(this)); addCommand(std::make_unique(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) { m_commands.push_back(std::move(command)); } void CommandLineParser::preparse(int argc, char** argv) { // put argv into a string vector std::vector args; for(int i = 1; i < argc; i++) { args.push_back(std::string(argv[i])); } preparse(args); } void CommandLineParser::preparse(std::vector& 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()); 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::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