Add change config file and run config file

This commit is contained in:
Timofey 2022-08-11 16:43:53 +03:00
parent 77a2ee9989
commit 51188e9f8e
9 changed files with 273 additions and 22 deletions

View file

@ -2,6 +2,7 @@
#include <clippy/target.hpp>
#include <utils/parametres.hpp>
#include <utils/config_path.hpp>
#include <iostream>
#include <memory>
@ -9,8 +10,11 @@
#include <filesystem>
void Clippy::Run(const std::vector<std::string>& args) {
auto result = TryExecuteClippyCommand(args);
if (result) {
if (auto result = TryExecuteClippyCommand(args); result) {
result->Execute();
return;
}
if (auto result = GetScriptTarget(args); result) {
result->Execute();
return;
}
@ -34,15 +38,34 @@ Clippy::TargetPtr Clippy::TryExecuteClippyCommand(
if (CheckPatternParametres(args, Parameter::Skip, "cfg",
Parameter::Anything)) {
projects_.LoadFrom("test");
auto p = projects_.GetCurrentProject();
LoadProjects();
auto p = projects_->GetCurrentProject();
if (p.has_value()) {
return std::make_unique<OpenProjectConfig>(p.value().configuration_file);
return std::make_unique<OpenProjectConfig>(p->GetConfig());
} else {
return std::make_unique<CreateProjectConfig>(projects_);
return std::make_unique<CreateProjectConfig>(projects_.value());
}
}
return nullptr;
}
Clippy::TargetPtr Clippy::GetScriptTarget(
const std::vector<std::string>& args) {
LoadProjects();
auto p = projects_->GetCurrentProject();
if (!p.has_value() || args.size() < 2) {
return nullptr;
}
auto cfg = p->GetConfig();
return cfg.GetTarget(args[1]);
}
void Clippy::LoadProjects() {
if (!projects_.has_value()) {
projects_.emplace(utils::GetProjectDirectory() / "projects");
}
}

View file

@ -14,6 +14,9 @@ class Clippy {
using TargetPtr = std::unique_ptr<clippy::targets::Target>;
private:
TargetPtr TryExecuteClippyCommand(const std::vector<std::string>& args);
TargetPtr GetScriptTarget(const std::vector<std::string>& args);
ProjectList projects_;
void LoadProjects();
std::optional<ProjectList> projects_;
};

52
src/clippy/config.cpp Normal file
View file

@ -0,0 +1,52 @@
#include <clippy/config.hpp>
#include <clippy/target.hpp>
#include <fstream>
#include <algorithm>
std::string Strip(std::string s) {
while (!s.empty() && std::isspace(s.back())) {
s.pop_back();
}
std::reverse(s.begin(), s.end());
while (!s.empty() && std::isspace(s.back())) {
s.pop_back();
}
std::reverse(s.begin(), s.end());
return s;
}
std::unique_ptr<clippy::targets::Target> Config::GetTarget(
const std::string& target) {
std::ifstream in(path_);
std::string current;
std::vector<std::string> target_commands;
bool target_begin = false;
while (std::getline(in, current)) {
if (current == target + ":") {
target_begin = true;
continue;
}
if (current.empty()) {
continue;
}
if (!std::isspace(current[0]) && target_begin) {
break;
}
if (target_begin) {
target_commands.emplace_back(Strip(std::move(current)));
}
}
if (!target_begin) {
return nullptr;
}
return std::make_unique<clippy::targets::RunShellScript>(
std::move(target_commands));
}

View file

@ -1,5 +1,22 @@
#pragma once
class Config {
#include <utils/editor.hpp>
#include <string>
#include <memory>
namespace clippy::targets {
class Target;
}
class Config {
public:
Config(std::string path) : path_(std::move(path)) {}
void Edit() { utils::OpenEditor(path_); }
std::unique_ptr<clippy::targets::Target> GetTarget(const std::string& target);
private:
std::string path_;
};

View file

@ -4,14 +4,72 @@
#include <fstream>
#include <mutex>
#include <random>
#include <chrono>
#include <iostream>
Config ProjectList::GetNewConfig(
const std::filesystem::path& config_directory) {
std::lock_guard guard(lock_file_);
void ProjectList::LoadFrom(const std::string& path) {
utils::filesystem::LockFile lock(path);
std::lock_guard guard(lock);
LoadWithouLock();
std::ifstream in(path);
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::ate);
out << std::filesystem::current_path() << " " << path_to_config << std::endl;
out.close();
projects_.emplace_back(std::filesystem::current_path(), path_to_config);
return {path_to_config};
}
void ProjectList::Load() {
std::lock_guard guard(lock_file_);
LoadWithouLock();
}
void ProjectList::LoadWithouLock() {
std::ifstream in(path_);
Project current;

View file

@ -1,6 +1,8 @@
#pragma once
#include <clippy/config.hpp>
#include <utils/lock_file.hpp>
#include <vector>
#include <filesystem>
#include <optional>
@ -8,20 +10,31 @@
struct Project {
std::strong_ordering operator<=>(const Project&) const = default;
Config GetConfig() { return Config{configuration_file}; }
std::filesystem::path root_project;
std::filesystem::path configuration_file;
};
class ProjectList {
public:
ProjectList() {}
ProjectList(std::filesystem::path path) : path_(std::move(path)), lock_file_(path_) {
Load();
}
void LoadFrom(const std::string& path);
Config GetNewConfig(const std::filesystem::path& config_directory);
const std::vector<Project>& GetProjects() const { return projects_; }
std::optional<Project> GetCurrentProject();
private:
void Load();
void LoadWithouLock();
private:
std::filesystem::path path_;
utils::filesystem::LockFile lock_file_;
std::vector<Project> projects_;
};

37
src/clippy/target.cpp Normal file
View file

@ -0,0 +1,37 @@
namespace clippy::targets {
class Target {
public:
virtual void Execute() = 0;
};
class EmptyTarget : public Target {
public:
void Execute() override {}
};
class OpenProjectConfig : public Target {
public:
OpenProjectConfig(Config config) : config_(config) {}
void Execute() override { config_.Edit(); }
private:
Config config_;
};
class CreateProjectConfig : public Target {
public:
CreateProjectConfig(ProjectList& projects) : projects_(projects) {}
void Execute() override {
auto scripts_path = utils::GetProjectDirectory() / "scripts";
std::filesystem::create_directories(scripts_path);
auto config = projects_.GetNewConfig(scripts_path);
config.Edit();
}
private:
ProjectList& projects_;
};
} // namespace clippy::targets

View file

@ -1,8 +1,14 @@
#pragma once
#include <clippy/project_list.hpp>
#include <clippy/config.hpp>
#include <utils/editor.hpp>
#include <utils/config_path.hpp>
#define SIGPIPE_ALWAYS_IGNORE
#include <cppshell/shell.hpp>
#undef SIGPIPE_ALWAYS_IGNORE
#include <iostream>
#include <functional>
@ -20,15 +26,12 @@ class EmptyTarget : public Target {
class OpenProjectConfig : public Target {
public:
OpenProjectConfig(std::string config_path) : config_path_(config_path) {}
OpenProjectConfig(Config config) : config_(config) {}
void Execute() override {
utils::OpenEditor(config_path_);
std::cout << "Open editor TODO" << std::endl;
}
void Execute() override { config_.Edit(); }
private:
std::string config_path_;
Config config_;
};
class CreateProjectConfig : public Target {
@ -36,10 +39,35 @@ class CreateProjectConfig : public Target {
CreateProjectConfig(ProjectList& projects) : projects_(projects) {}
void Execute() override {
std::cout << "Make new project config and open editor TODO" << std::endl;
auto scripts_path = utils::GetProjectDirectory() / "scripts";
std::filesystem::create_directories(scripts_path);
auto config = projects_.GetNewConfig(scripts_path);
config.Edit();
}
private:
ProjectList& projects_;
};
class RunShellScript : public Target {
public:
RunShellScript(std::vector<std::string> commands)
: commands_(std::move(commands)) {}
void Execute() override {
cppshell::Shell s;
for (auto& i : commands_) {
std::cout << "-> " << i << std::endl;
s.Execute(i);
if (int err = s.GetExitCodeLastCommand(); err != 0) {
std::cout << "ERROR" << std::endl;
}
}
}
private:
std::vector<std::string> commands_;
};
} // namespace clippy::targets

20
src/utils/config_path.hpp Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include <vector>
#include <ranges>
#include <filesystem>
namespace utils {
inline std::filesystem::path GetProjectDirectory() {
namespace fs = std::filesystem;
using std::filesystem::path;
path config_path =
std::string(std::getenv("HOME")) + "/.local/share/clippy-terminal/";
fs::create_directories(config_path);
return config_path;
}
} // namespace utils