Ajoute le namespace oki

This commit is contained in:
Colin FRIZOT
2022-10-10 11:06:29 +02:00
parent 73dbf64e7f
commit b9bfcc18bd
14 changed files with 176 additions and 145 deletions

View File

@@ -3,33 +3,36 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
void invalidUsage(std::ostream &os) { namespace oki{
void invalidUsage(std::ostream &os) {
std::cerr << "Invalid usage. Hint: "; std::cerr << "Invalid usage. Hint: ";
}
void help(std::ostream &os) {
os << "help: Show this help\n";
os << "list: List available packages\n";
os << "install: Install a new package\n";
}
CliAction parseArguments(int argc, char *argv[]) {
if (argc < 2) {
std::cerr << "See " << argv[0] << " help for all available actions.\n";
exit(0);
} }
if (strcmp("help", argv[1]) == 0) {
help(std::cout); void help(std::ostream &os) {
} else if (strcmp("list", argv[1]) == 0) { os << "help: Show this help\n";
return ListAction{}; os << "list: List available packages\n";
} else if (strcmp("install", argv[1]) == 0) { os << "install: Install a new package\n";
if (argc < 3) { }
invalidUsage(std::cerr);
std::cerr << "Add a package name after install.\n"; CliAction parseArguments(int argc, char *argv[]) {
if (argc < 2) {
std::cerr << "See " << argv[0] << " help for all available actions.\n";
exit(0);
}
if (strcmp("help", argv[1]) == 0) {
help(std::cout);
} else if (strcmp("list", argv[1]) == 0) {
return ListAction{};
} else if (strcmp("install", argv[1]) == 0) {
if (argc < 3) {
invalidUsage(std::cerr);
std::cerr << "Add a package name after install.\n";
exit(1);
}
return InstallAction{argv[2]};
} else {
exit(1); exit(1);
} }
return InstallAction{argv[2]};
} else {
exit(1);
} }
} }

View File

@@ -3,12 +3,16 @@
#include <string_view> #include <string_view>
#include <variant> #include <variant>
struct ListAction { namespace oki{
}; struct ListAction {
struct InstallAction { };
std::string_view packageName; struct InstallAction {
explicit InstallAction(const char *packageName) : packageName{packageName} {} std::string_view packageName;
}; explicit InstallAction(const char *packageName) : packageName{packageName} {}
using CliAction = std::variant<ListAction, InstallAction>; };
using CliAction = std::variant<ListAction, InstallAction>;
CliAction parseArguments(int argc, char *argv[]);
}
CliAction parseArguments(int argc, char *argv[]);

View File

@@ -4,11 +4,13 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
fs::path getDefaultLocalRepository() { namespace oki{
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html fs::path getDefaultLocalRepository() {
const char *xdgData = std::getenv("XDG_DATA_HOME"); // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
if (xdgData == nullptr) { const char *xdgData = std::getenv("XDG_DATA_HOME");
return std::getenv("HOME") / fs::path{".local/share/oki"}; if (xdgData == nullptr) {
return std::getenv("HOME") / fs::path{".local/share/oki"};
}
return xdgData / fs::path{"oki"};
} }
return xdgData / fs::path{"oki"};
} }

View File

@@ -2,4 +2,6 @@
#include <filesystem> #include <filesystem>
std::filesystem::path getDefaultLocalRepository(); namespace oki{
std::filesystem::path getDefaultLocalRepository();
}

View File

@@ -2,36 +2,38 @@
#include <curl/curl.h> #include <curl/curl.h>
static std::size_t writeCallback(char *in, std::size_t size, std::size_t nmemb, std::string *out) { namespace oki{
std::size_t totalSize = size * nmemb; static std::size_t writeCallback(char *in, std::size_t size, std::size_t nmemb, std::string *out) {
if (totalSize) { std::size_t totalSize = size * nmemb;
out->append(in, totalSize); if (totalSize) {
return totalSize; out->append(in, totalSize);
return totalSize;
}
return 0;
} }
return 0;
}
HttpRequest::HttpRequest(std::string_view url) : curl{curl_easy_init()}, url{url} { HttpRequest::HttpRequest(std::string_view url) : curl{curl_easy_init()}, url{url} {
curl_easy_setopt(curl, CURLOPT_URL, this->url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, this->url.c_str());
}
std::string HttpRequest::get() {
std::string buffer;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
throw RequestException{static_cast<int>(res)};
} }
return buffer;
}
HttpRequest::~HttpRequest() { std::string HttpRequest::get() {
curl_easy_cleanup(curl); std::string buffer;
} curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
throw RequestException{static_cast<int>(res)};
}
return buffer;
}
RequestException::RequestException(int code) : code{code} {} HttpRequest::~HttpRequest() {
curl_easy_cleanup(curl);
}
const char *RequestException::what() const noexcept { RequestException::RequestException(int code) : code{code} {}
return curl_easy_strerror(static_cast<CURLcode>(code));
} const char *RequestException::what() const noexcept {
return curl_easy_strerror(static_cast<CURLcode>(code));
}
}

View File

@@ -2,20 +2,22 @@
#include <string> #include <string>
class HttpRequest { namespace oki{
private: class HttpRequest {
void *curl; private:
std::string url; void *curl;
public: std::string url;
explicit HttpRequest(std::string_view url); public:
std::string get(); explicit HttpRequest(std::string_view url);
~HttpRequest(); std::string get();
}; ~HttpRequest();
};
class RequestException : public std::exception { class RequestException : public std::exception {
private: private:
int code; int code;
public: public:
explicit RequestException(int code); explicit RequestException(int code);
const char *what() const noexcept override; const char *what() const noexcept override;
}; };
}

