ADD: sources for the redmine cli

This commit is contained in:
Dominik Meyer 2024-02-18 13:54:21 +01:00
parent 224e361420
commit 02d3d282a3
Signed by: byterazor
GPG Key ID: EABDA0FD5981BC97
7 changed files with 568 additions and 0 deletions

View File

@ -0,0 +1,178 @@
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Redmine-CLI/Command/MyAccount.hpp>
#include <Redmine-CLI/Redmine.hpp>
#include "Redmine/API.hpp"
#include "Redmine/User.hpp"
#include "nlohmann/json_fwd.hpp"
Command::MyAccount::MyAccount(RedmineCLI::Redmine *r)
:
redmine_(r),
output_(TEXT)
{
CLI::App* myAccount = redmine_->getCLI().add_subcommand("myaccount",
"Api Calls on the account of the token owner");
myAccountGet = myAccount->add_subcommand("get", "Get the current information of the token owner");
myAccountGet->needs(redmine_->getTokenOption())->needs(redmine_->getUrlOption());
myAccountGet->callback([&](){get_();});
myAccountGet->add_option("-f,--fields", fields_, "The fields of the user object to print. Supported: firstname, lastname, login, id, mail");
myAccountGet->add_option("-o,--output", output_, "The Output Format to use. Supported: TEXT, YAML")->transform(CLI::CheckedTransformer(outputMap, CLI::ignore_case));
myAccountSet = myAccount->add_subcommand("set", "Set the current information of the token owner");
myAccountSet->needs(redmine_->getTokenOption())->needs(redmine_->getUrlOption());
myAccountSet->add_option("-f,--firstname", firstname_, "the new firstname");
myAccountSet->add_option("-l,--lastname", lastname_, "the new lastname");
myAccountSet->add_option("-a,--login", login_, "the new login");
myAccountSet->add_option("-m,--mail", mail_, "the new email address");
myAccountSet->callback([&](){set_();});
}
void Command::MyAccount::set_() const
{
Redmine::API client{redmine_->getUrl(), redmine_->getToken()};
Redmine::User user = client.getMyAccount();
if (! firstname_.empty())
{
user.setFirstName(firstname_);
}
if (! lastname_.empty())
{
user.setLastName(lastname_);
}
if (! login_.empty())
{
user.setLogin(login_);
}
if (! id_.empty())
{
user.setId(id_);
}
if (! mail_.empty())
{
user.setMail(mail_);
}
client.setMyAccount(user);
}
void Command::MyAccount::get_() const
{
Redmine::API client{redmine_->getUrl(), redmine_->getToken()};
Redmine::User user = client.getMyAccount();
bool hasFirstname = std::find(fields_.begin(), fields_.end(),"firstname")
!= fields_.end() || fields_.empty();
bool hasLastname = std::find(fields_.begin(), fields_.end(),"lastname")
!= fields_.end() || fields_.empty();
bool hasLogin = std::find(fields_.begin(), fields_.end(),"login")
!= fields_.end() || fields_.empty();
bool hasId = std::find(fields_.begin(), fields_.end(),"id")
!= fields_.end() || fields_.empty();
bool hasMail = std::find(fields_.begin(), fields_.end(),"mail")
!= fields_.end() || fields_.empty();
nlohmann::json data;
if (hasFirstname)
{
if (output_ == TEXT)
{
std::cout << "Firstname : " << user.getFirstName() << std::endl;
}
else if (output_ == YAML)
{
data["firstname"]=user.getFirstName();
}
}
if (hasLastname)
{
if (output_ == TEXT)
{
std::cout << "Lastname : " << user.getLastName() << std::endl;
}
else if (output_ == YAML)
{
data["lastname"]=user.getLastName();
}
}
if (hasLogin)
{
if (output_ == TEXT)
{
std::cout << "Login : " << user.getLogin() << std::endl;
}
else if (output_ == YAML)
{
data["login"]=user.getLogin();
}
}
if (hasId)
{
if (output_ == TEXT)
{
std::cout << "Id : " << user.getId() << std::endl;
}
else if (output_ == YAML)
{
data["id"]=user.getId();
}
}
if (hasMail)
{
if (output_ == TEXT)
{
std::cout << "Email : " << user.getEmail() << std::endl;
}
else if (output_ == YAML)
{
data["mail"]=user.getEmail();
}
}
if (output_ == YAML)
{
std::cout << data.dump(1);
}
}

View File

@ -0,0 +1,105 @@
#pragma once
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <CLI/App.hpp>
#include <Redmine/API.hpp>
#include <atomic>
#include <cstdint>
#include <memory>
#include <string>
#define LOGURU_WITH_STREAMS 1
#include <loguru.hpp>
#include <CLI/CLI.hpp>
// forward declaration
namespace RedmineCLI
{
class Redmine;
};
namespace Command
{
/**
* @brief class for processing the CLI11 parsed command lines
*
*/
class MyAccount
{
private:
/// the main redmine cli application context
RedmineCLI::Redmine *redmine_;
/// enum for identifying supported output types
enum outputType : std::uint16_t
{
/// output is just text
TEXT,
/// output is yaml
YAML
};
std::map<std::string, outputType> outputMap{{"text", TEXT}, {"yaml", YAML}};
/// pointer to the get subcommand
CLI::App* myAccountGet;
/// pointer to the set subcommand
CLI::App* myAccountSet;
/// vector to hold requested attribute fields
std::vector<std::string> fields_;
/// requested output type
outputType output_;
/// the actual implementation of the information get
void get_() const;
/// the actual implementation of the information set
void set_() const;
/// parameter for setting the firstname
std::string firstname_;
/// parameter for setting the lastname
std::string lastname_;
/// parameter for setting the login
std::string login_;
/// parameter for setting the id
std::string id_;
/// parameter for setting the email
std::string mail_;
public:
/**
* @brief Construct a new CLIProcessor object
*
*/
MyAccount(RedmineCLI::Redmine *r);
}; // class MyAccount
}; // namespace Command

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Redmine-CLI/Command/Version.hpp>
#include <Redmine-CLI/Redmine.hpp>
#include "Redmine/User.hpp"
#include "config.hpp"
#include <iostream>
Command::Version::Version(RedmineCLI::Redmine *r)
:
redmine_(r),
version_(nullptr)
{
version_ = redmine_->getCLI().add_subcommand("version", "Print current program version");
version_->callback( [&](){
std::cout << "redmine-api-client Version " << PROJECT_VERSION << std::endl;
});
}

