diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6b759..c2afcac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ along with Onur. If not, see . # CHANGELOG +## 0.3.0 + +- feat: edit/view configurations + ## 0.2.0 - feat: refactor, more tests and improve cli ui diff --git a/README.md b/README.md index 21e21db..0185f35 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Easily manage multiple FLOSS repositories. ```shell onur grab onur backup nuxt awesomewm gitignore +onur config c.misc cli11 https://github.com/cliutils/cli11 main onur --help ``` diff --git a/TODO.md b/TODO.md index b2cd28a..ba6cda5 100644 --- a/TODO.md +++ b/TODO.md @@ -17,12 +17,15 @@ along with Onur. If not, see . ### High -- verbose +- flag: --verbose - validation of repository links -- actions: --filter rust +- actions: --filter rust:misc - actions: --only rust,haskel,commonlisp - actions: --exclude rust,haskel,commonlisp +### Mid +- actions: onur config c.misc foo https://git@gmasd main + ### Low - config: move on these to a syntax check class diff --git a/meson.build b/meson.build index 5c8a876..8b18684 100644 --- a/meson.build +++ b/meson.build @@ -16,7 +16,7 @@ project( 'cpp', license: 'GNU GPL version 3', version: '0.2.0', - default_options: [ 'cpp_std=c++20', 'warning_level=3' ], + default_options: [ 'cpp_std=c++23', 'warning_level=3' ], meson_version: '>=1.4.0', ) diff --git a/src/database/parse.cpp b/src/database/parse.cpp index 450a80b..bb181e7 100644 --- a/src/database/parse.cpp +++ b/src/database/parse.cpp @@ -15,13 +15,16 @@ #include #include +#include #include +#include #include #include #include #include "../include/konfig.hpp" +#include "../include/misc.hpp" #include "../include/parse.hpp" #include "../include/project.hpp" @@ -52,29 +55,29 @@ auto Parse::single (path filepath) -> Konfig { Konfig result; - map > subtopiks; + map> _topics; auto configParsed = parse_file (contents_of (filepath)); - result.topic = { filepath.stem () }; + result.name = { filepath.stem () }; - for (auto &[subtopic, subtopics] : configParsed.items ()) + for (auto &[topic, topics] : configParsed.items ()) { list projects; - for (auto projekt : subtopics) + for (auto project : topics) { string branch{ "master" }; - if (!projekt["branch"].is_null ()) - branch = projekt["branch"]; + if (!project["branch"].is_null ()) + branch = project["branch"]; - auto pkt{ Project (projekt["name"], projekt["url"], branch) }; + auto pkt{ Project (project["name"], project["url"], branch) }; projects.push_back (pkt); } - subtopiks[subtopic] = { projects }; + _topics[topic] = { projects }; } - result.subtopics = { subtopiks }; + result.topics = { _topics }; return result; } @@ -90,3 +93,50 @@ Parse::contents_of (string path_to_file) -> string ifstream file (path_to_file); return { istreambuf_iterator (file), istreambuf_iterator{} }; } + +auto +Parse::exist (std::string name) -> bool +{ + bool result{ false }; + for (auto config : multi ()) + if (config.name == name) + result = true; + // std::for_each (multi ().begin (), multi ().end (), + // [name, &result] (Konfig config) { + // std::cout << "MEH"; + // result = { config.name == name }; + // std::cout << "FOOL"; + // }); + + return result; +} + +// Overload the to_json function for automatic conversion +void +to_json (nlohmann::json &j, const Konfig &k) +{ + j = k.to_json (); +} + +auto +Parse::save (std::string name, std::string topic, + ConfigEntries entries) -> void +{ + if (!entries.name && !entries.url.has_value ()) + { + std::cout << "Either name or url of project are missing. Exiting!" + << std::endl; + return; + } + + Project project{ entries }; + + std::map> topics; + topics[topic] = { entries }; + + Konfig konfig{ name, topics }; + nlohmann::json j = konfig; + + std::cout << std::format ("Saving config with name {} as {}", konfig.name, + j.dump ()); +} diff --git a/src/database/repository.cpp b/src/database/repository.cpp index 6c6ba30..e0f2f6f 100644 --- a/src/database/repository.cpp +++ b/src/database/repository.cpp @@ -32,7 +32,7 @@ Repository::allConfigs (void) -> list list result; Globals globals; - printf (" Configurations: ["); + printf ("Configurations: ["); for (auto config : directory_iterator (globals.onurDir)) { diff --git a/src/handlers/actions.cpp b/src/handlers/actions.cpp index bba0b63..405df28 100644 --- a/src/handlers/actions.cpp +++ b/src/handlers/actions.cpp @@ -30,7 +30,7 @@ auto Actions::klone (Project project, path dirpath) -> void { auto finalCommand{ format ( - "git clone --single-branch --depth=1 --quiet {} {}", project.url, + "git clone --single-branch --depth=1 --quiet {} {}", project.Url (), dirpath.string ()) }; system (finalCommand.c_str ()); } diff --git a/src/handlers/commands.cpp b/src/handlers/commands.cpp index 8457ec6..77bb815 100644 --- a/src/handlers/commands.cpp +++ b/src/handlers/commands.cpp @@ -14,12 +14,14 @@ */ #include +#include #include #include +#include #include "../include/commands.hpp" #include "../include/globals.hpp" -#include "helpers.hpp" +#include "../include/helpers.hpp" using std::cout; using std::endl; @@ -31,25 +33,24 @@ Commands::Commands () {} auto Commands::grab (void) -> void { - for (auto single : parse.multi ()) + for (auto singleConfig : parse.multi ()) { - cout << "\n " << single.topic << ":" << endl; + cout << "\n " << singleConfig.name << ":" << endl; - for (auto subtopic : single.subtopics) + for (auto topic : singleConfig.topics) { - cout << " + " << subtopic.first << endl; - for (auto project : subtopic.second) + cout << " + " << topic.first << endl; + for (auto project : topic.second) { - auto placeholder{ path (globals.projectsDir / single.topic - / subtopic.first / project.name) }; - auto dirpath{ placeholder }; + auto finalpath{ path (globals.projectsDir / singleConfig.name + / topic.first / project.Name ()) }; printProjectInfo (project); - if (exists (dirpath / ".git" / "config")) - actions.pull (dirpath); + if (exists (finalpath / ".git" / "config")) + actions.pull (finalpath); else - actions.klone (project, dirpath); + actions.klone (project, finalpath); } cout << endl; @@ -62,3 +63,57 @@ Commands::backup (void) -> void { cout << "Backing up" << endl; } + +auto +Commands::config (std::string name, ConfigEntries entries) -> void +{ + std::string _name{ name }; + std::optional _topic; + + if (name.contains (".")) + { + std::size_t dot_positon{ name.find (".") }; + _name = { name.substr (0, dot_positon) }; + _topic = { name.substr (dot_positon + 1) }; + } + + if (_topic.has_value ()) + parse.save (_name, _topic.value (), entries); + + // if (!parse.exist (_name)) + // { + // if (!_topic.has_value ()) + // { + // cout << "Provide a topic, exiting!"; + // } + + // cout << std::format ("Config does not exists: {}, imma creating it!", + // name); + + // parse.save (_name, _topic.value (), entries); + + // return; + // } + + for (auto singleConfig : parse.multi ()) + { + if (_name == singleConfig.name) + { + cout << "\n" << singleConfig.name << ":" << endl; + for (auto topic : singleConfig.topics) + { + if (_topic.has_value () && _topic.value () != topic.first) + continue; + + cout << " + " << topic.first << endl; + + for (auto project : topic.second) + printProjectInfo (project); + } + } + + std::string m{ std::format ("{} {} {} {}", name, + entries.name.has_value (), + entries.url.has_value (), entries.branch) }; + } +} diff --git a/src/handlers/helpers.cpp b/src/handlers/helpers.cpp index 6e792de..083a445 100644 --- a/src/handlers/helpers.cpp +++ b/src/handlers/helpers.cpp @@ -27,14 +27,15 @@ printProjectInfo (Project project) -> void { std::string::size_type nameLength = 27; auto nameTruncated - = project.name.length () <= nameLength - ? project.name - : project.name.substr (0, nameLength).append ("..."); + = project.Name ().length () <= nameLength + ? project.Name () + : project.Name ().substr (0, nameLength).append ("..."); std::string::size_type urlLength = 60; - auto urlTruncated = project.url.length () <= urlLength - ? project.url - : project.url.substr (0, urlLength).append ("..."); - auto message{ format ("{:5}- {:35} {:75} {}", "", nameTruncated, - urlTruncated, project.branch) }; + auto urlTruncated + = project.Url ().length () <= urlLength + ? project.Url () + : project.Url ().substr (0, urlLength).append ("..."); + auto message{ format ("{:3}- {:35} {:75} {}", "", nameTruncated, + urlTruncated, project.Branch ()) }; cout << message << endl; } diff --git a/src/include/commands.hpp b/src/include/commands.hpp index 16a3dea..421e2e0 100644 --- a/src/include/commands.hpp +++ b/src/include/commands.hpp @@ -17,8 +17,8 @@ #include "actions.hpp" #include "globals.hpp" +#include "misc.hpp" #include "parse.hpp" -#include "project.hpp" class Commands { @@ -31,4 +31,5 @@ class Commands auto grab (void) -> void; auto backup (void) -> void; + auto config (std::string name, ConfigEntries edit) -> void; }; diff --git a/src/include/konfig.hpp b/src/include/konfig.hpp index 3ff1d39..336d60a 100644 --- a/src/include/konfig.hpp +++ b/src/include/konfig.hpp @@ -18,13 +18,35 @@ #include #include +#include + #include "project.hpp" class Konfig { public: + Konfig (std::string &name, std::map> &topics) + : name (name), topics (topics) {}; + Konfig (); - std::string topic; - std::map > subtopics; + std::string name; + std::map> topics; + + nlohmann::json + to_json () const + { + nlohmann::json j; + j["name"] = name; + j["topics"] = nlohmann::json::object (); + for (const auto &[topic, projects] : topics) + { + j["topics"][topic] = nlohmann::json::array (); + for (const auto &project : projects) + { + j["topics"][topic].push_back (project.to_json ()); + } + } + return j; + } }; diff --git a/src/include/misc.hpp b/src/include/misc.hpp new file mode 100644 index 0000000..af1127a --- /dev/null +++ b/src/include/misc.hpp @@ -0,0 +1,26 @@ +/* + * Onur 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. + * + * Onur 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 Onur. If not, see . + */ + +#pragma once + +#include +#include + +struct ConfigEntries +{ + std::optional name; + std::optional url; + std::string branch{ "master" }; +}; diff --git a/src/include/parse.hpp b/src/include/parse.hpp index 8fd7b88..7d48c38 100644 --- a/src/include/parse.hpp +++ b/src/include/parse.hpp @@ -21,6 +21,7 @@ #include #include "konfig.hpp" +#include "misc.hpp" #include "repository.hpp" class Parse @@ -34,4 +35,8 @@ class Parse auto single (std::filesystem::path filepath) -> Konfig; auto parse_file (std::string jsonString) -> nlohmann::basic_json<>; auto contents_of (std::string path_to_file) -> std::string; + auto exist (std::string name) -> bool; + auto dump () -> void; + auto save (std::string name, std::string topic, + ConfigEntries entries) -> void; }; diff --git a/src/include/project.hpp b/src/include/project.hpp index 4593e70..291ce7c 100644 --- a/src/include/project.hpp +++ b/src/include/project.hpp @@ -15,15 +15,47 @@ #pragma once +#include "misc.hpp" #include +#include + class Project { + std::string name; + std::string url; + std::string branch; + public: Project (std::string name, std::string url, std::string branch) : name (name), url (url), branch (branch) {}; - std::string name; - std::string url; - std::string branch; + Project (ConfigEntries entries) + : name (entries.name.value ()), url (entries.url.value ()), + branch (entries.branch) {}; + + std::string + Name () + { + return name; + } + + std::string + Url () + { + return url; + } + std::string + Branch () + { + return branch; + } + + nlohmann::json + to_json () const + { + return nlohmann::json{ { "name", name }, + { "url", url }, + { "branch", branch } }; + } }; diff --git a/src/main.cpp b/src/main.cpp index 5a5120f..3fc01f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,7 @@ #include #include "include/commands.hpp" +#include "include/misc.hpp" using std::string; @@ -26,30 +27,40 @@ auto main (int argc, char *argv[]) -> int { CLI::App app{ "Easily manage multiple FLOSS repositories." }; + app.require_subcommand (1); argv = { app.ensure_utf8 (argv) }; string filename{ "default" }; app.add_option ("-f,--file", filename, "A help string"); - app.set_version_flag ("--version", string ("0.0.1")); + app.set_version_flag ("--version", string ("0.2.0")); CLI::App *grab_cmd{ app.add_subcommand ("grab", "grab all projects") }; CLI::App *backup_cmd{ app.add_subcommand ( "backup", "compress all selected projects") }; - app.require_subcommand (); + + CLI::App *config_cmd{ app.add_subcommand ("config", + "manage configurations") }; + std::string config_edit; + ConfigEntries edit; + config_cmd + ->add_option ("config", config_edit, "Configuration name and topic") + ->required (true); + config_cmd->add_option ("name", edit.name, "Project name"); + config_cmd->add_option ("url", edit.url, "Project url"); + config_cmd->add_option ("branch", edit.branch, "Project branch"); CLI11_PARSE (app, argc, argv); Commands commands; if (*grab_cmd) - { - commands.grab (); - } + commands.grab (); if (*backup_cmd) - { - commands.backup (); - } + commands.backup (); + + if (*config_cmd) + commands.config (config_edit, edit); return 0; }