...
This commit is contained in:
parent
caf1e87718
commit
88106b3260
18
build.sh
18
build.sh
@ -43,6 +43,24 @@ if ! command -v make &> /dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if pkg-config is installed
|
||||||
|
if ! command -v pkg-config &> /dev/null; then
|
||||||
|
print_error "pkg-config is not installed. Please install pkg-config first."
|
||||||
|
print_warning "On Ubuntu/Debian: sudo apt-get install pkg-config"
|
||||||
|
print_warning "On Fedora: sudo dnf install pkg-config"
|
||||||
|
print_warning "On Arch: sudo pacman -S pkg-config"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if ncurses is installed
|
||||||
|
if ! pkg-config --exists ncurses; then
|
||||||
|
print_error "ncurses is not installed. Please install ncurses first."
|
||||||
|
print_warning "On Ubuntu/Debian: sudo apt-get install libncurses-dev"
|
||||||
|
print_warning "On Fedora: sudo dnf install ncurses-devel"
|
||||||
|
print_warning "On Arch: sudo pacman -S ncurses"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Configure with CMake
|
# Configure with CMake
|
||||||
print_status "Configuring with CMake..."
|
print_status "Configuring with CMake..."
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
@ -63,17 +63,6 @@ std::vector<std::string> autocomplete_list_commands() {
|
|||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
std::set<std::string> unique_commands; // To ensure deduplication
|
std::set<std::string> unique_commands; // To ensure deduplication
|
||||||
|
|
||||||
// System templates directory
|
|
||||||
const std::string system_templates_dir = "/opt/dropshell/templates";
|
|
||||||
|
|
||||||
// User templates directory
|
|
||||||
std::string user_templates_dir;
|
|
||||||
if (!get_user_directory(user_templates_dir)) {
|
|
||||||
std::cerr << "Error: User directory not set" << std::endl;
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
user_templates_dir += "/usertemplates";
|
|
||||||
|
|
||||||
// Helper function to add commands from a directory
|
// Helper function to add commands from a directory
|
||||||
auto add_commands_from_dir = [&unique_commands](const std::string& dir_path) {
|
auto add_commands_from_dir = [&unique_commands](const std::string& dir_path) {
|
||||||
if (!fs::exists(dir_path)) {
|
if (!fs::exists(dir_path)) {
|
||||||
@ -97,10 +86,16 @@ std::vector<std::string> autocomplete_list_commands() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add commands from both template locations
|
// System templates directory
|
||||||
|
const std::string system_templates_dir = "/opt/dropshell/templates";
|
||||||
add_commands_from_dir(system_templates_dir);
|
add_commands_from_dir(system_templates_dir);
|
||||||
add_commands_from_dir(user_templates_dir);
|
|
||||||
|
|
||||||
|
std::string user_templates_dir;
|
||||||
|
if (get_user_directory(user_templates_dir)) {
|
||||||
|
// User templates directory
|
||||||
|
user_templates_dir += "/usertemplates";
|
||||||
|
add_commands_from_dir(user_templates_dir);
|
||||||
|
}
|
||||||
// Convert set to vector for return
|
// Convert set to vector for return
|
||||||
commands.assign(unique_commands.begin(), unique_commands.end());
|
commands.assign(unique_commands.begin(), unique_commands.end());
|
||||||
return commands;
|
return commands;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
namespace pt = boost::property_tree;
|
namespace pt = boost::property_tree;
|
||||||
@ -18,18 +19,14 @@ bool is_config_loaded() {
|
|||||||
return config_loaded;
|
return config_loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_config_path(std::string& path) {
|
bool get_config_path(std::string &path)
|
||||||
|
{
|
||||||
// Try ~/.config/dropshell/dropshell.conf
|
// Try ~/.config/dropshell/dropshell.conf
|
||||||
const char* home = std::getenv("HOME");
|
const char* home = std::getenv("HOME");
|
||||||
if (home) {
|
if (home) {
|
||||||
fs::path user_path = fs::path(home) / ".config" / "dropshell" / "dropshell.conf";
|
fs::path user_path = fs::path(home) / ".config" / "dropshell" / "dropshell.conf";
|
||||||
if (!fs::exists(user_path)) {
|
|
||||||
// create path
|
|
||||||
fs::create_directories(user_path.parent_path());
|
|
||||||
}
|
|
||||||
|
|
||||||
path = user_path.string();
|
path = user_path.string();
|
||||||
return true;
|
return fs::exists(path);
|
||||||
}
|
}
|
||||||
std::cerr << "Warning: Couldn't determine user directory" << std::endl;
|
std::cerr << "Warning: Couldn't determine user directory" << std::endl;
|
||||||
path = "";
|
path = "";
|
||||||
@ -39,12 +36,7 @@ bool get_config_path(std::string& path) {
|
|||||||
bool load_config() {
|
bool load_config() {
|
||||||
std::string config_path;
|
std::string config_path;
|
||||||
if (!get_config_path(config_path))
|
if (!get_config_path(config_path))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (config_path.empty()) {
|
|
||||||
// No config file found, but this is not an error
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
|
@ -7,9 +7,6 @@ _dropshell_completions() {
|
|||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
root="${COMP_WORDS[1]}"
|
root="${COMP_WORDS[1]}"
|
||||||
|
|
||||||
# List of main commands
|
|
||||||
opts="help version servers templates install backup"
|
|
||||||
|
|
||||||
# add all commands to opts
|
# add all commands to opts
|
||||||
local commands=($(dropshell autocomplete_list_commands))
|
local commands=($(dropshell autocomplete_list_commands))
|
||||||
opts="${opts} ${commands[*]}"
|
opts="${opts} ${commands[*]}"
|
||||||
|
138
src/main.cpp
138
src/main.cpp
@ -63,22 +63,27 @@ std::string safearg(int argc, char *argv[], int index)
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
try {
|
try {
|
||||||
// Load configuration
|
|
||||||
if (!dropshell::load_config()) {
|
|
||||||
std::cerr << "Error: Failed to load configuration" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No arguments provided
|
|
||||||
if (argc < 2) {
|
|
||||||
dropshell::interactive_mode();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle commands
|
// Handle commands
|
||||||
std::string cmd = argv[1];
|
std::string cmd;
|
||||||
|
if (argc > 1) {
|
||||||
|
cmd = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
auto commands = dropshell::autocomplete_list_commands();
|
// don't load old config if we're initializing
|
||||||
|
if (cmd == "init") {
|
||||||
|
if (argc < 3) {
|
||||||
|
std::cerr << "Error: init command requires a directory argument" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
dropshell::init_user_directory(argv[2]);
|
||||||
|
return 0;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == "help" || cmd == "-h" || cmd == "--help") {
|
if (cmd == "help" || cmd == "-h" || cmd == "--help") {
|
||||||
dropshell::print_help();
|
dropshell::print_help();
|
||||||
@ -90,6 +95,70 @@ int main(int argc, char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// silently attempt to load the config file.
|
||||||
|
dropshell::load_config();
|
||||||
|
|
||||||
|
|
||||||
|
// auto compeltion stuff.
|
||||||
|
auto commands = dropshell::autocomplete_list_commands();
|
||||||
|
if (cmd == "autocomplete_list_commands") {
|
||||||
|
// add in standard commands.
|
||||||
|
commands.insert(commands.end(), {
|
||||||
|
"help",
|
||||||
|
"version",
|
||||||
|
"init"
|
||||||
|
});
|
||||||
|
if (dropshell::is_config_loaded()) { // these only work if the config is loaded.
|
||||||
|
commands.insert(commands.end(), {
|
||||||
|
"servers",
|
||||||
|
"templates",
|
||||||
|
"install",
|
||||||
|
"backup"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& command : commands) {
|
||||||
|
std::cout << command << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "autocomplete_list_servers") {
|
||||||
|
if (dropshell::is_config_loaded())
|
||||||
|
{
|
||||||
|
auto servers = dropshell::autocomplete_list_servers();
|
||||||
|
for (const auto& server : servers)
|
||||||
|
std::cout << server << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "autocomplete_list_services") {
|
||||||
|
if (argc < 3) {
|
||||||
|
std::cerr << "Error: autocomplete_list_services requires a server name" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (dropshell::is_config_loaded()) {
|
||||||
|
auto services = dropshell::autocomplete_list_services(argv[2]);
|
||||||
|
for (const auto& service : services)
|
||||||
|
std::cout << service << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// from here we require the config file to be loaded.
|
||||||
|
if (!dropshell::is_config_loaded()) {
|
||||||
|
std::cerr << "Error: Failed to load configuration." << std::endl << "Please run 'dropshell init <path>' to initialise the user directory and create a configuration file." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No arguments provided
|
||||||
|
if (argc < 2) {
|
||||||
|
dropshell::interactive_mode();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == "servers") {
|
if (cmd == "servers") {
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
// Show details for specific server
|
// Show details for specific server
|
||||||
@ -106,47 +175,6 @@ int main(int argc, char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == "init") {
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "Error: init command requires a directory argument" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
dropshell::init_user_directory(argv[2]);
|
|
||||||
return 0;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Error: " << e.what() << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == "autocomplete_list_servers") {
|
|
||||||
auto servers = dropshell::autocomplete_list_servers();
|
|
||||||
for (const auto& server : servers) {
|
|
||||||
std::cout << server << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == "autocomplete_list_services") {
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "Error: autocomplete_list_services requires a server name" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
auto services = dropshell::autocomplete_list_services(argv[2]);
|
|
||||||
for (const auto& service : services) {
|
|
||||||
std::cout << service << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == "autocomplete_list_commands") {
|
|
||||||
for (const auto& command : commands) {
|
|
||||||
std::cout << command << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == "install") {
|
if (cmd == "install") {
|
||||||
std::string server_name;
|
std::string server_name;
|
||||||
std::vector<std::string> servicelist;
|
std::vector<std::string> servicelist;
|
||||||
@ -191,6 +219,8 @@ int main(int argc, char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// handle running a command.
|
||||||
for (const auto& command : commands) {
|
for (const auto& command : commands) {
|
||||||
if (cmd == command) {
|
if (cmd == command) {
|
||||||
std::string server_name;
|
std::string server_name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user