diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3e6a3b..3fdca91 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,6 +74,9 @@ SET(REDMINE_API_SOURCES
include/Redmine/User.hpp
src/Redmine/User.cpp
+ include/Redmine/IssueStatus.hpp
+ src/Redmine/IssueStatus.cpp
+
include/Redmine/API.hpp
src/Redmine/API.cpp
)
@@ -116,6 +119,8 @@ add_executable(redmine-cli
src/Redmine-CLI/Command/Version.cpp
src/Redmine-CLI/Command/MyAccount.hpp
src/Redmine-CLI/Command/MyAccount.cpp
+ src/Redmine-CLI/Command/IssueStatus.hpp
+ src/Redmine-CLI/Command/IssueStatus.cpp
)
target_link_libraries(redmine-cli redmine-api-cpp-static loguru CLI11)
target_include_directories(redmine-cli
diff --git a/include/Redmine/API.hpp b/include/Redmine/API.hpp
index 97918a0..745067f 100644
--- a/include/Redmine/API.hpp
+++ b/include/Redmine/API.hpp
@@ -16,12 +16,14 @@
* along with this program. If not, see .
*/
+#include "Redmine/IssueStatus.hpp"
#include "nlohmann/json_fwd.hpp"
#include
#include
#include
#include
#include
+#include
/**
* @brief The main namespace of this library for Redmine related datatypes, classes, and functions
@@ -46,7 +48,9 @@ namespace Redmine
/// the token to authenticate against the server in redmine called API Key
std::string authToken_;
-
+ /// cache for all issue stati
+ std::vector issueStatusList_;
+
nlohmann::json get(const std::string &path) const;
void put(const std::string &path, const nlohmann::json &data) const;
@@ -99,6 +103,12 @@ namespace Redmine
*/
void setMyAccount(const Redmine::User &user) const;
+ /**
+ * @brief Return a list of all available issue stati
+ *
+ */
+ std::vector getIssueStatusList();
+
/*@}*/
};
diff --git a/include/Redmine/Issue.hpp b/include/Redmine/Issue.hpp
new file mode 100644
index 0000000..0692e67
--- /dev/null
+++ b/include/Redmine/Issue.hpp
@@ -0,0 +1,73 @@
+#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 .
+*/
+
+#include "nlohmann/json_fwd.hpp"
+#include
+#include
+#include
+#include
+
+/**
+ * @brief The main namespace of this library for Redmine related datatypes, classes, and functions
+ *
+ */
+namespace Redmine
+{
+
+ /**
+ * @brief This class represents a user within the redmine server.
+ *
+ */
+ class Issue : public Redmine::Object
+ {
+ private:
+ /// the data store for the issue
+ nlohmann::json data_;
+
+ /**
+ * @brief verify issue data
+ *
+ * @param data - the json object containing the issue data
+ */
+ void _verify(const nlohmann::json &data);
+
+ public:
+ explicit Issue(const nlohmann::json &issue);
+
+ /**
+ * @brief set the issue object from a json object
+ *
+ * @param data
+ */
+ void set(const nlohmann::json &data);
+
+ /**
+ * @brief return a json object from the issue object
+ *
+ * @return nlohmann::json
+ */
+ nlohmann::json get() const;
+
+
+ std::uint64_t getId() const;
+
+
+
+ }; // class Issue
+
+}; // namespace Redmine
\ No newline at end of file
diff --git a/include/Redmine/IssueStatus.hpp b/include/Redmine/IssueStatus.hpp
new file mode 100644
index 0000000..ed80a69
--- /dev/null
+++ b/include/Redmine/IssueStatus.hpp
@@ -0,0 +1,99 @@
+#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 .
+*/
+
+/**
+ * @brief The main namespace of this library for Redmine related datatypes, classes, and functions
+ *
+ */
+#include "Redmine/Object.hpp"
+#include "nlohmann/json_fwd.hpp"
+namespace Redmine
+{
+
+ /**
+ * @brief Represents an IssueStatus within Redmine
+ *
+ * This can not be an enumeration as statusses can be added or deleted by an administrator
+ *
+ * The Redmine Rest API does not allow to add ad status therefore, no method to change or set
+ * anything.
+ */
+ class IssueStatus : public Redmine::Object
+ {
+ private:
+
+ /// the json object to hold all data
+ nlohmann::json data_;
+
+ /// method to verify the json input
+ void _verify(const nlohmann::json &data);
+
+ public:
+ /**
+ * @brief Constructor for a Status using input from a json object
+ *
+ * @param status - the status representation as a json object
+ */
+ explicit IssueStatus(const nlohmann::json &status);
+
+ /**
+ * @brief set the status from an json object
+ *
+ * @param data - the json object providing the status information
+ */
+ void set(const nlohmann::json &data);
+
+ /**
+ * @brief returns the currently set data of the object as a json object
+ *
+ * @return nlohmann::json - the json object holding all object information
+ */
+ nlohmann::json get() const;
+
+ /**
+ * @brief return the name of the status
+ *
+ * @return std::string
+ */
+ std::string getName() const;
+
+ /**
+ * @brief return the id of the status
+ *
+ * @return std::uint64_t
+ */
+ std::uint64_t getId() const;
+
+ /**
+ * @brief does the status mean the issue is closed
+ *
+ * @return true - the issue is closed
+ * @return false - the issue is not closed
+ */
+ bool isClosed() const;
+
+ /**
+ * @brief return a string representation of the status
+ *
+ * @return std::string
+ */
+ std::string to_string() const;
+
+ }; // class Status
+
+}; // namespace Redmine
\ No newline at end of file
diff --git a/include/Redmine/Priority.hpp b/include/Redmine/Priority.hpp
new file mode 100644
index 0000000..e69de29
diff --git a/include/Redmine/Project.hpp b/include/Redmine/Project.hpp
new file mode 100644
index 0000000..0692e67
--- /dev/null
+++ b/include/Redmine/Project.hpp
@@ -0,0 +1,73 @@
+#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 .
+*/
+
+#include "nlohmann/json_fwd.hpp"
+#include
+#include
+#include
+#include
+
+/**
+ * @brief The main namespace of this library for Redmine related datatypes, classes, and functions
+ *
+ */
+namespace Redmine
+{
+
+ /**
+ * @brief This class represents a user within the redmine server.
+ *
+ */
+ class Issue : public Redmine::Object
+ {
+ private:
+ /// the data store for the issue
+ nlohmann::json data_;
+
+ /**
+ * @brief verify issue data
+ *
+ * @param data - the json object containing the issue data
+ */
+ void _verify(const nlohmann::json &data);
+
+ public:
+ explicit Issue(const nlohmann::json &issue);
+
+ /**
+ * @brief set the issue object from a json object
+ *
+ * @param data
+ */
+ void set(const nlohmann::json &data);
+
+ /**
+ * @brief return a json object from the issue object
+ *
+ * @return nlohmann::json
+ */
+ nlohmann::json get() const;
+
+
+ std::uint64_t getId() const;
+
+
+
+ }; // class Issue
+
+}; // namespace Redmine
\ No newline at end of file
diff --git a/include/Redmine/Tracker.hpp b/include/Redmine/Tracker.hpp
new file mode 100644
index 0000000..e69de29
diff --git a/include/Redmine/Version.hpp b/include/Redmine/Version.hpp
new file mode 100644
index 0000000..e69de29
diff --git a/src/Redmine-CLI/Command/IssueStatus.cpp b/src/Redmine-CLI/Command/IssueStatus.cpp
new file mode 100644
index 0000000..c0e9da8
--- /dev/null
+++ b/src/Redmine-CLI/Command/IssueStatus.cpp
@@ -0,0 +1,53 @@
+/*
+* 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 .
+*/
+
+#include "Redmine/IssueStatus.hpp"
+#include
+#include
+#include
+#include "Redmine/API.hpp"
+#include "Redmine/User.hpp"
+#include "nlohmann/json_fwd.hpp"
+#define LOGURU_WITH_STREAMS 1
+#include
+
+Command::IssueStatus::IssueStatus(RedmineCLI::Redmine *r)
+:
+redmine_(r)
+{
+
+
+ issueStatus_ = redmine_->getCLI().add_subcommand("issuestatus",
+ "Request the available issue status list from the server");
+ issueStatus_->callback([&](){get_();});
+
+}
+
+
+void Command::IssueStatus::get_() const
+{
+
+ Redmine::API client{redmine_->getUrl(), redmine_->getToken()};
+
+ std::vector list = client.getIssueStatusList();
+
+ for (auto it = list.begin(); it!= list.end(); ++it)
+ {
+ std::cout << it->to_string() << std::endl;
+ }
+
+}
diff --git a/src/Redmine-CLI/Command/IssueStatus.hpp b/src/Redmine-CLI/Command/IssueStatus.hpp
new file mode 100644
index 0000000..22b10ca
--- /dev/null
+++ b/src/Redmine-CLI/Command/IssueStatus.hpp
@@ -0,0 +1,75 @@
+#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 .
+*/
+#include
+#include
+#include
+#include
+#include
+#include
+#define LOGURU_WITH_STREAMS 1
+#include
+#include
+
+
+// forward declaration
+namespace RedmineCLI
+{
+ class Redmine;
+};
+
+namespace Command
+{
+
+ /**
+ * @brief class for processing the CLI11 parsed command lines
+ *
+ */
+ class IssueStatus
+ {
+
+ 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 outputMap{{"text", TEXT}, {"yaml", YAML}};
+
+ CLI::App* issueStatus_;
+
+ /// the actual implementation of the information get
+ void get_() const;
+
+ public:
+ /**
+ * @brief Construct a new CLIProcessor object
+ *
+ */
+ IssueStatus(RedmineCLI::Redmine *r);
+
+
+ }; // class IssueStatus
+
+}; // namespace Command
\ No newline at end of file
diff --git a/src/Redmine-CLI/Command/MyAccount.cpp b/src/Redmine-CLI/Command/MyAccount.cpp
index faae5b2..83fd9f6 100644
--- a/src/Redmine-CLI/Command/MyAccount.cpp
+++ b/src/Redmine-CLI/Command/MyAccount.cpp
@@ -50,7 +50,7 @@ output_(TEXT)
void Command::MyAccount::set_() const
{
- Redmine::API client{redmine_->getUrl(), redmine_->getToken()};
+ Redmine::API client{redmine_->getUrl(), redmine_->getToken()};
Redmine::User user = client.getMyAccount();
diff --git a/src/Redmine-CLI/Redmine.cpp b/src/Redmine-CLI/Redmine.cpp
index 233608e..6765bdf 100644
--- a/src/Redmine-CLI/Redmine.cpp
+++ b/src/Redmine-CLI/Redmine.cpp
@@ -15,9 +15,13 @@
* along with this program. If not, see .
*/
#include
+#include "Redmine-CLI/Command/IssueStatus.hpp"
#include "Redmine-CLI/Command/Version.hpp"
#include
#include
+#define LOGURU_WITH_STREAMS 1
+#include
+
RedmineCLI::Redmine::Redmine(CLI::App &cli)
:
@@ -32,7 +36,8 @@ version_(nullptr)
// add all commands here
- version_ = std::make_unique(this);
- myAccount_ = std::make_unique(this);
+ version_ = std::make_unique(this);
+ myAccount_ = std::make_unique(this);
+ issueStatus_ = std::make_unique(this);
}
\ No newline at end of file
diff --git a/src/Redmine-CLI/Redmine.hpp b/src/Redmine-CLI/Redmine.hpp
index cbabe49..f652083 100644
--- a/src/Redmine-CLI/Redmine.hpp
+++ b/src/Redmine-CLI/Redmine.hpp
@@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+#include "Redmine-CLI/Command/IssueStatus.hpp"
#include "Redmine-CLI/Command/MyAccount.hpp"
#include "Redmine-CLI/Command/Version.hpp"
#include
@@ -56,6 +57,9 @@ namespace RedmineCLI
/// pointer to the myAccount subcommand
std::unique_ptr myAccount_;
+ /// pointer to the issues subcommand
+ std::unique_ptr issueStatus_;
+
public:
/**
diff --git a/src/Redmine-CLI/main.cpp b/src/Redmine-CLI/main.cpp
index 89602d4..e10fc27 100644
--- a/src/Redmine-CLI/main.cpp
+++ b/src/Redmine-CLI/main.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
#define LOGURU_WITH_STREAMS 1
@@ -31,11 +32,16 @@
int main(int argc, char **argv)
{
- CLI::App app("A command line client for the redmine project management server");
- RedmineCLI::Redmine redmineCli{app};
+ try {
+ CLI::App app("A command line client for the redmine project management server");
+ RedmineCLI::Redmine redmineCli{app};
+ CLI11_PARSE(app, argc, argv);
+ } catch (const std::exception &e)
+ {
+ return EXIT_FAILURE;
+ }
- CLI11_PARSE(app, argc, argv);
}
\ No newline at end of file
diff --git a/src/Redmine/API.cpp b/src/Redmine/API.cpp
index 953e5ba..d6f1e0f 100644
--- a/src/Redmine/API.cpp
+++ b/src/Redmine/API.cpp
@@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+#include "Redmine/IssueStatus.hpp"
#include "nlohmann/json_fwd.hpp"
#include
#include
@@ -68,6 +69,12 @@ Redmine::API::API(const std::string &serverURL, const std::string &authToken)
auto res = client.Get(path + ".json" , headers);
+ if (res == nullptr)
+ {
+ DLOG_S(ERROR) << "failed to get data from API endpoint";
+ throw std::runtime_error("API request failed");
+ }
+
if (res->status == httplib::StatusCode::Unauthorized_401)
{
DLOG_S(ERROR) << "authentication with API server failed (401)";
@@ -137,6 +144,22 @@ void Redmine::API::setMyAccount(const Redmine::User &user) const
}
+std::vector Redmine::API::getIssueStatusList()
+{
+ nlohmann::json statusList = get("/issue_statuses");
+ issueStatusList_.clear();
+
+
+ for (auto it=statusList["issue_statuses"].begin(); it != statusList["issue_statuses"].end(); ++it)
+ {
+
+ Redmine::IssueStatus status{*it};
+
+ issueStatusList_.push_back(status);
+ }
+
+ return issueStatusList_;
+}
bool Redmine::API::ready() const
{
diff --git a/src/Redmine/IssueStatus.cpp b/src/Redmine/IssueStatus.cpp
new file mode 100644
index 0000000..4994b9c
--- /dev/null
+++ b/src/Redmine/IssueStatus.cpp
@@ -0,0 +1,65 @@
+/*
+* 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 .
+*/
+#include
+#include
+
+void Redmine::IssueStatus::_verify(const nlohmann::json &data)
+{
+ _baseVerify(data,"");
+
+}
+
+
+void Redmine::IssueStatus::set(const nlohmann::json &data)
+{
+ _verify(data);
+ data_=data;
+}
+
+Redmine::IssueStatus::IssueStatus(const nlohmann::json &status)
+{
+ set(status);
+}
+
+nlohmann::json Redmine::IssueStatus::get() const
+{
+ return data_;
+}
+
+std::string Redmine::IssueStatus::getName() const
+{
+ return data_["name"].get();
+}
+
+std::uint64_t Redmine::IssueStatus::getId() const
+{
+ return data_["id"].get();
+}
+
+bool Redmine::IssueStatus::isClosed() const
+{
+ return data_["is_closed"].get();
+}
+
+std::string Redmine::IssueStatus::to_string() const
+{
+ std::stringstream strStream;
+
+ strStream << getName() << "( ID=" << getId() << ", closesIssue=" << isClosed() << ")";
+
+ return strStream.str();
+}
\ No newline at end of file
diff --git a/src/Redmine/Object.cpp b/src/Redmine/Object.cpp
index 9a83659..958cbe5 100644
--- a/src/Redmine/Object.cpp
+++ b/src/Redmine/Object.cpp
@@ -26,19 +26,19 @@ void Redmine::Object::_baseVerify(const nlohmann::json &data, const std::string
throw std::invalid_argument("provided data is empty");
}
- if (!data.is_object())
+ if (!data.is_object() && !data.is_array())
{
- DLOG_S(ERROR) << "provided data is not a json object/hash";
- throw std::invalid_argument("provided data is not a json objects/hash");
+ DLOG_S(ERROR) << "provided data is not a json object/hash or array";
+ throw std::invalid_argument("provided data is not a json objects/hash or array");
}
- if (!data.contains(objectName))
+ if ( !objectName.empty() && !data.contains(objectName))
{
DLOG_S(ERROR) << "provided data does not contain object information (" << objectName << ")";
throw std::invalid_argument("provided data does not contain object information (" + objectName + ")");
}
- if (data[objectName].empty())
+ if (!objectName.empty() && data[objectName].empty())
{
DLOG_S(ERROR) << "provided object information is empty";
throw std::invalid_argument("provided object information is empty");
diff --git a/src/config.hpp b/src/config.hpp
new file mode 100644
index 0000000..3e4403e
--- /dev/null
+++ b/src/config.hpp
@@ -0,0 +1,28 @@
+#ifndef __LIBCMS_CONFIG_HPP__
+#define __LIBCMS_CONFIG_HPP__
+/*
+* 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 .
+*/
+
+
+#define PROJECT_NAME remine-api-cpp
+
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 0
+#define VERSION_PATCH 1
+#define PROJECT_VERSION "0.0.1"
+
+#endif