Fixed minor issues

- Fixed error message formatting
- Fixed setting verbosity levels
- Fixed implementation of `replace_first` and `replace_all`
- Fixed issue where installing a package would failed because of unescaped single quotes in SQL statement
- Fixed error code returned from SQLITE related errors
- Fixed verbose flag not being repeatable and set correctly
- Fixed some error messages to correctly reflect occuring error
- Fixed the prompt asking the user twice and not taking a default input
- Added functions to get logging default prefixes
- Added `version` command (not implemented yet)
This commit is contained in:
David Allen 2023-06-18 21:10:50 -06:00
parent 02a4e879a8
commit c88cb08e03
9 changed files with 126 additions and 121 deletions

View file

@ -93,18 +93,17 @@ namespace gdpm{
namespace log { namespace log {
static constexpr void error(const gdpm::error& e){ static constexpr void error(const gdpm::error& e){
#if GDPM_LOG_LEVEL > ERROR #if GDPM_LOG_LEVEL > ERROR
set_prefix_if(std::format("[ERROR {}] ", utils::timestamp()), true);
set_suffix_if("\n");
vlog( vlog(
fmt::format(GDPM_COLOR_LOG_ERROR "[ERROR {}] {}\n" GDPM_COLOR_LOG_RESET, utils::timestamp(), e.get_message()), fmt::format(GDPM_COLOR_LOG_ERROR "{}{}\n" GDPM_COLOR_LOG_RESET, prefix.contents, e.get_message()),
fmt::make_format_args("" /*e.get_message()*/) fmt::make_format_args(prefix.contents, e.get_message())
); );
#endif #endif
} }
template <typename S, typename...Args> static void error(const char *p, const gdpm::error& e){
static constexpr void error(const S& prefix, const gdpm::error& e){ println("{}{}{}", p, prefix.contents, e.get_message());
vlog(
fmt::format(GDPM_COLOR_LOG_ERROR + prefix + GDPM_COLOR_LOG_RESET, e.get_message())
);
} }
} }
} }

View file