View File

@ -0,0 +1,62 @@
#pragma once
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <CLI/App.hpp>
#include <Redmine/API.hpp>
#include <memory>
#include <string>
#define LOGURU_WITH_STREAMS 1
#include <loguru.hpp>
#include <CLI/CLI.hpp>
// forward declaration
namespace RedmineCLI
{
class Redmine;
};
namespace Command
{
/**
* @brief Command for printing the version of the redmine-cli
*
*/
class Version
{
private:
/// the main redmine cli application context
RedmineCLI::Redmine *redmine_;
/// pointer to the version subcommand
CLI::App* version_;
public:
/**
* @brief Construct a new CLIProcessor object
*
* @param redmineURL - the url to the redmine instance
* @param apiToken - the token to authenticate api requests
*/
Version(RedmineCLI::Redmine *r);
}; // class Version
}; // namespace Command

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Redmine-CLI/Command/MyAccount.hpp>
#include "Redmine-CLI/Command/Version.hpp"
#include <Redmine-CLI/Redmine.hpp>
#include <memory>
RedmineCLI::Redmine::Redmine(CLI::App &cli)
:
cli_(cli),
version_(nullptr)
{
CLIredmineApiToken_ = cli_.add_option("-t,--token",redmineApiToken_,
"The API token for accessing redmine")->envname("REDMINE_API_TOKEN");
CLIredmineUrl_ = cli_.add_option("-u,--url",redmineUrl_,"The URL to the redmine server (e.g. https://redmine.org)")->envname("REDMINE_URL");
// add all commands here
version_ = std::make_unique<Command::Version>(this);
myAccount_ = std::make_unique<Command::MyAccount>(this);
}

108
src/Redmine-CLI/Redmine.hpp Normal file
View File

@ -0,0 +1,108 @@
#pragma once
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Redmine-CLI/Command/MyAccount.hpp"
#include "Redmine-CLI/Command/Version.hpp"
#include <CLI/App.hpp>
#include <CLI/Option.hpp>
#include <memory>
namespace RedmineCLI
{
/**
* @brief Main class for the CLI appication
*
* This class holds the main CLI::APP context and
* initializes commands for the application.
*
*/
class Redmine
{
private:
/// Main CLI11 application context
CLI::App &cli_;
/// CLI option for getting the redmine api token
CLI::Option *CLIredmineApiToken_;
/// CLI option for getting the redmine url
CLI::Option *CLIredmineUrl_;
/// the redmine api token itself
std::string redmineApiToken_;
/// the redmine url itself
std::string redmineUrl_;
/// pointer to the version subcommand
std::unique_ptr<Command::Version> version_;
/// pointer to the myAccount subcommand
std::unique_ptr<Command::MyAccount> myAccount_;
public:
/**
* @brief Main constructor for just creating an object and providing the main CLI::App Context
*
* @param cli - the CLI::App context
*/
explicit Redmine(CLI::App &cli);
/**
* @brief return the CLI::App context as a reference
*
* @return CLI::App&
*/
CLI::App & getCLI() const {return cli_;}
/**
* @brief Return a pointer to the CLI::Option for the redmine app token
*
* This is helpful as you can make it needed in a subcommand of the application.
*
* @return CLI::Option*
*/
CLI::Option* getTokenOption() { return CLIredmineApiToken_;}
/**
* @brief Return a pointer to the CLI::Option for the redmine url
*
* This is helpful as you can make it needed in a subcommand of the application.
*
* @return CLI::Option*
*/
CLI::Option* getUrlOption() { return CLIredmineUrl_;}
/**
* @brief return the parsed app token
*
* @return std::string
*/
std::string getToken() {return redmineApiToken_;}
/**
* @brief return the parsed redmine url
*
* @return std::string
*/
std::string getUrl() {return redmineUrl_;}
}; // class Redmine
}; // namespace RedmineCLI

41
src/Redmine-CLI/main.cpp Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Dominik Meyer
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Redmine-CLI/Redmine.hpp"
#include "config.hpp"
#include "config.hpp.in"
#include <CLI/App.hpp>
#include <CLI/Option.hpp>
#include <Redmine/API.hpp>
#include <Redmine/Exception/Api.hpp>
#include <string>
#include <vector>
#define LOGURU_WITH_STREAMS 1
#include <loguru.hpp>
#include <CLI/CLI.hpp>
int main(int argc, char **argv)
{
CLI::App app("A command line client for the redmine project management server");
RedmineCLI::Redmine redmineCli{app};
CLI11_PARSE(app, argc, argv);
}