Added a --test or -T test argument to validate the json file.

This commit is contained in:
unrealdragon 2026-10-10 15:33:55 +05:30
commit 111c2487d8

View file

@ -16,6 +16,7 @@ extern "C" {
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
#include <cstdlib>
} }
char *get_current_time() { char *get_current_time() {
@ -29,6 +30,19 @@ struct Options {
std::string log_directory = ""; std::string log_directory = "";
long long int log_file_max_size = 10 * 1024 * 1024; long long int log_file_max_size = 10 * 1024 * 1024;
int threads = 16; int threads = 16;
bool check_for_errors = false;
public:
Options() {
const char *home = std::getenv("HOME");
if(!home || strlen(home) <= 0)
{
log_directory = "StartUpApps/logs";
return;
}
using fp = std::filesystem::path;
fp fs = fp(home) / ".local" / "share" / "StartUpApps" / "logs";
log_directory = fs.string();
}
}options; }options;
void createConfig() { void createConfig() {
@ -83,6 +97,7 @@ void printHelp() {
std::cout << "\t--log_dir|-ld [Dir] : Sets log directory to [Dir]." << std::endl; std::cout << "\t--log_dir|-ld [Dir] : Sets log directory to [Dir]." << std::endl;
std::cout << "\t--defaults|-d : Prints the default values used if no arguments are provided." << std::endl; std::cout << "\t--defaults|-d : Prints the default values used if no arguments are provided." << std::endl;
std::cout << "\t--json|-j [FileName]: Set Json Startup List to FileName." << std::endl; std::cout << "\t--json|-j [FileName]: Set Json Startup List to FileName." << std::endl;
std::cout << "\t--test|-T [FileName]: Check the json file for errors." << std::endl;
std::cout << "For a detailed info about the json startup file use --help json." << std::endl; std::cout << "For a detailed info about the json startup file use --help json." << std::endl;
} }
@ -180,8 +195,9 @@ void parseArgs(int c, char *v[]) {
printDefaults(); printDefaults();
exit(0); exit(0);
} }
} }
if(c >= 3) { if(c >= 2) {
std::vector<std::string> arg_list; std::vector<std::string> arg_list;
for(int i=1; i<c; i++) { for(int i=1; i<c; i++) {
arg_list.push_back(v[i]); arg_list.push_back(v[i]);
@ -220,6 +236,17 @@ void parseArgs(int c, char *v[]) {
std::cout << "Threads: " << options.threads << std::endl; std::cout << "Threads: " << options.threads << std::endl;
contains_any_known_arg = true; contains_any_known_arg = true;
} }
i = contains(arg_list, "--test", "-T");
if(i >= 0) {
int j = i + 1;
if(j > arg_list.size()) {
printHelp();
exit(-1);
}
options.check_for_errors = true;
std::cout << "Testing json file." << std::endl;
contains_any_known_arg = true;
}
i = contains(arg_list, "--help", "-h"); i = contains(arg_list, "--help", "-h");
if(i >= 0) { if(i >= 0) {
int j = i + 1; int j = i + 1;
@ -412,7 +439,7 @@ int main(int argc, char *argv[]) {
parseConfig(); parseConfig();
parseArgs(argc, argv); parseArgs(argc, argv);
if(!std::filesystem::exists(options.log_directory)) { if(!std::filesystem::exists(options.log_directory)) {
std::filesystem::create_directory(options.log_directory); std::filesystem::create_directories(options.log_directory);
} }
std::filesystem::path json_path = options.json_file_path; std::filesystem::path json_path = options.json_file_path;
std::string log_file_path = std::filesystem::path(options.log_directory) / "StartUpRunner.log"; std::string log_file_path = std::filesystem::path(options.log_directory) / "StartUpRunner.log";
@ -443,6 +470,7 @@ int main(int argc, char *argv[]) {
json_file.open(json_file_path, std::fstream::in); json_file.open(json_file_path, std::fstream::in);
if(!json_file.is_open()) { if(!json_file.is_open()) {
log_file << "Why is the startup_apps.json file not open?" << std::endl; log_file << "Why is the startup_apps.json file not open?" << std::endl;
std::cerr << "startup_apps.json file is not readable from location: " << json_file_path << "." << std::endl;
return -1; return -1;
} }
std::stringstream test; std::stringstream test;
@ -452,6 +480,7 @@ int main(int argc, char *argv[]) {
bool valid = json::accept(test.str()); bool valid = json::accept(test.str());
if(!valid) { if(!valid) {
log_file << "Json Document Parsing error...." << std::endl; log_file << "Json Document Parsing error...." << std::endl;
std::cerr << "Invalid JSON format in: " << json_file_path << "." << std::endl;
return -1; return -1;
} }
json file = json::parse(test.str()); json file = json::parse(test.str());
@ -462,19 +491,21 @@ int main(int argc, char *argv[]) {
if(object.find("app_name") == object.end()) { if(object.find("app_name") == object.end()) {
log_file << "Error in json." << std::endl; log_file << "Error in json." << std::endl;
log_file << "Field app name is a required field." << std::endl; log_file << "Field app name is a required field." << std::endl;
std::cerr << "Field error in: " << json_file_path << ", check log for more details." << std::endl;
exit(-2); exit(-2);
} }
if(object.find("name") == object.end()) { if(object.find("name") == object.end()) {
log_file << "Error in json." << std::endl; log_file << "Error in json." << std::endl;
log_file << "Field name is a required field." << std::endl; log_file << "Field name is a required field." << std::endl;
std::cerr << "Field error in: " << json_file_path << ", check log for more details." << std::endl;
exit(-2); exit(-2);
} }
if(object.find("run_mode") == object.end()) { if(object.find("run_mode") == object.end()) {
log_file << "Error in json." << std::endl; log_file << "Error in json." << std::endl;
log_file << "Field run_mode is a required field." << std::endl; log_file << "Field run_mode is a required field." << std::endl;
std::cerr << "Field error in: " << json_file_path << ", check log for more details." << std::endl;
exit(-2); exit(-2);
} }
app_info.program_name = object["app_name"].get<std::string>(); app_info.program_name = object["app_name"].get<std::string>();
std::string args = ""; std::string args = "";
std::deque<const char*> c_args; std::deque<const char*> c_args;
@ -519,14 +550,21 @@ int main(int argc, char *argv[]) {
} }
std::vector<std::shared_ptr<AppInfo>> list; std::vector<std::shared_ptr<AppInfo>> list;
log_file << "Checking App List for errors." << std::endl; log_file << "Checking App List for errors." << std::endl;
auto list_check = checkAppList(initial_app_list, list, log_file.rdbuf()); std::optional<int> list_check;
if(options.check_for_errors)
list_check = checkAppList(initial_app_list, list, std::cerr);
else
list_check = checkAppList(initial_app_list, list, log_file.rdbuf());
if(list_check.has_value()) { if(list_check.has_value()) {
log_file << "No errors found in app list." << std::endl; log_file << "No errors found in app list." << std::endl;
} }
else { else {
std::cerr << "Dependency error in: " << json_file_path << "check log for more details." << std::endl;
log_file << "Errors present in app list; Please fix them" << std::endl; log_file << "Errors present in app list; Please fix them" << std::endl;
return -1; return -1;
} }
if(options.check_for_errors)
return 0;
for(int i=0;i<list.size();i++) { for(int i=0;i<list.size();i++) {
list[i]->printInfo(log_file.rdbuf()); list[i]->printInfo(log_file.rdbuf());
} }