diff options
| author | Claudius "keldu" Holeksa <mail@keldu.de> | 2025-11-07 15:15:16 +0100 |
|---|---|---|
| committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2025-11-07 15:15:16 +0100 |
| commit | 136966aeac7ac000d5b0aadc689e40a61aa5efd5 (patch) | |
| tree | 4ba20593d500cf1e405db7d1340c0849123f7e0a | |
| parent | f32687ccab6158e9611007e6fc2d66bf4751e111 (diff) | |
| download | apps-science_tools-136966aeac7ac000d5b0aadc689e40a61aa5efd5.tar.gz | |
Adding git features
| -rw-r--r-- | run_and_record/.nix/derivation.nix | 2 | ||||
| -rw-r--r-- | run_and_record/SConstruct | 3 | ||||
| -rw-r--r-- | run_and_record/c++/git.hpp | 88 | ||||
| -rw-r--r-- | run_and_record/c++/main.cpp | 89 | ||||
| -rw-r--r-- | run_and_record/c++/schema.hpp | 58 |
5 files changed, 178 insertions, 62 deletions
diff --git a/run_and_record/.nix/derivation.nix b/run_and_record/.nix/derivation.nix index 089c7cb..ed20cbe 100644 --- a/run_and_record/.nix/derivation.nix +++ b/run_and_record/.nix/derivation.nix @@ -1,6 +1,7 @@ { stdenv , scons , forstio +, libgit2 }: stdenv.mkDerivation { @@ -18,6 +19,7 @@ stdenv.mkDerivation { forstio.codec-json forstio.remote forstio.remote-filesystem + libgit2 ]; src = ./..; diff --git a/run_and_record/SConstruct b/run_and_record/SConstruct index 9dbf18f..8dcd782 100644 --- a/run_and_record/SConstruct +++ b/run_and_record/SConstruct @@ -49,7 +49,8 @@ env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[], CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'], LIBS=[ 'forstio-core', - 'forstio-async' + 'forstio-async', + 'git2' ] ) env.__class__.add_source_files = add_kel_source_files diff --git a/run_and_record/c++/git.hpp b/run_and_record/c++/git.hpp new file mode 100644 index 0000000..c145e01 --- /dev/null +++ b/run_and_record/c++/git.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include <forstio/error.hpp> + +#include <git2.h> + +#include "schema.hpp" + +namespace kel { +saw::error_or<saw::data<sch::RarGit>> is_clean_git_repo(){ + saw::data<sch::RarGit> git_data; + + git_repository *repo = nullptr; + { + int error = git_repository_open_ext(&repo, ".", 0, nullptr); + if (error < 0) { + // const git_error *e = git_error_last(); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Not a git repository"); + } + } + + { + git_status_options status_opts = GIT_STATUS_OPTIONS_INIT; + status_opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; + status_opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX; + + git_status_list* status_list = nullptr; + int error = git_status_list_new(&status_list, repo, &status_opts); + if (error < 0) { + git_repository_free(repo); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Failed to get git status"); + } + + size_t count = git_status_list_entrycount(status_list); + if(count > 0){ + git_status_list_free(status_list); + git_repository_free(repo); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Git repo is not clean"); + } + git_status_list_free(status_list); + } + + git_oid oid; + { + if(git_reference_name_to_id(&oid, repo, "HEAD") < 0){ + git_repository_free(repo); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Failed to read HEAD"); + } + } + + std::array<char, (GIT_OID_HEXSZ) + 1u> hash_chars; + hash_chars[GIT_OID_HEXSZ] = 0; + git_oid_tostr(&hash_chars[0], hash_chars.size(), &oid); + hash_chars[GIT_OID_HEXSZ] = 0; + + auto& commit = git_data.template get<"commit">(); + commit.set(std::string{hash_chars.data()}); + + git_remote* remote = nullptr; + auto& origin = git_data.template get<"origin">(); + { + int error = git_remote_lookup(&remote, repo, "origin"); + if (error < 0) { + git_repository_free(repo); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Failed to find origin remote"); + } + const char* url = git_remote_url(remote); + if(not url) { + git_remote_free(remote); + git_repository_free(repo); + git_libgit2_shutdown(); + return saw::make_error<saw::err::critical>("Failed to get origin remote url"); + } + + origin.set(std::string{url}); + } + + git_remote_free(remote); + git_repository_free(repo); + git_libgit2_shutdown(); + return git_data; +} +} diff --git a/run_and_record/c++/main.cpp b/run_and_record/c++/main.cpp index 8440d67..d28629f 100644 --- a/run_and_record/c++/main.cpp +++ b/run_and_record/c++/main.cpp @@ -10,56 +10,12 @@ #include <random> #include <string_view> +#include "git.hpp" +#include "schema.hpp" + +extern char** environ; + namespace kel { -namespace sch { -using namespace saw::schema; - -using RarConfig = Struct< ->; - -// Additionally record the files which are needed to run the simulation -using RarArgsTuple = Tuple< - Array<String> ->; - -using RarArgs = Args< - RarConfig, - RarArgsTuple ->; - -using RarFileData = Struct< - Member< - Member< - Array< - Struct< - Member<String, "program">, - Member<Array<String>, "arguments"> - > - >, - >, "commands">, - Member< - Array< - Struct< - Member<String, "key">, - Member<String, "value"> - > - >, "env">, - Member< - Struct< - Member<String, "commit">, - Member<String, "origin"> - >, - "git">, - Member< - Array< - Struct< - Member<Array<String>, "command">, - Member<String, "stdout">, - Member<String, "stderr"> - > - >, "meta"> ->; -} /** * Check if HOME env variable is set and where it points to. @@ -135,7 +91,7 @@ saw::error_or<std::string> generate_data_dir_name(const std::string_view& bin_na thread_local std::mt19937 generator{std::random_device{}()}; std::uniform_int_distribution<size_t> distribution(0, chars.size() - 1); - for (size_t i = 0; i < length; ++i){ + for (size_t i = 0; i < 8; ++i){ oss << chars[distribution(generator)]; } } @@ -143,25 +99,21 @@ saw::error_or<std::string> generate_data_dir_name(const std::string_view& bin_na return oss.str(); } -extern char** environ; - /** * Record the environment */ -saw::error_or<void> record_environment(saw::data<sch::RarFileData>& df){ +saw::error_or<void> record_environment(saw::data<sch::RarEnv>& df_env){ saw::data<sch::UInt64> env_size{0u}; for(char** env = environ; *env != nullptr; ++env){ ++env_size; } - auto& df_env = df.template get<"env">(); - - df_env = {env_size}; + df_env = {saw::data<sch::FixedArray<sch::UInt64,1u>>{{env_size}}}; saw::data<sch::UInt64> i{0u}; for(char** env = environ; *env != nullptr; ++env){ - df_env.at(i).set(std::to_string(env)); + df_env.at(i).set(std::string(*env)); ++i; } @@ -202,9 +154,9 @@ saw::error_or<void> kel_main(int argc, char** argv){ saw::data<sch::RarArgs> args; auto eo_home = get_home_env(); if(eo_home.is_error()){ - return std::move(eov.get_error()); + return std::move(eo_home.get_error()); } - auto& home = eov.get_value(); + auto& home = eo_home.get_value(); auto data_dir = home / ".local" / "kel" / "run_and_record"; // @@ -221,7 +173,7 @@ saw::error_or<void> kel_main(int argc, char** argv){ // Read the user config file for recording { auto conf_file = home / ".config" / "kel" / "run_and_record.json"; - auto eo_file = simple_read_file<sch::RarConfig,saw::encode::Json>(conf_file); + auto eo_file = saw::easy::read_and_decode_file<sch::RarConfig,saw::encode::Json>(conf_file); if(eo_file.is_error()){ return std::move(eo_file.get_error()); @@ -247,6 +199,16 @@ saw::error_or<void> kel_main(int argc, char** argv){ return eov; } } + + { + auto eo_git = is_clean_git_repo(); + if(eo_git.is_error()){ + return std::move(eo_git.get_error()); + } + auto& v_git = eo_git.get_value(); + data_for_file.template get<"git">() = v_git; + } + // sep_pos+1 til end int argc_prog = argc - (sep_pos+1); { @@ -255,8 +217,13 @@ saw::error_or<void> kel_main(int argc, char** argv){ return eov; } } + + if(not std::filesystem::create_directory(data_full_dir)){ + return saw::make_error<saw::err::critical>("Couldn't create directory for file"); + } + { - auto eov = easy::write_file<sch::RarFileData, saw::encode::Json>(data_full_dir, data_for_file); + auto eov = saw::easy::encode_and_write_file<sch::RarFileData, saw::encode::Json>(data_full_dir / "data.json", data_for_file); if(eov.is_error()){ return eov; } diff --git a/run_and_record/c++/schema.hpp b/run_and_record/c++/schema.hpp new file mode 100644 index 0000000..140e81b --- /dev/null +++ b/run_and_record/c++/schema.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include <forstio/codec/schema.hpp> + +namespace kel { +namespace sch { +using namespace saw::schema; + +using RarConfig = Struct< +>; + +// Additionally record the files which are needed to run the simulation +using RarArgsTuple = Tuple< +>; + +using RarGit = Struct< + Member<String, "commit">, + Member<String, "origin"> +>; + +using RarArgs = Args< + RarConfig, + RarArgsTuple +>; + +using RarEnv = Array<String>; + +using RarFileData = Struct< + Member< + Array< + Struct< + Member<String, "program">, + Member<Array<String>, "arguments"> + > + >, + "commands" + >, + Member< + RarEnv, + "env" + >, + Member< + RarGit, + "git" + >, + Member< + Array< + Struct< + Member<Array<String>, "command">, + Member<String, "stdout">, + Member<String, "stderr"> + > + >, + "meta" + > +>; +} +} |
