Add change config file and run config file
This commit is contained in:
parent
77a2ee9989
commit
51188e9f8e
9 changed files with 273 additions and 22 deletions
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
52
src/clippy/config.cpp
Normal 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));
|
||||
}
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
37
src/clippy/target.cpp
Normal 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
|
|
@ -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
20
src/utils/config_path.hpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue