From 7eeaa4dd5d75356ca5987d98005f6f40af922f3e Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 23 Dec 2022 23:07:58 +0100 Subject: [PATCH] Added subcommand `devel' `ceev devel commitinfo' shows the latest commit along with the commit hash. More to be added. --- CMakeLists.txt | 22 ++++++++- src/ceev.cc | 123 ++++++++++++++++++++++++++++++++++++++++++++----- src/ceev.h | 22 +++++++++ 3 files changed, 154 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ead07d3..a29a78c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,28 @@ cmake_minimum_required(VERSION 3.7) project(ceev) +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND git log -1 --pretty=%B + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_MSG + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_CXX_STANDARD 17) find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIRS}) add_executable(ceev src/ceev.cc src/ceev.h src/colors.cc src/colors.h) -target_link_libraries(ceev ${SDL2_LIBRARIES}) \ No newline at end of file +target_link_libraries(ceev ${SDL2_LIBRARIES}) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"") + +string(REPLACE "\n" "\\n" GIT_COMMIT_MSG "${GIT_COMMIT_MSG}") + +target_compile_definitions(${PROJECT_NAME} PRIVATE + "-DGIT_COMMIT_MSG=\"${GIT_COMMIT_MSG}\"") \ No newline at end of file diff --git a/src/ceev.cc b/src/ceev.cc index a9397b0..fe35fe7 100644 --- a/src/ceev.cc +++ b/src/ceev.cc @@ -35,29 +35,58 @@ int show_help() { std::cout << GET_PROGRAM_NAME() << cyan(" clean") << "\n"; std::cout << "\t\t"; std::cout << "Not yet implemented"; + // ceev devel + std::cout << "\n*\t"; + std::cout << GET_PROGRAM_NAME() << cyan(" devel ") << "<" << bright_green("--help") << ">\n"; + std::cout << "\t\t"; + std::cout << "Supplementary command for development information"; // ceev --help std::cout << "\n*\t"; - std::cout << GET_PROGRAM_NAME() << cyan(" --help") << "\n"; + std::cout << GET_PROGRAM_NAME() << cyan(" --help") << "/" << cyan("-h") << "\n"; std::cout << "\t\t"; - std::cout << "This help page.\n"; + std::cout << "This help page."; + // ceev --version + std::cout << "\n*\t"; + std::cout << GET_PROGRAM_NAME() << cyan(" --version") << "/" << cyan("-v") << "\n"; + std::cout << "\t\t"; + std::cout << "Get the current version."; std::cout << std::endl; return 0; } +int show_version() { + std::cout << "CeeV version " << __ceev_version << '\n'; + return 0; +} + +bool replace(std::string& str, const std::string& from, const std::string& to) { + size_t start_pos = str.find(from); + if(start_pos == std::string::npos) + return false; + str.replace(start_pos, from.length(), to); + return true; +} + +static std::string query_author() { + std::string author; + std::cout << "Author: "; + std::getline(std::cin, author); + return author; +} + int create_fs(std::deque args) { fs::path cwd = fs::current_path(); - if (!fs::is_empty(cwd) && args[0] != "--force") { - std::cerr << "ERROR: Folder not empty.\n" << + if (!fs::is_empty(cwd) && ((!args.empty() && args[0] != "--force") || args.empty())) { + std::cerr << bg_red(bold("ERROR")) << ": Folder not empty.\n" << "Run the command with `--force' to run anyways" << std::endl; return 1; } - std::cout << "running create_fs()" << std::endl; fs::create_directory(cwd.string() + "/.ceev", cwd); fs::create_directory(cwd.string() + "/src", cwd); - std::ofstream config(cwd.string() + "/.ceev/config"); + std::ofstream config(cwd.string() + "/.ceev/" + CONFIG_FILENAME); std::string directory = cwd.string().substr(cwd.parent_path().string().length() + 1); std::cout << "Initializing project...\n"; - std::cout << "You can change this information later by editing .ceev/config\n"; + std::cout << "You can change this information later by editing .ceev/" << CONFIG_FILENAME << "\n"; std::string project_name; std::cout << "Project name [" << directory << "]: "; std::getline(std::cin, project_name); @@ -68,11 +97,19 @@ int create_fs(std::deque args) { std::getline(std::cin, version); if (version == "") version = "0.0.1"; config << "version=" << version << '\n'; - std::string author; - std::cout << "Author: "; - std::getline(std::cin, author); - if (author == "") author = "Unknown"; + std::string author = query_author(); + if (author == "") { + std::cerr << bg_red(bold("ERROR")) << ": Author cannot be empty.\n"; + author = query_author(); + } config << "author=" << author << '\n'; + std::string email; + while (author.find(' ') != std::string::npos) + replace(author, " ", "."); + std::cout << "Email [" << author << "@example.org]: "; + std::getline(std::cin, email); + if (email == "") email = author + "@example.org"; + config << "email=" << email << '\n'; config.close(); return 0; } @@ -88,9 +125,9 @@ int run_project(std::deque args) { return 1; } std::string line; + struct config_data data; while (std::getline(config, line)) { std::istringstream iss(line); - struct config_data data; std::string key; if (!std::getline(iss, key, '=')) continue; std::string value; @@ -98,8 +135,13 @@ int run_project(std::deque args) { if (key == "name") data.name = value; if (key == "version") data.version = value; if (key == "author") data.author = value; + if (key == "email") data.email = value; } config.close(); + std::cout << "Name: " << data.name << '\n'; + std::cout << "Version: " << data.version << '\n'; + std::cout << "Author: " << data.author << '\n'; + std::cout << "Email: " << data.email << '\n'; std::cout << "Running project..." << std::endl; return 0; } @@ -107,6 +149,53 @@ int clean_project(std::deque args) { std::cout << "Cleaning project..." << std::endl; return 0; } +int devel(std::deque args) { + if (args.empty()) { + std::cout << bg_red(bold("ERROR")) << ": No subcommands given." << std::endl; + devel_help(); + return 1; + } + std::string a1 = args[0]; + args.pop_front(); + if (a1 == "commitinfo") return devel_commitinfo(); + std::string kw; + if (a1.substr(0, 2) == "--") { + kw = a1.substr(2); + if (kw == "help") return devel_help(); + } + if (a1.substr(0, 1) == "-") { + kw = a1.substr(1); + if (kw == "h") return devel_help(); + } + std::cerr << bg_red(bold("ERROR")) << ": Unknown command `" << bright_magenta(a1) << "'\n" << std::endl; + devel_help(); + return 1; +} +int devel_help() { + std::cout << "Usage:\n"; + // ceev devel roadmap + std::cout << "\n*\t"; + std::cout << GET_PROGRAM_NAME() << " devel " << cyan("roadmap") << "\n"; + std::cout << "\t\t"; + std::cout << "Get the current roadmap.\n"; + // ceev devel commitinfo + std::cout << "\n*\t"; + std::cout << GET_PROGRAM_NAME() << " devel " << cyan("commitinfo") << "\n"; + std::cout << "\t\t"; + std::cout << "Get info about the latest commit.\n"; + // ceev devel --help + std::cout << "\n*\t"; + std::cout << GET_PROGRAM_NAME() << " devel " << cyan("--help") << "/" << cyan("-h") << "\n"; + std::cout << "\t\t"; + std::cout << "This help page.\n"; + return 0; +} +int devel_commitinfo() { + std::cout << "CeeV build " << bright_cyan(bold(GIT_COMMIT_HASH)) << "\n\n"; + std::cout << "Commit message:\n"; + std::cout << bright_cyan(bold(GIT_COMMIT_MSG)) << std::endl; + return 0; +} int main(int argc, char **argv) { if (argc <= 1) { return usage(); @@ -114,6 +203,7 @@ int main(int argc, char **argv) { std::deque args; for (int i = 1; i < argc; i++) args.push_back(std::string(argv[i])); std::string a1 = std::string(args[0]); + // XXX: Is this really needed? std::transform(a1.begin(), a1.end(), a1.begin(), [](unsigned char c){return std::tolower(c);}); args.pop_front(); if (a1 == "init") { @@ -122,11 +212,20 @@ int main(int argc, char **argv) { if (a1 == "build") return build_project(args); if (a1 == "run") return run_project(args); if (a1 == "clean") return clean_project(args); + if (a1 == "devel") return devel(args); std::string kw; if (a1.substr(0, 2) == "--") { kw = a1.substr(2); + if (kw == "version") return show_version(); if (kw == "help") return show_help(); } + if (a1.substr(0, 1) == "-") { + // TODO: Although not yet needed, add support for multiparams, like `ceev -hv' + // True, that doesn't make sense, that's why it's not yet needed. + kw = a1.substr(1); + if (kw == "v") return show_version(); + if (kw == "h") return show_help(); + } std::cerr << bg_red(bold("ERROR")) << ": Unknown command `" << bright_magenta(a1) << "'\n" << std::endl; return usage(); } \ No newline at end of file diff --git a/src/ceev.h b/src/ceev.h index 4645959..fdf949f 100644 --- a/src/ceev.h +++ b/src/ceev.h @@ -10,6 +10,22 @@ #include "colors.h" +#ifndef __ceev_version +#define __ceev_version "0.1.1-devel" +#endif + +#ifndef CONFIG_FILENAME +#define CONFIG_FILENAME "ceev.cfg" +#endif + +#ifndef GIT_COMMIT_HASH +#define GIT_COMMIT_HASH "Unknown" +#endif + +#ifndef GIT_COMMIT_MSG +#define GIT_COMMIT_MSG "Unknown" +#endif + #undef GET_PROGRAM_NAME #ifdef __GLIBC__ #define GET_PROGRAM_NAME() program_invocation_short_name @@ -24,11 +40,17 @@ struct config_data { std::string name = ""; std::string version = ""; std::string author = ""; + std::string email = ""; }; int usage(); int show_help(); +bool replace(std::string& str, const std::string& from, const std::string& to); +static std::string query_author(); int create_fs(std::deque args); int build_project(std::deque args); int run_project(std::deque args); int clean_project(std::deque args); +int devel(std::deque args); +int devel_help(); +int devel_commitinfo(); int main(int argc, char **argv); \ No newline at end of file