@ -25,10 +25,10 @@ namespace gdpm::log
enum level_e : int{ enum level_e : int{
NONE = 0, NONE = 0,
INFO = 1, ERROR = 1,
WARNING = 2, INFO = 2,
DEBUG = 3, DEBUG = 3,
ERROR = 4 WARNING = 4,
}; };
enum flag_opt { enum flag_opt {
@ -36,11 +36,17 @@ namespace gdpm::log
PRINT_STDERR = 0b00000010 PRINT_STDERR = 0b00000010
}; };
static int level = INFO; struct prefix {
static string prefix = ""; string contents = "";
static string suffix = ""; string enclosing_start = "]";
static string path = ""; string enclosing_end = "[";
static std::bitset<8> flags = PRINT_STDOUT | PRINT_STDERR; };
static int level = INFO;
static prefix prefix = {};
static string suffix = "";
static string path = "";
static std::bitset<8> flags = PRINT_STDOUT | PRINT_STDERR;
static bool print_to_stdout; static bool print_to_stdout;
static bool print_to_stderr; static bool print_to_stderr;
@ -60,14 +66,18 @@ namespace gdpm::log
return flags.test(flag); return flags.test(flag);
} }
inline constexpr void set_prefix_if(const std::string& v, bool predicate = !prefix.empty()){ inline constexpr void set_prefix_if(const std::string& v, bool predicate = prefix.contents.empty()){
prefix = (predicate) ? v : prefix; prefix.contents = (predicate) ? v : prefix.contents;
} }
inline constexpr void set_suffix_if(const std::string& v, bool predicate = !suffix.empty()){ inline constexpr void set_suffix_if(const std::string& v, bool predicate = suffix.empty()){
suffix = (predicate) ? v : suffix; suffix = (predicate) ? v : suffix;
} }
inline constexpr const char* get_info_prefix() { return "[INFO {}] "; }
inline constexpr const char* get_error_prefix() { return "[ERROR {}] "; }
inline constexpr const char* get_debug_prefix() { return "[DEBUG {}] "; }
static void vlog(fmt::string_view format, fmt::format_args args){ static void vlog(fmt::string_view format, fmt::format_args args){
fmt::vprint(format, args); fmt::vprint(format, args);
} }
@ -81,10 +91,10 @@ namespace gdpm::log
if(log::level < to_int(log::INFO)) if(log::level < to_int(log::INFO))
return; return;
#if GDPM_LOG_LEVEL > NONE #if GDPM_LOG_LEVEL > NONE
set_prefix_if(fmt::format("[INFO {}] ", utils::timestamp())); set_prefix_if(fmt::format( get_info_prefix(), utils::timestamp()), true);
set_suffix_if("\n"); set_suffix_if("\n");
vlog( vlog(
fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix, format, suffix), fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix),
fmt::make_format_args(args...) fmt::make_format_args(args...)
); );
#endif #endif
@ -95,10 +105,10 @@ namespace gdpm::log
if(log::level < to_int(log::INFO)) if(log::level < to_int(log::INFO))
return; return;
#if GDPM_LOG_LEVEL > INFO #if GDPM_LOG_LEVEL > INFO
set_prefix_if(fmt::format("[INFO {}] ", utils::timestamp())); set_prefix_if(fmt::format(get_info_prefix(), utils::timestamp()), true);
set_suffix_if(""); set_suffix_if("", true);
vlog( vlog(
fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix, format, suffix), fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix),
fmt::make_format_args(args...) fmt::make_format_args(args...)
); );
#endif #endif
@ -109,10 +119,10 @@ namespace gdpm::log
if(log::level < to_int(log::ERROR)) if(log::level < to_int(log::ERROR))
return; return;
#if GDPM_LOG_LEVEL > ERROR #if GDPM_LOG_LEVEL > ERROR
set_prefix_if(std::format("[ERROR {}] ", utils::timestamp())); set_prefix_if(std::format(get_error_prefix(), utils::timestamp()), true);
set_suffix_if("\n"); set_suffix_if("\n");
vlog( vlog(
fmt::format(GDPM_COLOR_LOG_ERROR "{}{}{}" GDPM_COLOR_LOG_RESET, prefix, format, suffix), fmt::format(GDPM_COLOR_LOG_ERROR "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix),
fmt::make_format_args(args...) fmt::make_format_args(args...)
); );
#endif #endif
@ -123,10 +133,10 @@ namespace gdpm::log
if(log::level < to_int(log::DEBUG)) if(log::level < to_int(log::DEBUG))
return; return;
#if GDPM_LOG_LEVEL > DEBUG #if GDPM_LOG_LEVEL > DEBUG
set_prefix_if(std::format("[DEBUG {}] ", utils::timestamp())); set_prefix_if(std::format(get_debug_prefix(), utils::timestamp()), true);
set_suffix_if("\n"); set_suffix_if("\n");
vlog( vlog(
fmt::format(GDPM_COLOR_LOG_DEBUG "{}{}{}" GDPM_COLOR_LOG_RESET, prefix, format, suffix), fmt::format(GDPM_COLOR_LOG_DEBUG "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix),
fmt::make_format_args(args...) fmt::make_format_args(args...)
); );
#endif #endif

View file

@ -40,6 +40,7 @@ namespace gdpm::package_manager {
remote_list, remote_list,
ui, ui,
help, help,
version,
none none
}; };

View file

@ -103,8 +103,8 @@ namespace gdpm::utils {
std::string trim_right(const std::string& s); std::string trim_right(const std::string& s);
std::string trim_right(const std::string& s, const std::string& ref); std::string trim_right(const std::string& s, const std::string& ref);
std::vector<std::string> parse_lines(const std::string& s); std::vector<std::string> parse_lines(const std::string& s);
std::string replace_first(std::string& s, const std::string& from, const std::string& to); std::string replace_first(const std::string& s, const std::string& from, const std::string& to);
std::string replace_all(std::string& s, const std::string& from, const std::string& to); std::string replace_all(const std::string& s, const std::string& from, const std::string& to);
int extract_zip(const char *archive, const char *dest, int verbose = 0); int extract_zip(const char *archive, const char *dest, int verbose = 0);
std::string prompt_user(const char *message); std::string prompt_user(const char *message);
bool prompt_user_yn(const char *message); bool prompt_user_yn(const char *message);

View file

@ -13,6 +13,10 @@
namespace gdpm::cache{ namespace gdpm::cache{
std::string _escape_sql(const std::string& s){
return utils::replace_all(s, "'", "''");
}
error create_package_database( error create_package_database(
bool overwrite, bool overwrite,
const params& params const params& params
@ -31,13 +35,12 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, error error(constants::error::SQLITE_ERR,
std::format( std::format(
"create_package_database.sqlite3_open(): {}", "create_package_database.sqlite3_open(): {}",
sqlite3_errmsg(db) sqlite3_errmsg(db)
) )
); );
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
} }
@ -67,11 +70,10 @@ namespace gdpm::cache{
rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg); rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
// log::error("Failed to fetch data: {}\n", sqlite3_errmsg(db)); // log::error("Failed to fetch data: {}\n", sqlite3_errmsg(db));
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"create_package_database.sqlite3_exec(): {}", "create_package_database.sqlite3_exec(): {}",
errmsg errmsg
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
@ -99,11 +101,10 @@ namespace gdpm::cache{
// log::println("{}", sql); // log::println("{}", sql);
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"insert_package_info.sqlite3_open(): {}", "insert_package_info.sqlite3_open(): {}",
sqlite3_errmsg(db) sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
} }
@ -162,10 +163,9 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"get_package_info_by_id.sqlite3_open(): {}", sqlite3_errmsg(db) "get_package_info_by_id.sqlite3_open(): {}", sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return result_t(package::info_list(), error); return result_t(package::info_list(), error);
} }
@ -176,10 +176,9 @@ namespace gdpm::cache{
sql += "COMMIT;\n"; sql += "COMMIT;\n";
rc = sqlite3_exec(db, sql.c_str(), callback, (void*)&p_vector, &errmsg); rc = sqlite3_exec(db, sql.c_str(), callback, (void*)&p_vector, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"get_package_info_by_id.sqlite3_exec(): {}", errmsg "get_package_info_by_id.sqlite3_exec(): {}", errmsg
)); ));
log::error("get_package_info_by_id.sqlite3_exec(): {}", errmsg);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return result_t(package::info_list(), error); return result_t(package::info_list(), error);
@ -232,10 +231,9 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"get_package_info_by_title.sqlite3_open(): {}", sqlite3_errmsg(db) "get_package_info_by_title.sqlite3_open(): {}", sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return result_t(package::info_list(), error); return result_t(package::info_list(), error);
} }
@ -248,10 +246,9 @@ namespace gdpm::cache{
// log::println(sql); // log::println(sql);
rc = sqlite3_exec(db, sql.c_str(), callback, (void*)&p_vector, &errmsg); rc = sqlite3_exec(db, sql.c_str(), callback, (void*)&p_vector, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"get_package_info_by_title.sqlite3_exec(): {}", errmsg "get_package_info_by_title.sqlite3_exec(): {}", errmsg
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return result_t(package::info_list(), error); return result_t(package::info_list(), error);
@ -295,10 +292,9 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"get_installed_packages.sqlite3_open(): {}", sqlite3_errmsg(db) "get_installed_packages.sqlite3_open(): {}", sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return result_t(package::info_list(), error); return result_t(package::info_list(), error);
} }
@ -339,34 +335,33 @@ namespace gdpm::cache{
string sql; string sql;
for(const auto& p : packages){ for(const auto& p : packages){
sql += "UPDATE " + params.table_name + " SET " sql += "UPDATE " + params.table_name + " SET "
" asset_id=" + std::to_string(p.asset_id) + ", " " asset_id=" + std::to_string(p.asset_id) + ", "
" type='" + p.type + "', " " type='" + _escape_sql(p.type) + "', "
" title='" + p.title + "', " " title='" + _escape_sql(p.title) + "', "
" author='" + p.author + "', " + " author='" + _escape_sql(p.author) + "', " +
" author_id=" + std::to_string(p.author_id) + ", " " author_id=" + std::to_string(p.author_id) + ", "
" version='" + p.version + "', " + " version='" + _escape_sql(p.version) + "', " +
" godot_version='" + p.godot_version + "', " + " godot_version='" + _escape_sql(p.godot_version) + "', " +
" cost='" + p.cost + "', " + " cost='" + _escape_sql(p.cost) + "', " +
" description='" + p.description + "', " + " description='" + _escape_sql(p.description) + "', " +
" modify_date='" + p.modify_date + "', " + " modify_date='" + _escape_sql(p.modify_date) + "', " +
" support_level='" + p.support_level + "', " + " support_level='" + _escape_sql(p.support_level) + "', " +
" category='" + p.category + "', " + " category='" + _escape_sql(p.category) + "', " +
" remote_source='" + p.remote_source + "', " + " remote_source='" + _escape_sql(p.remote_source) + "', " +
" download_url='" + p.download_url + "', " + " download_url='" + _escape_sql(p.download_url) + "', " +
" download_hash='" + p.download_hash + "', " + " download_hash='" + _escape_sql(p.download_hash) + "', " +
" is_installed=" + std::to_string(p.is_installed) + ", " " is_installed=" + std::to_string(p.is_installed) + ", "
" install_path='" + p.install_path + "'" " install_path='" + _escape_sql(p.install_path) + "'"
// " dependencies='" + p.dependencies + "'" // " dependencies='" + p.dependencies + "'"
" WHERE title='" + p.title + "' AND asset_id=" + std::to_string(p.asset_id) " WHERE title='" + p.title + "' AND asset_id=" + std::to_string(p.asset_id)
+ ";\n"; + ";\n";
} }
rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg); rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"update_package_info.sqlite3_exec(): {}", errmsg "update_package_info.sqlite3_exec(): {}\n\t{}", errmsg, sql
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
@ -387,10 +382,9 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"delete_packages.sqlite3_open(): {}", sqlite3_errmsg(db) "delete_packages.sqlite3_open(): {}", sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
} }
@ -401,10 +395,9 @@ namespace gdpm::cache{
} }
rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg); rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"delete_packages.sqlite3_exec(): {}", errmsg "delete_packages.sqlite3_exec(): {}", errmsg
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
@ -425,10 +418,9 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"delete_packages.sqlite3_open(): {}", errmsg "delete_packages.sqlite3_open(): {}", errmsg
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
} }
@ -439,10 +431,9 @@ namespace gdpm::cache{
} }
rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg); rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"delete_packages.sqlite3_exec(): {}", errmsg "delete_packages.sqlite3_exec(): {}", errmsg
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
@ -460,20 +451,18 @@ namespace gdpm::cache{
int rc = sqlite3_open(params.cache_path.c_str(), &db); int rc = sqlite3_open(params.cache_path.c_str(), &db);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"drop_package_database.sqlite3_open(): {}", sqlite3_errmsg(db) "drop_package_database.sqlite3_open(): {}", sqlite3_errmsg(db)
)); ));
log::error(error);
sqlite3_close(db); sqlite3_close(db);
return error; return error;
} }
rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg); rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errmsg);
if(rc != SQLITE_OK){ if(rc != SQLITE_OK){
error error(rc, std::format( error error(constants::error::SQLITE_ERR, std::format(
"drop_package_database.sqlite3_exec(): {}", errmsg "drop_package_database.sqlite3_exec(): {}", errmsg
)); ));
log::error(error);
sqlite3_free(errmsg); sqlite3_free(errmsg);
sqlite3_close(db); sqlite3_close(db);
return error; return error;

View file

@ -1,5 +1,6 @@
#include "package.hpp" #include "package.hpp"
#include "colors.hpp"
#include "error.hpp" #include "error.hpp"
#include "log.hpp" #include "log.hpp"
#include "rest_api.hpp" #include "rest_api.hpp"
@ -11,6 +12,7 @@
#include "utils.hpp" #include "utils.hpp"
#include <functional> #include <functional>
#include <future> #include <future>
#include <rapidjson/error/en.h>
#include <rapidjson/ostreamwrapper.h> #include <rapidjson/ostreamwrapper.h>
#include <rapidjson/prettywriter.h> #include <rapidjson/prettywriter.h>
@ -89,7 +91,7 @@ namespace gdpm::package{
log::println(""); log::println("");
if(!config.skip_prompt){ if(!config.skip_prompt){
if(!utils::prompt_user_yn("Do you want to install these packages? (y/n)")) if(!utils::prompt_user_yn("Do you want to install these packages? (Y/n)"))
return error(); return error();
} }
@ -118,13 +120,14 @@ namespace gdpm::package{
/* Retrieve necessary asset data if it was found already in cache */ /* Retrieve necessary asset data if it was found already in cache */
Document doc; Document doc;
bool is_valid = p.download_url.empty() || p.category.empty() || p.description.empty() || p.support_level.empty(); bool is_missing_data = p.download_url.empty() || p.category.empty() || p.description.empty() || p.support_level.empty();
if(is_valid){ if(is_missing_data){
doc = rest_api::get_asset(url, p.asset_id, rest_api_params); doc = rest_api::get_asset(url, p.asset_id, rest_api_params);
if(doc.HasParseError() || doc.IsNull()){ if(doc.HasParseError() || doc.IsNull()){
constexpr const char *message = "\nError parsing HTTP response."; const std::string message = std::format("Error parsing JSON: {}", GetParseError_En(doc.GetParseError()));
log::error(message); log::error(message);
return error(doc.GetParseError(), message);
return error(constants::error::JSON_ERR, std::format("{}: {}", message, GetParseError_En(doc.GetParseError())));
} }
p.category = doc["category"].GetString(); p.category = doc["category"].GetString();
p.description = doc["description"].GetString(); p.description = doc["description"].GetString();
@ -133,7 +136,7 @@ namespace gdpm::package{
p.download_hash = doc["download_hash"].GetString(); p.download_hash = doc["download_hash"].GetString();
} }
else{ else{
log::error("Not a valid package."); log::info("Found asset data found for \"{}\"", p.title);
} }
/* Set directory and temp paths for storage */ /* Set directory and temp paths for storage */
@ -162,10 +165,8 @@ namespace gdpm::package{
} }
else{ else{
/* Download all the package files and place them in tmp directory. */ /* Download all the package files and place them in tmp directory. */
log::info_n("Downloading \"{}\"...", p.title); log::info("Downloading \"{}\"...", p.title);
std::string download_url = p.download_url;// doc["download_url"].GetString(); http::response response = http::download_file(p.download_url, tmp_zip);
std::string title = p.title;// doc["title"].GetString();
http::response response = http::download_file(download_url, tmp_zip);
if(response.code == http::OK){ if(response.code == http::OK){
log::println("Done."); log::println("Done.");
}else{ }else{
@ -190,12 +191,13 @@ namespace gdpm::package{
/* Update the cache data with information from */ /* Update the cache data with information from */
log::info_n("Updating local asset data..."); log::info_n("Updating local asset data...");
error error = cache::update_package_info(p_found); error error = cache::update_package_info(p_found);
if(error()){ if(error.has_occurred()){
log::error(error); string prefix = std::format(log::get_error_prefix(), utils::timestamp());
log::println(GDPM_COLOR_LOG_ERROR"\n{}{}" GDPM_COLOR_RESET, prefix, error.get_message());
return error; return error;
} }
log::println("done."); log::println("Done.");
// }) // })
// ); // );
} }
@ -301,11 +303,11 @@ namespace gdpm::package{
{ {
error error = cache::update_package_info(p_cache); error error = cache::update_package_info(p_cache);
if(error.has_occurred()){ if(error.has_occurred()){
log::error(error); log::error("\n{}", error.get_message());
return error; return error;
} }
} }
log::println("done."); log::println("Done.");
return error(); return error();
} }

View file

@ -106,8 +106,9 @@ namespace gdpm::package_manager{
auto packageDirOpt = option("--package-dir").set(config.packages_dir) % "set the global package location"; auto packageDirOpt = option("--package-dir").set(config.packages_dir) % "set the global package location";
auto tmpDirOpt = option("--tmp-dir").set(config.tmp_dir) % "set the temporary download location"; auto tmpDirOpt = option("--tmp-dir").set(config.tmp_dir) % "set the temporary download location";
auto timeoutOpt = option("--timeout").set(config.timeout) % "set the request timeout"; auto timeoutOpt = option("--timeout").set(config.timeout) % "set the request timeout";
auto verboseOpt = repeatable(option("-v", "--verbose", "-v").call([]{ config.verbose += 1; })) % "show verbose output"; auto verboseOpt = joinable(repeatable(option("-v", "--verbose").call([]{ config.verbose += 1; }))) % "show verbose output";
auto versionOpt = option("--version").set(action, action_e::version);
/* Set the options */ /* Set the options */
auto cleanOpt = option("--clean").set(config.clean_temporary) % "enable/disable cleaning temps"; auto cleanOpt = option("--clean").set(config.clean_temporary) % "enable/disable cleaning temps";
auto parallelOpt = option("--jobs").set(config.jobs) % "set number of parallel jobs"; auto parallelOpt = option("--jobs").set(config.jobs) % "set number of parallel jobs";
@ -207,7 +208,7 @@ namespace gdpm::package_manager{
); );
auto cli = ( auto cli = (
debugOpt, configOpt, debugOpt, configOpt, verboseOpt, versionOpt,
(installCmd | addCmd | removeCmd | updateCmd | searchCmd | exportCmd | (installCmd | addCmd | removeCmd | updateCmd | searchCmd | exportCmd |
listCmd | linkCmd | cloneCmd | cleanCmd | configCmd | fetchCmd | listCmd | linkCmd | cloneCmd | cleanCmd | configCmd | fetchCmd |
remoteCmd | uiCmd | helpCmd) remoteCmd | uiCmd | helpCmd)
@ -249,6 +250,7 @@ namespace gdpm::package_manager{
case action_e::remote_remove: remote::remove_respositories(config, params.args); break; case action_e::remote_remove: remote::remove_respositories(config, params.args); break;
case action_e::ui: log::println("UI not implemented yet"); break; case action_e::ui: log::println("UI not implemented yet"); break;
case action_e::help: log::println("{}", man_page_format); break; case action_e::help: log::println("{}", man_page_format); break;
case action_e::version: break;
case action_e::none: /* ...here to run with no command */ break; case action_e::none: /* ...here to run with no command */ break;
} }
} else { } else {

View file

@ -18,8 +18,9 @@
namespace gdpm::rest_api{ namespace gdpm::rest_api{
request_params make_from_config(const config::context& config){ request_params make_from_config(const config::context& config){
request_params params = make_request_params(); bool is_latest = (config.info.godot_version.empty() || config.info.godot_version == "latest");
params.godot_version = config.info.godot_version; request_params params = make_request_params();
params.godot_version = (is_latest) ? "" : config.info.godot_version;
params.verbose = config.verbose; params.verbose = config.verbose;
return params; return params;
} }
@ -37,7 +38,7 @@ namespace gdpm::rest_api{
bool reverse, bool reverse,
int verbose int verbose
){ ){
request_params params{ return request_params{
.type = type, .type = type,
.category = category, .category = category,
.support = support, .support = support,
@ -50,7 +51,6 @@ namespace gdpm::rest_api{
.reverse = reverse, .reverse = reverse,
.verbose = verbose .verbose = verbose
}; };
return params;
} }
bool register_account( bool register_account(
@ -211,7 +211,7 @@ namespace gdpm::rest_api{
string request_url = _prepare_request(url, c); string request_url = _prepare_request(url, c);
http::response r = http::request_get(request_url); http::response r = http::request_get(request_url);
if(c.verbose > 0) if(c.verbose > 0)
log::info("URL: {}", request_url); log::info("get_asset().URL: {}", request_url);
return _parse_json(r.body, c.verbose); return _parse_json(r.body, c.verbose);
} }
@ -220,11 +220,10 @@ namespace gdpm::rest_api{
int asset_id, int asset_id,
const request_params& params const request_params& params
){ ){
string request_url = _prepare_request(url, params); string request_url = utils::replace_all(_prepare_request(url, params), "{id}", std::to_string(asset_id));
utils::replace_all(request_url, "{id}", std::to_string(asset_id));
http::response r = http::request_get(request_url.c_str()); http::response r = http::request_get(request_url.c_str());
if(params.verbose > 0) if(params.verbose >= log::INFO)
log::info("URL: {}", request_url); log::info("get_asset().URL: {}", request_url);
return _parse_json(r.body); return _parse_json(r.body);
} }

View file

@ -102,27 +102,29 @@ namespace gdpm::utils{
} }
std::string replace_first( std::string replace_first(
std::string &s, const std::string &s,
const std::string &from, const std::string &from,
const std::string &to const std::string &to
){ ){
size_t pos = s.find(from); std::string copy = s; // make string copy
size_t pos = copy.find(from);
if(pos == std::string::npos) if(pos == std::string::npos)
return s; return copy;
return s.replace(pos, from.length(), to); return copy.replace(pos, from.length(), to);
} }
std::string replace_all( std::string replace_all(
std::string& s, const std::string& s,
const std::string& from, const std::string& from,
const std::string& to const std::string& to
){ ){
std::string copy = s; // make string copy
size_t pos = 0; size_t pos = 0;
while((pos = s.find(from, pos)) != std::string::npos){ while((pos = copy.find(from, pos)) != std::string::npos){
s.replace(pos, s.length(), to); copy.replace(pos, s.length(), to);
pos += to.length(); pos += to.length();
} }
return s; return copy;
} }
/* Ref: https://gist.github.com/mobius/1759816 */ /* Ref: https://gist.github.com/mobius/1759816 */
@ -204,17 +206,18 @@ namespace gdpm::utils{
std::string prompt_user(const char *message){ std::string prompt_user(const char *message){
log::print("{} ", message); log::print("{} ", message);
std::string input; std::string input;
std::cin >> input; // std::cin >> input;
getline(std::cin, input);
return input; return input;
} }
bool prompt_user_yn(const char *message){ bool prompt_user_yn(const char *message){
std::string input{"y"}; std::string input{""};
do{ while( !std::cin.fail() && input != "y" && input != "n" ){
input = utils::prompt_user(message); bool is_default = (input == "\0" || input == "\n" || input == "\r\n" || input.empty());
to_lower(input); input = to_lower(utils::prompt_user(message));
input = (input == "\0" || input == "\n" || input.empty()) ? "y" : input; input = is_default ? "y" : input;
}while( !std::cin.fail() && input != "y" && input != "n"); }
return input == "y"; return input == "y";
} }