View File

@@ -4,6 +4,8 @@
#include "cli/options.h" #include "cli/options.h"
#include "repository/RemoteRepository.h" #include "repository/RemoteRepository.h"
using namespace oki;
std::size_t writeCallback(char *in, size_t size, size_t nmemb, std::string *out){ std::size_t writeCallback(char *in, size_t size, size_t nmemb, std::string *out){
std::size_t total_size = size * nmemb; std::size_t total_size = size * nmemb;
if (total_size){ if (total_size){

View File

@@ -1,11 +1,13 @@
#include "Package.h" #include "Package.h"
Package::Package(std::string_view shortName, std::string_view longName) : shortName{shortName}, longName{longName} {} namespace oki{
Package::Package(std::string_view shortName, std::string_view longName) : shortName{shortName}, longName{longName} {}
const std::string& Package::getShortName() const { const std::string& Package::getShortName() const {
return shortName; return shortName;
} }
const std::string& Package::getLongName() const { const std::string& Package::getLongName() const {
return longName; return longName;
} }
}

View File

@@ -2,12 +2,14 @@
#include <string> #include <string>
class Package { namespace oki{
private: class Package {
std::string shortName; private:
std::string longName; std::string shortName;
public: std::string longName;
Package(std::string_view shortName, std::string_view longName); public:
const std::string& getShortName() const; Package(std::string_view shortName, std::string_view longName);
const std::string& getLongName() const; const std::string& getShortName() const;
}; const std::string& getLongName() const;
};
}

View File

@@ -4,20 +4,22 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
LocalRepository::LocalRepository(fs::path root) : root{std::move(root)} {} namespace oki{
LocalRepository::LocalRepository(fs::path root) : root{std::move(root)} {}
void LocalRepository::createIfNotExists() { void LocalRepository::createIfNotExists() {
fs::create_directories(root); fs::create_directories(root);
}
std::vector<Package> LocalRepository::listPackages() {
std::vector<Package> packages;
for (const auto& file : fs::directory_iterator(root)) {
packages.emplace_back(file.path().filename().string(), "");
} }
return packages;
}
void LocalRepository::download(std::string_view packageName, const fs::path& destination) { std::vector<Package> LocalRepository::listPackages() {
std::cerr << "TODO : downloading " << packageName << "\n"; std::vector<Package> packages;
} for (const auto& file : fs::directory_iterator(root)) {
packages.emplace_back(file.path().filename().string(), "");
}
return packages;
}
void LocalRepository::download(std::string_view packageName, const fs::path& destination) {
std::cerr << "TODO : downloading " << packageName << "\n";
}
}

View File

@@ -2,12 +2,14 @@
#include "Repository.h" #include "Repository.h"
class LocalRepository : public Repository { namespace oki{
private: class LocalRepository : public Repository {
std::filesystem::path root; private:
public: std::filesystem::path root;
explicit LocalRepository(std::filesystem::path root); public:
void createIfNotExists(); explicit LocalRepository(std::filesystem::path root);
std::vector<Package> listPackages() override; void createIfNotExists();
void download(std::string_view packageName, const std::filesystem::path& destination) override; std::vector<Package> listPackages() override;
}; void download(std::string_view packageName, const std::filesystem::path& destination) override;
};
}

View File

@@ -5,18 +5,20 @@
using json = nlohmann::json; using json = nlohmann::json;
RemoteRepository::RemoteRepository(std::string_view apiUrl) : apiUrl{apiUrl} {} namespace oki{
RemoteRepository::RemoteRepository(std::string_view apiUrl) : apiUrl{apiUrl} {}
std::vector<Package> RemoteRepository::listPackages() { std::vector<Package> RemoteRepository::listPackages() {
HttpRequest request{apiUrl + "?api=list"}; HttpRequest request{apiUrl + "?api=list"};
json data = json::parse(request.get()); json data = json::parse(request.get());
std::vector<Package> packages; std::vector<Package> packages;
for (const auto &item : data) { for (const auto &item : data) {
packages.emplace_back(item.at("short_name").get<std::string>(), item.at("long_name").get<std::string>()); packages.emplace_back(item.at("short_name").get<std::string>(), item.at("long_name").get<std::string>());
}
return packages;
} }
return packages;
}
void RemoteRepository::download(std::string_view packageName, const std::filesystem::path &destination) { void RemoteRepository::download(std::string_view packageName, const std::filesystem::path &destination) {
}
} }

View File

@@ -2,11 +2,13 @@
#include "Repository.h" #include "Repository.h"
class RemoteRepository : public Repository { namespace oki{
private: class RemoteRepository : public Repository {
std::string apiUrl; private:
public: std::string apiUrl;
explicit RemoteRepository(std::string_view apiUrl); public:
std::vector<Package> listPackages() override; explicit RemoteRepository(std::string_view apiUrl);
void download(std::string_view packageName, const std::filesystem::path& destination) override; std::vector<Package> listPackages() override;
}; void download(std::string_view packageName, const std::filesystem::path& destination) override;
};
}

View File

@@ -6,9 +6,11 @@
#include "../package/Package.h" #include "../package/Package.h"
class Repository { namespace oki{
public: class Repository {
virtual std::vector<Package> listPackages() = 0; public:
virtual void download(std::string_view packageName, const std::filesystem::path& destination) = 0; virtual std::vector<Package> listPackages() = 0;
virtual ~Repository() = default; virtual void download(std::string_view packageName, const std::filesystem::path& destination) = 0;
}; virtual ~Repository() = default;
};
}