From 9fec1b427c1228af3319debb77f956413f7f347b Mon Sep 17 00:00:00 2001 From: Aaron Fiore Date: Fri, 21 Nov 2025 12:32:32 -0800 Subject: [PATCH] container: root: change base path, related refactor The base path is now *outside* of the macro directory; allowing for a more integrated view of `dfi`'s entire `root` system. This is more apparent once running an interactive session where the expectation is (more intuitively) that any path should be relative to 'src/root' and not 'src/root/macro'. The rationale for why this was in 'src/root/macro' to begin with stems from how `root` (by default) will automatically load rootlogon.C in the directory that `root` is started. This is causing more confusion than not because `dfi`'s usage of `root` is not limited to macros. These changes skirt the line between needing a major API bump and not but, so far, appears to be on the side of *not*. However, the TODOs noted for macro loading should be addressed prior to any API changes. --- .../src/finance/lib/internal/lib_root.bash | 64 ++++++++++++------- container/src/root/macro/rootlogon.C | 10 +-- container/src/root/macro/test/benchmark.C | 6 +- container/src/root/macro/test/unit.C | 8 +-- container/src/root/macro/web/server.C | 10 +-- container/src/root/test/unit/utility.hh | 4 +- 6 files changed, 61 insertions(+), 41 deletions(-) diff --git a/container/src/finance/lib/internal/lib_root.bash b/container/src/finance/lib/internal/lib_root.bash index 7febbd4..efd166c 100644 --- a/container/src/finance/lib/internal/lib_root.bash +++ b/container/src/finance/lib/internal/lib_root.bash @@ -107,17 +107,18 @@ function lib_root::__parse_root() # if [[ "$_arg" =~ ^macro ]]; then - local -r _macro="$_stub" + # TODO: utilize stub when 'repo/' and 'custom/' is implemented (like plugins) + local -r _macro="$_arg" # Repo macros - [ ! -f "${DOCKER_FINANCE_CONTAINER_REPO}/src/root/macro/${_macro}" ] \ + [ ! -f "${DOCKER_FINANCE_CONTAINER_REPO}/src/root/${_macro}" ] \ && lib_utils::die_fatal "repo macro not found '${_macro}'" # TODO: currently, only repo macros are supported # (no custom macros, use custom plugins instead) # Per API (v1), requires path stub format - declare -gr global_arg_macro="$_stub" + declare -gr global_arg_macro="$_macro" fi # @@ -149,10 +150,29 @@ function lib_root::__root() { lib_utils::deps_check "root" - local _exec=("root" "-l") + local -r _path="${DOCKER_FINANCE_CONTAINER_REPO}/src/root" + pushd "$_path" 1>/dev/null || lib_utils::die_fatal "could not pushd '${_path}'" # - # Default + # Base command + # + + # NOTE: + # + # rootlogon.C *MUST* be loaded at any startup; as if fulfills loading + # of `dfi` source files and other library requirements. + # + # Typically, ROOT.cern would load rootlogon.C if we start `root` + # interactively within the macro directory. However, `dfi` has its own + # requirements. + # + # After rootlogon, any loading of macros, plugins or any `dfi` files + # can be completed using the `dfi` API. + + local _exec=("root" "-l" "macro/rootlogon.C") + + # + # Interactive opts # # Start interactive instance w/out loading/running macro or plugin @@ -161,7 +181,7 @@ function lib_root::__root() fi # - # Macro + # Macro: non-interactive opts # if [ ! -z "$global_arg_macro" ]; then @@ -179,11 +199,19 @@ function lib_root::__root() # # - run() static function is the entry point for all macros # - local -r _file="${global_arg_macro##*/}" - local -r _stub="${_file^}" - local -r _class="${_stub%.*}" - local -r _caller="dfi::macro::${global_arg_macro%%/*}::${_class}" + # TODO: modify substring when 'repo/' and 'custom/' is implemented (like plugins) + + local _namespace="${global_arg_macro#*/}" + _namespace="${_namespace%/*}" + declare -r _namespace + + local _class="${global_arg_macro##*/}" + _class="${_class^}" + _class="${_class%.*}" + declare -r _class + + local -r _caller="dfi::macro::${_namespace}::${_class}" # Per-API signatures (v1) if [[ ${_class} == "Hash" ]]; then @@ -195,6 +223,7 @@ function lib_root::__root() else _run="run()" fi + _exec+=("-e" "${_caller}::${_run}") # NOTE: when called via shell, server(s) are implied to @@ -205,7 +234,7 @@ function lib_root::__root() fi # - # Plugin + # Plugin: non-interactive opts # if [ ! -z "$global_arg_plugin" ]; then @@ -216,19 +245,8 @@ function lib_root::__root() # Execute # - # NOTE: - # - # This *MUST* be executed from within the macro directory, - # regardless of what is loaded (macro or plugin), as ROOT.cern - # will automatically load rootlogon.C (which `dfi` needs). - # - # Any loading or macros of plugins from within an interactive - # instance can use be completed with the `dfi` API. - # lib_utils::print_debug "${_exec[@]}" - pushd "${DOCKER_FINANCE_CONTAINER_REPO}/src/root/macro" 1>/dev/null \ - && "${_exec[@]}" \ - || lib_utils::die_fatal "could not pushd" + "${_exec[@]}" || lib_utils::die_fatal "root exited with: $?" } # vim: sw=2 sts=2 si ai et diff --git a/container/src/root/macro/rootlogon.C b/container/src/root/macro/rootlogon.C index 5963eba..c3bee4f 100644 --- a/container/src/root/macro/rootlogon.C +++ b/container/src/root/macro/rootlogon.C @@ -189,11 +189,11 @@ void rootlogon() gSystem->AddLinkedLibs("-lsodium"); // libsodium // Load default `dfi` public consumables - gInterpreter->ProcessLine(".L ../plugin/common/utility.hh"); - gInterpreter->ProcessLine(".L ../macro/common/utility.hh"); - gInterpreter->ProcessLine(".L ../src/hash.hh"); - gInterpreter->ProcessLine(".L ../src/random.hh"); - gInterpreter->ProcessLine(".L ../src/utility.hh"); + gInterpreter->ProcessLine(".L plugin/common/utility.hh"); + gInterpreter->ProcessLine(".L macro/common/utility.hh"); + gInterpreter->ProcessLine(".L src/hash.hh"); + gInterpreter->ProcessLine(".L src/random.hh"); + gInterpreter->ProcessLine(".L src/utility.hh"); } #endif // CONTAINER_SRC_ROOT_MACRO_ROOTLOGON_C_ diff --git a/container/src/root/macro/test/benchmark.C b/container/src/root/macro/test/benchmark.C index 26b1384..4b93c95 100644 --- a/container/src/root/macro/test/benchmark.C +++ b/container/src/root/macro/test/benchmark.C @@ -66,9 +66,9 @@ class Benchmark { static bool loaded{false}; static const std::initializer_list paths{ - {"../test/benchmark/hash.hh"}, - {"../test/benchmark/random.hh"}, - {"../test/benchmark/utility.hh"}}; + {"test/benchmark/hash.hh"}, + {"test/benchmark/random.hh"}, + {"test/benchmark/utility.hh"}}; if (!loaded) { diff --git a/container/src/root/macro/test/unit.C b/container/src/root/macro/test/unit.C index 0670538..0cf69b6 100644 --- a/container/src/root/macro/test/unit.C +++ b/container/src/root/macro/test/unit.C @@ -66,10 +66,10 @@ class Unit { static bool loaded{false}; static const std::initializer_list paths{ - {"../test/unit/hash.hh"}, - {"../test/unit/random.hh"}, - {"../test/unit/type.hh"}, - {"../test/unit/utility.hh"}}; + {"test/unit/hash.hh"}, + {"test/unit/random.hh"}, + {"test/unit/type.hh"}, + {"test/unit/utility.hh"}}; if (!loaded) { diff --git a/container/src/root/macro/web/server.C b/container/src/root/macro/web/server.C index 483aa4f..97bb9b2 100644 --- a/container/src/root/macro/web/server.C +++ b/container/src/root/macro/web/server.C @@ -60,16 +60,16 @@ class Server final //! \details Registers internal macros static void register_commands() { - namespace common = ::dfi::macro::common; + namespace macro = ::dfi::macro; - common::Command::load({"web/internal/crypto.C"}); - common::g_HTTPServer->RegisterCommand( + macro::load("macro/web/internal/crypto.C"); + macro::common::g_HTTPServer->RegisterCommand( "/rng_sample", "::dfi::macro::web::internal::Random::rng_sample(\"%arg1%" "\")"); - common::Command::load({"web/internal/meta.C"}); - common::g_HTTPServer->RegisterCommand( + macro::load("macro/web/internal/meta.C"); + macro::common::g_HTTPServer->RegisterCommand( "/meta_sample", "::dfi::macro::web::internal::Meta::meta_sample(\"%arg1%" "\")"); diff --git a/container/src/root/test/unit/utility.hh b/container/src/root/test/unit/utility.hh index 153cc10..3767a51 100644 --- a/container/src/root/test/unit/utility.hh +++ b/container/src/root/test/unit/utility.hh @@ -373,7 +373,9 @@ TEST_F(CommonRepoFiles, MacroLoad) ASSERT_NE(ecode, nullptr); EXPECT_NE(*ecode, EErrorCode::kNoError); - ASSERT_NO_THROW(::dfi::macro::load("crypto/hash.C")); + // TODO(afiore): macro loading should not need to be prepended with "macro/" + // (see TODO in common impl regarding plugins-like functionality) + ASSERT_NO_THROW(::dfi::macro::load("macro/crypto/hash.C")); gInterpreter->ProcessLine( "dfi::macro::common::crypto::botan::Hash h;", ecode.get()); ASSERT_NE(ecode, nullptr);