diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cd922..ae92603 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB_RECURSE SOURCES_FILES src/*) add_executable(clippy_terminal ${SOURCES_FILES}) target_include_directories(clippy_terminal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_link_libraries(clippy_terminal PRIVATE cppshell tmuxub rang jsoncons yaml-cpp) +target_link_libraries(clippy_terminal cppshell rang) install(TARGETS clippy_terminal DESTINATION bin) @@ -20,31 +20,9 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(cppshell) -FetchContent_Declare( - tmuxub - GIT_REPOSITORY https://gitlab.com/Onyad/tmuxub - GIT_TAG origin/main -) -FetchContent_MakeAvailable(tmuxub) - FetchContent_Declare( rang GIT_REPOSITORY https://github.com/agauniyal/rang.git GIT_TAG origin/master ) FetchContent_MakeAvailable(rang) - -set(JSONCONS_BUILD_TESTS OFF CACHE INTERNAL "Turn off tests") -FetchContent_Declare( - jsoncons - GIT_REPOSITORY https://github.com/danielaparker/jsoncons - GIT_TAG origin/master -) -FetchContent_MakeAvailable(jsoncons) - -FetchContent_Declare( - yaml-cpp - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git - GIT_TAG origin/master -) -FetchContent_MakeAvailable(yaml-cpp) diff --git a/src/clippy/clippy.cpp b/src/clippy/clippy.cpp index b1c8b94..1b9d064 100644 --- a/src/clippy/clippy.cpp +++ b/src/clippy/clippy.cpp @@ -25,13 +25,15 @@ void Clippy::Run(const std::vector& args) { for (size_t i = 1; i < args.size(); ++i) { std::cout << args[i] << (i + 1 == args.size() ? "" : ",") << " "; } - std::cout << "}" << rang::bg::reset << rang::style::reset << std::endl; + std::cout << "}" << std::endl << rang::bg::reset << rang::style::reset; } -Clippy::TargetPtr Clippy::TryExecuteClippyCommand(const std::vector& args) { +Clippy::TargetPtr Clippy::TryExecuteClippyCommand( + const std::vector& args) { using namespace utils::parametres; using namespace clippy::targets; - if (CheckPatternParametres(args, Parameter::Skip, "help", Parameter::Anything)) { + if (CheckPatternParametres(args, Parameter::Skip, "help", + Parameter::Anything)) { std::cout << "Hello I'm clippy" << std::endl; std::cout << "Parametres: { "; for (size_t i = 0; i < args.size(); ++i) { @@ -39,12 +41,11 @@ Clippy::TargetPtr Clippy::TryExecuteClippyCommand(const std::vector } std::cout << "}" << std::endl; - std::cout << "You can use:\n cfg\n crt\n prj\n list\n setname\n loadcfg\n op" << std::endl; - return std::make_unique(); } - if (CheckPatternParametres(args, Parameter::Skip, "cfg", Parameter::Anything)) { + if (CheckPatternParametres(args, Parameter::Skip, "cfg", + Parameter::Anything)) { LoadProjects(); auto p = projects_->GetCurrentProject(); @@ -55,44 +56,17 @@ Clippy::TargetPtr Clippy::TryExecuteClippyCommand(const std::vector } } - if (CheckPatternParametres(args, Parameter::Skip, "crt", Parameter::Anything)) { + if (CheckPatternParametres(args, Parameter::Skip, "crt", + Parameter::Anything)) { LoadProjects(); return std::make_unique(projects_.value()); } - if (CheckPatternParametres(args, Parameter::Skip, "prj", Parameter::Anything)) { - // TODO description current project or project by name - return nullptr; - } - - if (CheckPatternParametres(args, Parameter::Skip, "list", Parameter::Nothing)) { - LoadProjects(); - - return std::make_unique(projects_.value()); - } - - if (CheckPatternParametres(args, Parameter::Skip, "setname", Parameter::Anything)) { - LoadProjects(); - - return std::make_unique(projects_.value(), args[2]); - } - - if (CheckPatternParametres(args, Parameter::Skip, "loadcfg", Parameter::Nothing)) { - LoadProjects(); - - return std::make_unique(projects_.value()); - } - - if (CheckPatternParametres(args, Parameter::Skip, "op", Parameter::Anything)) { - LoadProjects(); - - return std::make_unique(projects_.value(), args[2]); - } - return nullptr; } -Clippy::TargetPtr Clippy::GetScriptTarget(const std::vector& args) { +Clippy::TargetPtr Clippy::GetScriptTarget( + const std::vector& args) { LoadProjects(); auto p = projects_->GetCurrentProject(); diff --git a/src/clippy/config.cpp b/src/clippy/config.cpp index e7499e8..1940174 100644 --- a/src/clippy/config.cpp +++ b/src/clippy/config.cpp @@ -25,13 +25,11 @@ std::unique_ptr Config::GetTarget( std::vector target_commands; target_commands.emplace_back("cd " + initial_directory_); - bool target_exists = false; - bool in_target = false; + bool target_begin = false; while (std::getline(in, current)) { if (current == target + ":") { - target_exists = true; - in_target = true; + target_begin = true; continue; } @@ -39,18 +37,18 @@ std::unique_ptr Config::GetTarget( continue; } - if (!std::isspace(current[0])) { - in_target = false; + if (!std::isspace(current[0]) && target_begin) { + target_begin = false; } - if (in_target) { + if (target_begin) { target_commands.emplace_back(Strip(std::move(current))); } else if (current[0] == '!') { target_commands.emplace_back(current.substr(1, current.size() - 1)); } } - if (!target_exists) { + if (!target_begin) { return nullptr; } diff --git a/src/clippy/project_list.cpp b/src/clippy/project_list.cpp index cf4aa2e..e2ad9f3 100644 --- a/src/clippy/project_list.cpp +++ b/src/clippy/project_list.cpp @@ -1,45 +1,75 @@ #include #include -#include -#include #include -#include #include #include #include #include -#include - -#include -#include -#include "yaml-cpp/node/parse.h" - -#include - -Config ProjectList::GetNewConfig(const std::filesystem::path& config_directory) { +Config ProjectList::GetNewConfig( + const std::filesystem::path& config_directory) { std::lock_guard guard(lock_file_); - LoadWithoutLock(); + LoadWithouLock(); - auto path_to_config = utils::filesystem::GenerateFile(config_directory); + std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count()); + + auto RandomSymbol = [&rnd]() { + int n = rnd() % (26 + 26 + 10); + if (n < 26) { + return 'a' + n; + } else if (n < 26 + 26) { + return 'A' + n - 26; + } else { + return '0' + n - 26 - 26; + } + }; + + auto GenerateFilename = [&rnd, &RandomSymbol]() { + std::string filename; + for (size_t i = 0; i < 6; ++i) { + filename += RandomSymbol(); + } + + return filename; + }; + + auto filename = GenerateFilename(); + while (true) { + bool exist_config = false; + for (auto& project : projects_) { + if (filename == project.configuration_file.filename()) { + exist_config = true; + break; + } + } + if (!exist_config) { + break; + } + + filename = GenerateFilename(); + } + + auto path_to_config = config_directory / filename; + + std::ofstream out(path_, std::ios::app); + out << std::filesystem::current_path() << " " << path_to_config << std::endl; + out.close(); projects_.emplace_back(std::filesystem::current_path(), path_to_config); - SaveConfig(); - return {path_to_config, std::filesystem::current_path()}; } void ProjectList::Load() { std::lock_guard guard(lock_file_); - LoadWithoutLock(); + LoadWithouLock(); } -void ProjectList::OldLoadConfig(const std::string& data) { - std::stringstream in(data); +void ProjectList::LoadWithouLock() { + std::ifstream in(path_); Project current; @@ -48,147 +78,15 @@ void ProjectList::OldLoadConfig(const std::string& data) { } } -template -void UpdateField(jsoncons::json& data, const std::string& field, std::optional member) { - if (member) { - data[field] = static_cast(member.value()); - } -} - -template -void UpdateField(YAML::Node& data, const std::string& field, std::optional member) { - if (member) { - data[field] = static_cast(member.value()); - } -} - -void ProjectList::SaveConfig(tag_json) { - jsoncons::json result; - - result["version"] = "0.1"; - result["projects"] = std::vector(); - - for (auto& project : projects_) { - jsoncons::json current; - current["path_to_config"] = std::string(project.configuration_file); - current["path_root_project"] = std::string(project.root_project); - - UpdateField(current, "name", project.name); - UpdateField(current, "open_script", project.open_script); - - result["projects"].emplace_back(current); - } - - std::ofstream out(path_); - out << result.to_string(); -} - -void ProjectList::SaveConfig() { - YAML::Node result; - result["version"] = "0.2"; - - for (auto& project : projects_) { - YAML::Node current; - - UpdateField(current, "name", project.name); - current["path_root_project"] = std::string(project.root_project); - current["path_to_config"] = std::string(project.configuration_file); - UpdateField(current, "open_script", project.open_script); - - result["projects"].push_back(current); - } - - std::ofstream out(path_); - out << result; -} - -template -std::optional GetOptionalField(const jsoncons::json& data, std::string field) { - return data.contains(field) ? std::make_optional(data[field].as()) : std::nullopt; -} - -template -std::optional GetOptionalField(const YAML::Node& data, std::string field) { - return data[field].IsDefined() ? std::make_optional(data[field].as()) : std::nullopt; -} - -void ProjectList::LoadConfig(const YAML::Node& data) { - if (data["version"].as() != "0.2") { - throw std::logic_error("unsupport version"); - } - - Project current; - for (const auto& project : data["projects"]) { - current.configuration_file = project["path_to_config"].as(); - current.root_project = project["path_root_project"].as(); - - current.name = GetOptionalField(project, "name"); - current.open_script = GetOptionalField(project, "open_script"); - - projects_.emplace_back(current); - } -} - -void ProjectList::LoadConfig(const jsoncons::json& data) { - if (data["version"] != "0.1") { - throw std::logic_error("unsupported version config"); - } - - Project current; - for (auto& project : data["projects"].array_range()) { - current.configuration_file = project["path_to_config"].as(); - current.root_project = project["path_root_project"].as(); - - current.name = GetOptionalField(project, "name"); - current.open_script = GetOptionalField(project, "open_script"); - - projects_.emplace_back(current); - } -} - -void ProjectList::LoadWithoutLock() { - projects_.clear(); - - try { - LoadConfig(YAML::LoadFile(path_)); - } catch (...) { - auto data = utils::filesystem::LoadFile(path_); - - std::cout << "I can't parse yaml. Try read json?" << std::endl; - - std::string result; - std::getline(std::cin, result); - - if (result == "y") { - try { - LoadConfig(jsoncons::json::parse(data)); - } catch (...) { - std::cout << "I can't read project lists. Try fix it?" << std::endl; - - std::string result; - std::getline(std::cin, result); - - if (result == "y") { - OldLoadConfig(data); - SaveConfig(); - } - } - SaveConfig(); - } - } -} - -Project* ProjectList::GetCurrentProject_() { +std::optional ProjectList::GetCurrentProject() { auto current_path = std::filesystem::current_path(); - Project* result = nullptr; - auto UpdateResult = [&result](Project& p) { - if (!result) { - result = &p; + std::optional result; + auto UpdateResult = [&result](Project p) { + if (!result.has_value()) { + result = p; } else { - if (*result < p) { - result = &p; - } + result = std::max(p, result.value()); } }; @@ -210,16 +108,3 @@ Project* ProjectList::GetCurrentProject_() { return result; } - -Project* ProjectList::GetProjectByName_(const std::string& name) { - Project* result = nullptr; - for (auto& project : projects_) { - if (!project.name) { - continue; - } - if (project.name == name) { - result = &project; - } - } - return result; -} diff --git a/src/clippy/project_list.hpp b/src/clippy/project_list.hpp index fe1ba71..5cefefe 100644 --- a/src/clippy/project_list.hpp +++ b/src/clippy/project_list.hpp @@ -1,20 +1,12 @@ #pragma once #include -#include -#include #include #include #include #include -#include -#include -#include "utils/config_path.hpp" -#include "utils/editor.hpp" -#include "utils/filesystem.hpp" - struct Project { Project() {} @@ -23,14 +15,10 @@ struct Project { std::strong_ordering operator<=>(const Project&) const = default; - Config GetConfig() { - return Config{configuration_file, root_project}; - } + Config GetConfig() { return Config{configuration_file, root_project}; } std::filesystem::path root_project; std::filesystem::path configuration_file; - std::optional name; - std::optional open_script; }; class ProjectList { @@ -41,72 +29,13 @@ class ProjectList { Config GetNewConfig(const std::filesystem::path& config_directory); - const std::vector& GetProjects() const { - return projects_; - } + const std::vector& GetProjects() const { return projects_; } - std::optional GetCurrentProject() { - auto* p = GetCurrentProject_(); - if (p) { - return *p; - } else { - return std::nullopt; - } - } - - void SetNameCurrentProject(const std::string& name) { - auto* p = GetCurrentProject_(); - if (p) { - p->name = name; - SaveConfig(); - } else { - throw std::logic_error("Not exists current project"); - } - } - - std::filesystem::path GetCurrentLoadConfig() { - auto* p = GetCurrentProject_(); - if (p) { - if (p->open_script) { - return p->open_script.value(); - } else { - auto scripts_path = utils::GetProjectDirectory() / "scripts"; - { - std::lock_guard lock(lock_file_); - p->open_script = utils::filesystem::GenerateFile(scripts_path); - SaveConfig(); - } - return p->open_script.value(); - } - } else { - throw std::logic_error("Not exists current project"); - } - } - - std::optional GetProjectByName(const std::string& name) { - auto* p = GetProjectByName_(name); - if (p) { - return *p; - } else { - return std::nullopt; - } - } + std::optional GetCurrentProject(); private: - Project* GetCurrentProject_(); - Project* GetProjectByName_(const std::string&); - - void OldLoadConfig(const std::string&); - - struct tag_json {}; - void SaveConfig(tag_json); - - void SaveConfig(); - void Load(); - void LoadConfig(const jsoncons::json&); - void LoadConfig(const YAML::Node&); - void LoadWithoutLock(); + void LoadWithouLock(); private: std::filesystem::path path_; diff --git a/src/clippy/target.hpp b/src/clippy/target.hpp index d2f9b7e..48fab11 100644 --- a/src/clippy/target.hpp +++ b/src/clippy/target.hpp @@ -11,12 +11,8 @@ #include #include -#include #include #include -#include "utils/filesystem.hpp" - -#include namespace clippy::targets { class Target { @@ -35,9 +31,7 @@ class OpenProjectConfig : public Target { public: OpenProjectConfig(Config config) : config_(config) {} - void Execute() override { - config_.Edit(); - } + void Execute() override { config_.Edit(); } ~OpenProjectConfig() override {} private: @@ -64,8 +58,7 @@ class CreateProjectConfig : public Target { class RunShellScript : public Target { public: template