Refaaaacttt00000rr

This commit is contained in:
Your Name 2025-05-04 11:30:57 +12:00
parent 6380ce9178
commit 0e9466365e
11 changed files with 25977 additions and 219 deletions

View File

@ -2,9 +2,8 @@
#include <iostream>
#include <fstream>
#include "config.hpp"
#include "utils/envmanager.hpp"
#include "utils/utils.hpp"
#include "utils/json.hpp"
#include <filesystem>
namespace dropshell {
@ -16,103 +15,116 @@ config & gConfig() {
}
config::config() {
config::config() : mIsConfigSet(false) {
}
config::~config() {
}
bool config::load_config() {
std::string config_path = localfile::dropshell_env();
bool config::load_config() { // load json config file.
std::string config_path = localfile::dropshell_json();
if (config_path.empty() || !std::filesystem::exists(config_path))
return false;
envmanager config_env(config_path);
if (!config_env.load())
std::ifstream config_file(config_path);
if (!config_file.is_open())
return false;
std::string directories = config_env.get_variable_substituted("local.config.directories");
if (directories.empty())
return false;
try {
mConfig = nlohmann::json::parse(config_file);
}
catch (nlohmann::json::parse_error& ex)
{
std::cerr << "Error: Failed to parse config file: " << ex.what() << std::endl;
return false;
}
// Split the directories string into a vector of strings
mLocalConfigPaths = string2multi(directories);
mLocalBackupPath = config_env.get_variable_substituted("local.backup.directory");
// legacy config file conversion
if (mLocalBackupPath.empty() && mLocalConfigPaths.size()>0)
mLocalBackupPath = mLocalConfigPaths[0] + "/backups";
//std::cout << "Local config path: " << mLocalConfigPath << std::endl;
mIsConfigSet = true;
return true;
}
void config::save_config()
bool config::save_config()
{
if (mLocalConfigPaths.empty())
std::string config_path = localfile::dropshell_json();
if (config_path.empty())
return false;
std::filesystem::create_directories(get_parent(config_path));
std::ofstream config_file(config_path);
if (!config_file.is_open())
return false;
if (!mIsConfigSet)
{
std::cerr << "Warning: Unable to save configuration file, as DropShell has not been initialised."<< std::endl;
std::cerr << "Please run 'dropshell init <path>' to initialise DropShell." << std::endl;
return;
}
std::string homedir = localpath::current_user_home();
std::string dropshell_base = homedir + "/.dropshell";
mConfig["tempfiles"] = dropshell_base + "/tmp";
mConfig["backups"] = dropshell_base + "/backups";
mConfig["template_cache"] = dropshell_base + "/cache";
mConfig["template_registry_urls"] = {
"https://templates.dropshell.app"
};
mConfig["server_definition_paths"] = {
dropshell_base + "/servers"
};
mConfig["template_upload_registry_url"] = "https://templates.dropshell.app";
mConfig["template_upload_registry_token"] = "SECRETTOKEN";
}
std::string parent_path = dropshell::get_parent(localfile::dropshell_env());
std::filesystem::create_directories(parent_path);
config_file << mConfig.dump(4);
config_file.close();
return true;
std::string config_path = localfile::dropshell_env();
envmanager config_env(config_path);
config_env.set_variable("local.config.directories", multi2string(mLocalConfigPaths));
config_env.set_variable("local.backup.directory", mLocalBackupPath);
config_env.save();
std::filesystem::create_directories(get_local_template_cache_path());
std::filesystem::create_directories(get_local_backup_path());
std::filesystem::create_directories(get_local_tempfiles_path());
for (auto & p : get_local_server_definition_paths())
std::filesystem::create_directories(p);
}
bool config::is_config_set() const
{
return !mLocalConfigPaths.empty() && !mLocalBackupPath.empty();
return mIsConfigSet;
}
const std::vector<std::string> & config::get_local_config_directories() const
{
return mLocalConfigPaths;
std::string config::get_local_tempfiles_path() {
return mConfig["tempfiles"];
}
bool config::add_local_config_directory(const std::string &path)
{
if (path.empty())
return false;
std::string config::get_local_backup_path() {
return mConfig["backups"];
}
// Convert to canonical path, using std::filesystem
std::filesystem::path abs_path = std::filesystem::canonical(path);
// The directory must exist
if (!std::filesystem::exists(abs_path)) {
std::cerr << "Error: The local config directory does not exist: " << abs_path.string() << std::endl;
return false;
std::string config::get_local_template_cache_path() {
return mConfig["template_cache"];
}
std::vector<std::string> config::get_template_registry_urls() {
nlohmann::json template_registry_urls = mConfig["template_registry_urls"];
std::vector<std::string> urls;
for (auto &url : template_registry_urls) {
urls.push_back(url);
}
// Add to config paths if not already there
for (auto &p : mLocalConfigPaths)
{ // robustly compare the two paths.
if (p == abs_path.string())
{
std::cerr << "Warning: The local config directory is already registered: " << abs_path.string() << std::endl;
std::cerr << "No changes made to the DropShell configuration." << std::endl;
return false;
}
}
mLocalConfigPaths.push_back(abs_path.string());
if (mLocalBackupPath.empty())
mLocalBackupPath = abs_path.string() + "/backups";
return true;
return urls;
}
const std::string &config::get_local_backup_path() const
{
return mLocalBackupPath;
std::vector<std::string> config::get_local_server_definition_paths() {
nlohmann::json server_definition_paths = mConfig["server_definition_paths"];
std::vector<std::string> paths;
for (auto &path : server_definition_paths) {
paths.push_back(path);
}
return paths;
}
std::string config::get_template_upload_registry_url() {
return mConfig["template_upload_registry_url"];
}
std::string config::get_template_upload_registry_token() {
return mConfig["template_upload_registry_token"];
}
} // namespace dropshell

View File

@ -2,6 +2,7 @@
#include <string>
#include <vector>
#include "utils/json.hpp"
namespace dropshell {
@ -9,19 +10,25 @@ class config {
public:
config();
~config();
bool load_config();
void save_config();
bool save_config();
bool is_config_set() const;
const std::vector<std::string> & get_local_config_directories() const;
bool add_local_config_directory(const std::string& path);
const std::string & get_local_backup_path() const;
std::string get_local_tempfiles_path();
std::string get_local_backup_path();
std::string get_local_template_cache_path();
std::vector<std::string> get_template_registry_urls();
std::vector<std::string> get_local_server_definition_paths();
std::string get_template_upload_registry_url();
std::string get_template_upload_registry_token();
private:
std::vector<std::string> mLocalConfigPaths;
std::string mLocalBackupPath;
nlohmann::json mConfig;
bool mIsConfigSet;
};

View File

@ -33,7 +33,7 @@ void print_help() {
std::cout << std::endl;
std::cout << "dropshell ..." << std::endl;
std::cout << " help Show this help message" << std::endl;
std::cout << " init DIR Add DIR as a local server config directory (can add several)" << std::endl;
std::cout << " edit Edit the configuration of dropshell" << std::endl;
if (gConfig().is_config_set()) {
std::cout << " server NAME Show details for specific server" << std::endl;
@ -68,39 +68,6 @@ int die(const std::string & msg) {
return 1;
}
int init(const std::vector<std::string> &args)
{
std::string lcd;
if (args.size() < 3) {
std::cerr << "Error: init command requires a directory argument" << std::endl;
return 1;
}
try {
if (!gConfig().add_local_config_directory(args[2]))
return 1; // error already reported
gConfig().save_config();
std::cout << "Config directory added: " << gConfig().get_local_config_directories().back() << std::endl;
dropshell::create_readme_local_config_dir(gConfig().get_local_config_directories().back());
if (gConfig().get_local_config_directories().size() ==1)
std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server <server-name>'" << std::endl;
else
{
std::cout << "DropShell will now use all of the following directories for configuration:" << std::endl;
for (const auto& dir : gConfig().get_local_config_directories()) {
std::cout << " " << dir << std::endl;
}
std::cout << "You can edit the config file manually with: dropshell edit" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error in init: " << e.what() << std::endl;
return 1;
}
return 0;
}
struct ServerAndServices {
std::string server_name;
std::vector<LocalServiceInfo> servicelist;
@ -162,32 +129,38 @@ int main(int argc, char* argv[]) {
return 0;
}
if (cmd == "init") {
return init(argvec);
}
if (cmd == "help" || cmd == "-h" || cmd == "--help" || cmd== "h" || cmd=="halp") {
print_help();
return 0;
}
if (cmd == "edit" && argc < 3) {
std::string config_file = localfile::dropshell_env();
std::filesystem::create_directories( get_parent(config_file) );
edit_file(config_file, "Please ensure any directories you have introduced in the config file exist.");
std::string config_file = localfile::dropshell_json();
if (!edit_file(config_file) || !std::filesystem::exists(config_file))
return die("Error: Failed to edit config file.");
gConfig().load_config();
if (!gConfig().is_config_set())
return die("Error: Failed to load and parse edited config file.");
gConfig().save_config();
gConfig().load_config();
std::cout << "Successfully edited config file." << std::endl;
return 0;
}
// ------------------------------------------------------------
// from here we require the config file to be loaded.
if (!gConfig().is_config_set())
return die("Please run 'dropshell init <path>' to initialise the user directory and create a configuration file.");
return die("Please run 'dropshell edit' to set up the dropshell configuration.");
const std::vector<std::string> & local_config_directories = gConfig().get_local_config_directories();
std::cout << "Config directories: ";
for (auto & dir : local_config_directories)
std::cout << "["<< dir << "] ";
std::cout << std::endl;
const std::vector<std::string> & server_definition_paths = gConfig().get_local_server_definition_paths();
if (server_definition_paths.size()>1) { // only show if there are multiple.
std::cout << "Server definition paths: ";
for (auto & dir : server_definition_paths)
std::cout << "["<< dir << "] ";
std::cout << std::endl;
}
if (cmd == "server" || cmd == "servers" || cmd == "list" || cmd == "view")
switch (argc)

View File

@ -144,7 +144,12 @@ bool server_env_manager::run_remote_template_command_and_capture_output(const st
}
bool server_env_manager::execute_local_command(const sCommand& command) {
return (system(command.construct_safecmd().c_str()) == 0);
auto status = system(command.construct_safecmd().c_str());
if ( WIFEXITED(status) ) {
int returned = WEXITSTATUS(status);
return (returned == 0);
}
return false;
}
bool server_env_manager::execute_local_command_and_capture_output(const sCommand& command, std::string &output)
@ -159,7 +164,11 @@ bool server_env_manager::execute_local_command_and_capture_output(const sCommand
output += buffer;
}
int status = pclose(pipe);
return (status == 0);
if ( WIFEXITED(status) ) {
int returned = WEXITSTATUS(status);
return (returned == 0);
}
return false;
}

View File

@ -450,17 +450,20 @@ void edit_server(const std::string &server_name)
<< "Once moved, reinstall all services with: dropshell install " << server_name;
std::string config_file = serverpath + "/server.env";
edit_file(config_file, aftertext.str());
if (!edit_file(config_file))
std::cerr << "Error: Failed to edit server.env" << std::endl;
else
std::cout << aftertext.str() << std::endl;
}
void edit_file(const std::string &file_path, const std::string & aftertext)
bool edit_file(const std::string &file_path)
{
std::string cmd = "nano -w "+file_path+" ; echo \""+aftertext+"\"";
execlp("bash","bash","-c",cmd.c_str(), nullptr);
// If exec returns, it means there was an error
perror("ssh execution failed");
exit(EXIT_FAILURE);
// make sure parent directory exists.
std::string parent_dir = get_parent(file_path);
std::filesystem::create_directories(parent_dir);
std::string cmd = "nano -w " + file_path;
return server_env_manager::execute_local_command(cmd);
}
void service_runner::interactive_ssh_service()
@ -483,9 +486,8 @@ void service_runner::edit_service_config()
return;
}
std::string aftertext = "To apply your changes, run:\n dropshell install " + mServer + " " + mService;
edit_file(config_file, aftertext);
if (edit_file(config_file) && std::filesystem::exists(config_file))
std::cout << "To apply your changes, run:\n dropshell install " + mServer + " " + mService << std::endl;
}
@ -497,7 +499,7 @@ bool service_runner::restore(std::string backup_file, bool silent)
return false;
}
std::string local_backups_dir = localpath::backups_path();
std::string local_backups_dir = gConfig().get_local_backup_path();
std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string();
if (! std::filesystem::exists(local_backup_file_path)) {
@ -632,7 +634,7 @@ bool service_runner::backup(bool silent) {
}
// Create backups directory locally if it doesn't exist
std::string local_backups_dir = localpath::backups_path();
std::string local_backups_dir = gConfig().get_local_backup_path();
if (local_backups_dir.empty()) {
std::cerr << "Error: Local backups directory not found - is DropShell initialised?" << std::endl;
return false;

View File

@ -109,7 +109,7 @@ class service_runner {
// other utility routines (not specific to service_runner)
void interactive_ssh(const std::string & server_name, const std::string & command);
void edit_server(const std::string & server_name);
void edit_file(const std::string & file_path, const std::string & aftertext);
bool edit_file(const std::string & file_path);
// check if the service template and config are up to date on the remote server.
class service_versions {

View File

@ -12,14 +12,13 @@ namespace dropshell {
namespace localfile {
std::string dropshell_env() {
// Try ~/.config/dropshell/dropshell.env
const char* home = std::getenv("HOME");
if (home) {
fs::path user_path = fs::path(home) / ".config" / "dropshell" / "dropshell.env";
std::string dropshell_json() {
// Try ~/.config/dropshell/dropshell.json
std::string homedir = localpath::current_user_home();
if (!homedir.empty()) {
fs::path user_path = fs::path(homedir) / ".config" / "dropshell" / "dropshell.json";
return user_path.string();
}
std::cerr << "Warning: Couldn't determine user directory" << std::endl;
return std::string();
}
@ -39,60 +38,46 @@ namespace localfile {
return (servicepath.empty() ? "" : (fs::path(servicepath) / ".template_info.env").string());
}
std::string service_hash(const std::string &server_name, const std::string &service_name) {
std::string config_path = localpath::config();
if (server_name.empty() || service_name.empty() || config_path.empty())
return std::string();
return (fs::path(config_path) / ".remote_versions" / server_name / (service_name + ".hash.env")).string();
}
} // namespace localfile
// ------------------------------------------------------------------------------------------
namespace localpath {
// /opt/dropshell/templates
std::string system_templates() {
return "/opt/dropshell/templates";
}
// configured by user - defaults to first config_path/backups.
std::string backups_path() {
return gConfig().get_local_backup_path();
}
int num_config_directories() {
return gConfig().get_local_config_directories().size();
}
std::string config(int index) {
return (num_config_directories()>index) ? gConfig().get_local_config_directories()[index] : "";
}
std::string config_templates(int index) {
return (num_config_directories()>index) ? (gConfig().get_local_config_directories()[index]+"/templates") : "";
}
std::string config_servers(int index) {
return (num_config_directories()>index) ? (gConfig().get_local_config_directories()[index]+"/servers") : "";
}
std::string server(const std::string &server_name) {
if (server_name.empty()) return "";
for (auto &dir : gConfig().get_local_config_directories())
if (fs::exists(dir + "/servers/" + server_name))
return dir + "/servers/" + server_name;
for (auto &dir : gConfig().get_local_server_definition_paths())
if (fs::exists(dir + server_name))
return dir + server_name;
return "";
}
std::string service(const std::string &server_name, const std::string &service_name) {
std::string serverpath = localpath::server(server_name);
return (serverpath.empty() || service_name.empty() ? "" : (serverpath+"/"+service_name));
return ((serverpath.empty() || service_name.empty()) ? "" : (serverpath+"/"+service_name));
}
std::string remote_versions(const std::string &server_name, const std::string &service_name)
{
std::string template_cache_path = gConfig().get_local_template_cache_path();
return ((template_cache_path.empty() || service_name.empty()) ? "" :
(template_cache_path+"/remote_versions/"+service_name+".json"));
}
std::string local_bin(){
return current_user_home() + "/.local/bin";
}
std::string current_user_home(){
char * homedir = std::getenv("HOME");
if (homedir)
{
std::filesystem::path homedir_path(homedir);
return fs::canonical(homedir_path).string();
}
std::cerr << "Warning: Couldn't determine user directory" << std::endl;
return std::string();
}
} // namespace localpath
// ------------------------------------------------------------------------------------------
// remote paths

View File

@ -9,49 +9,52 @@ namespace dropshell {
//------------------------------------------------------------------------------------------------
// local user config directories
// config_path
// |-- servers
// | |-- server_name
// | |-- server.env
// | |-- services
// | |-- service_name
// | |-- service.env
// | |-- .template_info.env
// | |-- (other config files for specific server&service)
// |-- templates
// | |-- template_name
// | |-- (script files)
// | |-- _default.env
// | |-- example
// | |-- service.env
// | |-- .template_info.env
// | |-- (other service config files)
// |-- .remote_versions
// | |-- server_name
// | |-- service_name.hash.env
// ~/.config/dropshell/dropshell.json
// server_definition_path
// |-- <server_name>
// |-- server.env
// |-- services
// |-- <service_name>
// |-- service.env
// |-- .template_info.env
// |-- (...other config files for specific server&service...)
// backup path
// |-- katie-_-squashkiwi-_-squashkiwi-test-_-2025-04-28_21-23-59.tgz
// temp files path
// template cache path
// |-- templates
// | |-- <template_name>.json
// | |-- <template_name>
// | |-- (...script files...)
// | |-- _default.env
// | |-- example
// | |-- service.env
// | |-- .template_info.env
// | |-- (...other service config files...)
// |-- remote_versions
// | |-- server_name-service_name.json
namespace localfile {
// ~/.config/dropshell/dropshell.conf
std::string dropshell_env();
// ~/.config/dropshell/dropshell.json
std::string dropshell_json();
std::string server_env(const std::string &server_name);
std::string service_env(const std::string &server_name, const std::string &service_name);
std::string template_info_env(const std::string &server_name, const std::string &service_name);
std::string service_hash(const std::string &server_name, const std::string &service_name);
} // namespace localfile
namespace localpath {
// /opt/dropshell/templates
std::string system_templates();
// configured by user - defaults to first config_path/backups.
std::string backups_path();
int num_config_directories();
std::string config(int index=0);
std::string config_templates(int index=0);
std::string config_servers(int index=0);
std::string server(const std::string &server_name);
std::string service(const std::string &server_name, const std::string &service_name);
std::string remote_versions(const std::string &server_name, const std::string &service_name);
std::string local_bin();
std::string current_user_home();
} // namespace local
@ -88,4 +91,4 @@ namespace dropshell {
} // namespace dropshell
#endif
#endif // DIRECTORIES_HPP

25578
src/utils/json.hpp Normal file

File diff suppressed because it is too large Load Diff

187
src/utils/json_fwd.hpp Normal file
View File

@ -0,0 +1,187 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
#include <cstdint> // int64_t, uint64_t
#include <map> // map
#include <memory> // allocator
#include <string> // string
#include <vector> // vector
// #include <nlohmann/detail/abi_macros.hpp>
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
// This file contains all macro definitions affecting or depending on the ABI
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
#warning "Already included a different version of the library!"
#endif
#endif
#endif
#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum)
#ifndef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 0
#endif
#ifndef JSON_DIAGNOSTIC_POSITIONS
#define JSON_DIAGNOSTIC_POSITIONS 0
#endif
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
#endif
#if JSON_DIAGNOSTICS
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
#else
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
#endif
#if JSON_DIAGNOSTIC_POSITIONS
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp
#else
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
#else
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
#endif
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c)
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif
/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
@since version 1.0.0
*/
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief default JSONSerializer template argument
This serializer ignores the template arguments and uses ADL
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
for serialization.
*/
template<typename T = void, typename SFINAE = void>
struct adl_serializer;
/// a class to store JSON values
/// @sa https://json.nlohmann.me/api/basic_json/
template<template<typename U, typename V, typename... Args> class ObjectType =
std::map,
template<typename U, typename... Args> class ArrayType = std::vector,
class StringType = std::string, class BooleanType = bool,
class NumberIntegerType = std::int64_t,
class NumberUnsignedType = std::uint64_t,
class NumberFloatType = double,
template<typename U> class AllocatorType = std::allocator,
template<typename T, typename SFINAE = void> class JSONSerializer =
adl_serializer,
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
class CustomBaseClass = void>
class basic_json;
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
/// @sa https://json.nlohmann.me/api/json_pointer/
template<typename RefStringType>
class json_pointer;
/*!
@brief default specialization
@sa https://json.nlohmann.me/api/json/
*/
using json = basic_json<>;
/// @brief a minimal map-like container that preserves insertion order
/// @sa https://json.nlohmann.me/api/ordered_map/
template<class Key, class T, class IgnoredLess, class Allocator>
struct ordered_map;
/// @brief specialization that maintains the insertion order of object keys
/// @sa https://json.nlohmann.me/api/ordered_json/
using ordered_json = basic_json<nlohmann::ordered_map>;
NLOHMANN_JSON_NAMESPACE_END
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_

View File

@ -5,6 +5,8 @@ _autocommandrun() {
command="$1"
key="$2"
value="$3"
# only passed through if command is backup or restore.
backup_file="$4"
temp_path="$5"
@ -26,7 +28,7 @@ _autocommandrun() {
_autocommandparse() {
# first argument is the command
# last two arguments are the backup file and the temporary path
# if the command is backup or restore, then the last two arguments are the backup file and the temporary path
# all other arguments are of form:
# key=value
# where key can be one of volume, path or file.