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 <clippy/target.hpp>
|
||||||
|
|
||||||
#include <utils/parametres.hpp>
|
#include <utils/parametres.hpp>
|
||||||
|
#include <utils/config_path.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -9,8 +10,11 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
void Clippy::Run(const std::vector<std::string>& args) {
|
void Clippy::Run(const std::vector<std::string>& args) {
|
||||||
auto result = TryExecuteClippyCommand(args);
|
if (auto result = TryExecuteClippyCommand(args); result) {
|
||||||
if (result) {
|
result->Execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (auto result = GetScriptTarget(args); result) {
|
||||||
result->Execute();
|
result->Execute();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,15 +38,34 @@ Clippy::TargetPtr Clippy::TryExecuteClippyCommand(
|
||||||
|
|
||||||
if (CheckPatternParametres(args, Parameter::Skip, "cfg",
|
if (CheckPatternParametres(args, Parameter::Skip, "cfg",
|
||||||
Parameter::Anything)) {
|
Parameter::Anything)) {
|
||||||
projects_.LoadFrom("test");
|
LoadProjects();
|
||||||
auto p = projects_.GetCurrentProject();
|
auto p = projects_->GetCurrentProject();
|
||||||
|
|
||||||
if (p.has_value()) {
|
if (p.has_value()) {
|
||||||
return std::make_unique<OpenProjectConfig>(p.value().configuration_file);
|
return std::make_unique<OpenProjectConfig>(p->GetConfig());
|
||||||
} else {
|
} else {
|
||||||
return std::make_unique<CreateProjectConfig>(projects_);
|
return std::make_unique<CreateProjectConfig>(projects_.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
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>;
|
using TargetPtr = std::unique_ptr<clippy::targets::Target>;
|
||||||
private:
|
private:
|
||||||
TargetPtr TryExecuteClippyCommand(const std::vector<std::string>& args);
|
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
|
#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 <fstream>
|
||||||
#include <mutex>
|
#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) {
|
LoadWithouLock();
|
||||||
utils::filesystem::LockFile lock(path);
|
|
||||||
std::lock_guard guard(lock);
|
|
||||||
|
|
||||||
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;
|
Project current;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <clippy/config.hpp>
|
#include <clippy/config.hpp>
|
||||||
|
|
||||||
|
#include <utils/lock_file.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -8,20 +10,31 @@
|
||||||
struct Project {
|
struct Project {
|
||||||
std::strong_ordering operator<=>(const Project&) const = default;
|
std::strong_ordering operator<=>(const Project&) const = default;
|
||||||
|
|
||||||
|
Config GetConfig() { return Config{configuration_file}; }
|
||||||
|
|
||||||
std::filesystem::path root_project;
|
std::filesystem::path root_project;
|
||||||
std::filesystem::path configuration_file;
|
std::filesystem::path configuration_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProjectList {
|
class ProjectList {
|
||||||
public:
|
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_; }
|
const std::vector<Project>& GetProjects() const { return projects_; }
|
||||||
|
|
||||||
std::optional<Project> GetCurrentProject();
|
std::optional<Project> GetCurrentProject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Load();
|
||||||
|
void LoadWithouLock();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::filesystem::path path_;
|
||||||
|
utils::filesystem::LockFile lock_file_;
|
||||||
|
|
||||||
std::vector<Project> projects_;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <clippy/project_list.hpp>
|
#include <clippy/project_list.hpp>
|
||||||
|
#include <clippy/config.hpp>
|
||||||
|
|
||||||
#include <utils/editor.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 <iostream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -20,15 +26,12 @@ class EmptyTarget : public Target {
|
||||||
|
|
||||||
class OpenProjectConfig : public Target {
|
class OpenProjectConfig : public Target {
|
||||||
public:
|
public:
|
||||||
OpenProjectConfig(std::string config_path) : config_path_(config_path) {}
|
OpenProjectConfig(Config config) : config_(config) {}
|
||||||
|
|
||||||
void Execute() override {
|
void Execute() override { config_.Edit(); }
|
||||||
utils::OpenEditor(config_path_);
|
|
||||||
std::cout << "Open editor TODO" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string config_path_;
|
Config config_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CreateProjectConfig : public Target {
|
class CreateProjectConfig : public Target {
|
||||||
|
@ -36,10 +39,35 @@ class CreateProjectConfig : public Target {
|
||||||
CreateProjectConfig(ProjectList& projects) : projects_(projects) {}
|
CreateProjectConfig(ProjectList& projects) : projects_(projects) {}
|
||||||
|
|
||||||
void Execute() override {
|
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:
|
private:
|
||||||
ProjectList& projects_;
|
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
|
} // 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