From ec015e87ef511f45826ae53c0aae1d6e1a99b9f1 Mon Sep 17 00:00:00 2001 From: Zohar Malamant Date: Thu, 14 Jul 2022 13:49:53 +0200 Subject: [PATCH] config_parser: Make paths absolute --- libres/lib/CMakeLists.txt | 1 - libres/lib/config/config_content.cpp | 73 ++++------ libres/lib/config/config_content_node.cpp | 14 -- libres/lib/config/config_path_elm.cpp | 125 +++--------------- libres/lib/config/config_root_path.cpp | 89 ------------- libres/lib/config/config_schema_item.cpp | 2 +- .../lib/include/ert/config/config_content.hpp | 6 - .../ert/config/config_content_node.hpp | 2 - .../include/ert/config/config_path_elm.hpp | 18 +-- .../include/ert/config/config_root_path.hpp | 33 ----- libres/old_tests/config/CMakeLists.txt | 4 - .../config/test_config_content_node.cpp | 6 +- .../old_tests/config/test_config_include.cpp | 22 --- .../old_tests/config/test_config_path_elm.cpp | 20 +-- .../config/test_config_root_path.cpp | 82 ------------ res/config/config_content.py | 16 +-- res/config/config_path_elm.py | 5 - res/enkf/config/gen_kw_config.py | 6 +- res/enkf/enkf_main.py | 2 +- .../local/poly_example/assert_runpath_file.py | 2 +- tests/libres_tests/res/config/test_config.py | 11 +- .../libres_tests/res/enkf/test_res_config.py | 30 +++++ 22 files changed, 102 insertions(+), 467 deletions(-) delete mode 100644 libres/lib/config/config_root_path.cpp delete mode 100644 libres/lib/include/ert/config/config_root_path.hpp delete mode 100644 libres/old_tests/config/test_config_root_path.cpp diff --git a/libres/lib/CMakeLists.txt b/libres/lib/CMakeLists.txt index 58beab9b226..3d9733c6d32 100644 --- a/libres/lib/CMakeLists.txt +++ b/libres/lib/CMakeLists.txt @@ -38,7 +38,6 @@ pybind11_add_module( config/config_content_node.cpp config/config_error.cpp config/config_path_elm.cpp - config/config_root_path.cpp config/config_schema_item.cpp config/config_settings.cpp rms/rms_file.cpp diff --git a/libres/lib/config/config_content.cpp b/libres/lib/config/config_content.cpp index 5fd5c1d79be..8c2b7b79672 100644 --- a/libres/lib/config/config_content.cpp +++ b/libres/lib/config/config_content.cpp @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -28,7 +29,8 @@ #include #include #include -#include + +namespace fs = std::filesystem; #define CONFIG_CONTENT_TYPE_ID 6612520 @@ -36,7 +38,7 @@ struct config_content_struct { UTIL_TYPE_ID_DECLARATION; /** A set of config files which have been parsed - to protect against * circular includes. */ - std::set *parsed_files; + std::set parsed_files; vector_type *nodes; hash_type *items; config_error_type *parse_errors; @@ -47,17 +49,16 @@ struct config_content_struct { char *config_path; config_path_stack_type *path_stack; - config_root_path_type *invoke_path; + /** Absolute path to directory that contains current config */ + fs::path invoke_path; bool valid; }; UTIL_IS_INSTANCE_FUNCTION(config_content, CONFIG_CONTENT_TYPE_ID) config_content_type *config_content_alloc(const char *filename) { - config_content_type *content = - (config_content_type *)util_malloc(sizeof *content); + auto content = new config_content_type; UTIL_TYPE_ID_INIT(content, CONFIG_CONTENT_TYPE_ID); - content->parsed_files = new std::set(); content->valid = false; content->items = hash_alloc(); @@ -70,7 +71,7 @@ config_content_type *config_content_alloc(const char *filename) { content->config_file = util_alloc_string_copy(filename); content->abs_path = util_alloc_abs_path(filename); content->config_path = util_split_alloc_dirname(content->abs_path); - content->invoke_path = config_root_path_alloc(NULL); + content->invoke_path = fs::current_path(); return content; } @@ -128,8 +129,6 @@ void config_content_free(config_content_type *content) { if (!content) return; - delete content->parsed_files; - stringlist_free(content->warnings); vector_free(content->nodes); hash_free(content->items); @@ -138,28 +137,21 @@ void config_content_free(config_content_type *content) { free(content->config_file); free(content->abs_path); free(content->config_path); - if (content->invoke_path != NULL) - config_root_path_free(content->invoke_path); config_path_stack_free(content->path_stack); - free(content); + delete content; } bool config_content_add_file(config_content_type *content, const char *config_file) { - const auto iter = content->parsed_files->find(config_file); - if (iter == content->parsed_files->end()) { - content->parsed_files->insert(config_file); + const auto iter = content->parsed_files.find(config_file); + if (iter == content->parsed_files.end()) { + content->parsed_files.insert(config_file); return true; } return false; } -config_root_path_type * -config_content_get_invoke_path(config_content_type *content) { - return content->invoke_path; -} - /* Here comes some xxx_get() functions - many of them will fail if the item has not been added in the right way (this is to ensure that @@ -331,14 +323,6 @@ config_content_get_value_as_abspath(const config_content_type *config, return config_content_node_iget_as_abspath(node, 0); } -const char * -config_content_get_value_as_relpath(const config_content_type *config, - const char *kw) { - config_content_node_type *node = - config_content_get_value_node__(config, kw); - return config_content_node_iget_as_relpath(node, 0); -} - const char * config_content_get_value_as_executable(const config_content_type *config, const char *kw) { @@ -389,34 +373,25 @@ const char *config_content_get_config_file(const config_content_type *content, config_path_elm_type *config_content_add_path_elm(config_content_type *content, const char *path) { - const config_path_elm_type *current_path_elm; + const config_path_elm_type *current_path_elm{}; if (config_path_stack_size(content->path_stack) == 0) current_path_elm = NULL; else current_path_elm = config_path_stack_get_last(content->path_stack); - { - config_path_elm_type *new_path_elm; - - { - char *rel_path = NULL; - config_root_path_type *invoke_path = - config_content_get_invoke_path(content); - if (path != NULL) { - if (current_path_elm == NULL) - rel_path = util_alloc_rel_path( - config_root_path_get_abs_path(invoke_path), path); - else - rel_path = - config_path_elm_alloc_relpath(current_path_elm, path); - } - new_path_elm = config_path_elm_alloc(invoke_path, rel_path); - free(rel_path); - } - config_path_stack_append(content->path_stack, new_path_elm); - return new_path_elm; + config_path_elm_type *new_path_elm; + const auto &invoke_path = current_path_elm == nullptr + ? content->invoke_path + : current_path_elm->path; + if (path != NULL) { + auto new_path = fs::absolute(invoke_path / path); + new_path_elm = config_path_elm_alloc(invoke_path, new_path.c_str()); + } else { + new_path_elm = config_path_elm_alloc(invoke_path, nullptr); } + config_path_stack_append(content->path_stack, new_path_elm); + return new_path_elm; } const char *config_content_get_config_path(const config_content_type *content) { diff --git a/libres/lib/config/config_content_node.cpp b/libres/lib/config/config_content_node.cpp index b416905d004..312b9b15281 100644 --- a/libres/lib/config/config_content_node.cpp +++ b/libres/lib/config/config_content_node.cpp @@ -184,20 +184,6 @@ const char *config_content_node_iget_as_abspath(config_content_node_type *node, } } -const char *config_content_node_iget_as_relpath(config_content_node_type *node, - int index) { - config_schema_item_assure_type(node->schema, index, - CONFIG_PATH + CONFIG_EXISTING_PATH); - { - const char *config_value = config_content_node_iget(node, index); - char *path_value = - config_path_elm_alloc_relpath(node->cwd, config_value); - config_content_node_push_string(node, path_value); - - return path_value; - } -} - const char * config_content_node_iget_as_executable(config_content_node_type *node, int index) { diff --git a/libres/lib/config/config_path_elm.cpp b/libres/lib/config/config_path_elm.cpp index 73f3e12cdb2..373302e463d 100644 --- a/libres/lib/config/config_path_elm.cpp +++ b/libres/lib/config/config_path_elm.cpp @@ -16,6 +16,7 @@ for more details. */ +#include #include #include @@ -24,127 +25,43 @@ #include #include -#include #include +namespace fs = std::filesystem; + #define CONFIG_PATH_ELM_TYPE_ID 7100063 -struct config_path_elm_struct { - UTIL_TYPE_ID_DECLARATION; - /** This will always be absolute */ - char *abs_path; - /** This will always be relative to the root path. */ - char *rel_path; - const config_root_path_type *root_path; -}; - -static UTIL_SAFE_CAST_FUNCTION(config_path_elm, CONFIG_PATH_ELM_TYPE_ID) - - config_path_elm_type *config_path_elm_alloc( - const config_root_path_type *root_path, const char *path) { - if (root_path != NULL) { - config_path_elm_type *path_elm = - (config_path_elm_type *)util_malloc(sizeof *path_elm); - UTIL_TYPE_ID_INIT(path_elm, CONFIG_PATH_ELM_TYPE_ID); - path_elm->root_path = root_path; - if (path == NULL) { - path_elm->rel_path = NULL; - path_elm->abs_path = util_alloc_string_copy( - config_root_path_get_abs_path(root_path)); - } else { - if (util_is_abs_path(path)) { - path_elm->abs_path = util_alloc_string_copy(path); - path_elm->rel_path = util_alloc_rel_path( - config_root_path_get_abs_path(root_path), path); - } else { - { - char *tmp_abs_path = (char *)util_alloc_filename( - config_root_path_get_abs_path(root_path), path, NULL); - path_elm->abs_path = util_alloc_abs_path(tmp_abs_path); - free(tmp_abs_path); - } - path_elm->rel_path = util_alloc_string_copy(path); - } - } - return path_elm; +static UTIL_SAFE_CAST_FUNCTION(config_path_elm, CONFIG_PATH_ELM_TYPE_ID); + +config_path_elm_type *config_path_elm_alloc(const fs::path &root_path, + const char *path) { + auto path_elm = new config_path_elm_type; + UTIL_TYPE_ID_INIT(path_elm, CONFIG_PATH_ELM_TYPE_ID); + if (path == NULL) { + path_elm->path = root_path; } else { - util_abort("%s: root_path input argument == NULL - invalid \n", - __func__); - return NULL; + path_elm->path = root_path / path; } + path_elm->path = fs::absolute(path_elm->path); + return path_elm; } -void config_path_elm_free(config_path_elm_type *path_elm) { - free(path_elm->rel_path); - free(path_elm->abs_path); - free(path_elm); -} +void config_path_elm_free(config_path_elm_type *path_elm) { delete path_elm; } void config_path_elm_free__(void *arg) { config_path_elm_type *path_elm = config_path_elm_safe_cast(arg); config_path_elm_free(path_elm); } -const char *config_path_elm_get_relpath(const config_path_elm_type *path_elm) { - return path_elm->rel_path; -} - const char *config_path_elm_get_abspath(const config_path_elm_type *path_elm) { - return path_elm->abs_path; + return path_elm->path.c_str(); } char *config_path_elm_alloc_path(const config_path_elm_type *path_elm, - const char *path) { - if (util_is_abs_path(path)) - return util_alloc_string_copy(path); - else { - /* This will be relative or absolute depending on the relative/absolute - status of the root_path. */ - const char *input_root = - config_root_path_get_input_path(path_elm->root_path); - std::string tmp_path; - char *return_path; - if (input_root == NULL) - tmp_path = util_alloc_filename(path_elm->rel_path, path, NULL); - else { - const std::vector str_list{input_root, - path_elm->rel_path, path}; - - tmp_path = - fmt::format("{}", fmt::join(str_list, UTIL_PATH_SEP_STRING)); - } - - return_path = util_alloc_normal_path(tmp_path.c_str()); - - return return_path; - } -} - -char *config_path_elm_alloc_relpath(const config_path_elm_type *path_elm, - const char *input_path) { - if (util_is_abs_path(input_path)) - return util_alloc_rel_path( - config_root_path_get_rel_path(path_elm->root_path), input_path); - else { - char *abs_path = config_path_elm_alloc_abspath(path_elm, input_path); - char *rel_path = (char *)util_alloc_rel_path( - config_root_path_get_abs_path(path_elm->root_path), abs_path); - free(abs_path); - return rel_path; - } -} - -char *config_path_elm_alloc_abspath(const config_path_elm_type *path_elm, - const char *input_path) { - if (util_is_abs_path(input_path)) - return util_alloc_string_copy(input_path); - else { - char *abs_path1 = - (char *)util_alloc_filename(path_elm->abs_path, input_path, NULL); - char *abs_path = (char *)util_alloc_realpath__( - abs_path1); // The util_alloc_realpath__() will work also for nonexsting paths - free(abs_path1); - return abs_path; - } + const char *input_path) { + if (input_path[0] == '/') + return strdup(input_path); + auto path = (path_elm->path / input_path).lexically_normal(); + return strdup(path.c_str()); } diff --git a/libres/lib/config/config_root_path.cpp b/libres/lib/config/config_root_path.cpp deleted file mode 100644 index 292404cd9a8..00000000000 --- a/libres/lib/config/config_root_path.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 2013 Equinor ASA, Norway. - - The file 'config_root_path.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include - -#include - -#include - -struct config_root_path_struct { - char *input_path; - char *abs_path; - char *rel_path; -}; - -/** - Input must be an existing directory, which will be used as the - root; or NULL in which case cwd will be used as root. The input - directory can be both realtive or absolute. -*/ -config_root_path_type *config_root_path_alloc(const char *input_path) { - if (input_path == NULL || util_is_directory(input_path)) { - config_root_path_type *root_path = - (config_root_path_type *)util_malloc(sizeof *root_path); - { - char *cwd = (char *)util_alloc_cwd(); - - root_path->input_path = util_alloc_string_copy(input_path); - if (input_path == NULL) { - root_path->rel_path = NULL; - root_path->abs_path = util_alloc_string_copy(cwd); - } else { - if (util_is_abs_path(input_path)) { - root_path->abs_path = util_alloc_string_copy(input_path); - root_path->rel_path = - util_alloc_rel_path(cwd, root_path->abs_path); - } else { - root_path->rel_path = util_alloc_string_copy(input_path); - { - char *abs_path = - (char *)util_alloc_filename(cwd, input_path, NULL); - root_path->abs_path = util_alloc_realpath(abs_path); - free(abs_path); - } - } - } - free(cwd); - } - return root_path; - } else - return NULL; -} - -void config_root_path_free(config_root_path_type *root_path) { - free(root_path->rel_path); - free(root_path->abs_path); - free(root_path->input_path); - free(root_path); -} - -const char * -config_root_path_get_input_path(const config_root_path_type *root_path) { - return root_path->input_path; -} - -const char * -config_root_path_get_rel_path(const config_root_path_type *root_path) { - return root_path->rel_path; -} - -const char * -config_root_path_get_abs_path(const config_root_path_type *root_path) { - return root_path->abs_path; -} diff --git a/libres/lib/config/config_schema_item.cpp b/libres/lib/config/config_schema_item.cpp index 84484a194ed..0e6d481f38d 100644 --- a/libres/lib/config/config_schema_item.cpp +++ b/libres/lib/config/config_schema_item.cpp @@ -422,7 +422,7 @@ bool config_schema_item_validate_set(const config_schema_item_type *item, error_list, util_alloc_sprintf( "Can not find entry %s in %s ", value, - config_path_elm_get_relpath(path_elm))); + config_path_elm_get_abspath(path_elm))); OK = false; } free(path); diff --git a/libres/lib/include/ert/config/config_content.hpp b/libres/lib/include/ert/config/config_content.hpp index 954db515166..cb45a50c834 100644 --- a/libres/lib/include/ert/config/config_content.hpp +++ b/libres/lib/include/ert/config/config_content.hpp @@ -25,7 +25,6 @@ #include #include -#include #include typedef struct config_content_struct config_content_type; @@ -76,9 +75,6 @@ extern "C" const char * config_content_get_value_as_abspath(const config_content_type *config, const char *kw); const char * -config_content_get_value_as_relpath(const config_content_type *config, - const char *kw); -const char * config_content_get_value_as_executable(const config_content_type *config, const char *kw); const char *config_content_get_value(const config_content_type *config, @@ -101,8 +97,6 @@ const config_content_node_type * config_content_iget_node(const config_content_type *content, int index); bool config_content_add_file(config_content_type *content, const char *config_file); -config_root_path_type * -config_content_get_invoke_path(config_content_type *content); extern "C" config_path_elm_type * config_content_add_path_elm(config_content_type *content, const char *path); extern "C" const stringlist_type * diff --git a/libres/lib/include/ert/config/config_content_node.hpp b/libres/lib/include/ert/config/config_content_node.hpp index 4d0b82d05da..c421db9bb48 100644 --- a/libres/lib/include/ert/config/config_content_node.hpp +++ b/libres/lib/include/ert/config/config_content_node.hpp @@ -58,8 +58,6 @@ extern "C" const char * config_content_node_iget_as_path(config_content_node_type *node, int index); extern "C" const char * config_content_node_iget_as_abspath(config_content_node_type *node, int index); -extern "C" const char * -config_content_node_iget_as_relpath(config_content_node_type *node, int index); const char * config_content_node_iget_as_executable(config_content_node_type *node, int index); diff --git a/libres/lib/include/ert/config/config_path_elm.hpp b/libres/lib/include/ert/config/config_path_elm.hpp index 788fa2e8f1c..5067c95dfbf 100644 --- a/libres/lib/include/ert/config/config_path_elm.hpp +++ b/libres/lib/include/ert/config/config_path_elm.hpp @@ -19,23 +19,23 @@ #ifndef ERT_CONFIG_PATH_ELM_H #define ERT_CONFIG_PATH_ELM_H -#include +#include -typedef struct config_path_elm_struct config_path_elm_type; +struct config_path_elm_type { + /** UTIL_TYPE_ID_DECLARATION */ + int __type_id; + std::filesystem::path path; +}; extern "C" void config_path_elm_free(config_path_elm_type *path_elm); void config_path_elm_free__(void *arg); config_path_elm_type * -config_path_elm_alloc(const config_root_path_type *root_path, const char *path); +config_path_elm_alloc(const std::filesystem::path &root_path, const char *path); extern "C" const char * config_path_elm_get_abspath(const config_path_elm_type *path_elm); -extern "C" const char * -config_path_elm_get_relpath(const config_path_elm_type *path_elm); -char *config_path_elm_alloc_abspath(const config_path_elm_type *path_elm, - const char *input_path); -char *config_path_elm_alloc_relpath(const config_path_elm_type *path_elm, - const char *input_path); char *config_path_elm_alloc_path(const config_path_elm_type *path_elm, const char *input_path); +#define config_path_elm_alloc_abspath(path_elm, input_path) \ + config_path_elm_alloc_path(path_elm, input_path) #endif diff --git a/libres/lib/include/ert/config/config_root_path.hpp b/libres/lib/include/ert/config/config_root_path.hpp deleted file mode 100644 index 4401b4368d4..00000000000 --- a/libres/lib/include/ert/config/config_root_path.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2013 Equinor ASA, Norway. - - The file 'config_root_path.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_CONFIG_ROOT_PATH_H -#define ERT_CONFIG_ROOT_PATH_H - -typedef struct config_root_path_struct config_root_path_type; - -void config_root_path_free(config_root_path_type *root_path); -config_root_path_type *config_root_path_alloc(const char *input_path); -const char * -config_root_path_get_input_path(const config_root_path_type *root_path); -const char * -config_root_path_get_rel_path(const config_root_path_type *root_path); -const char * -config_root_path_get_abs_path(const config_root_path_type *root_path); - -#endif diff --git a/libres/old_tests/config/CMakeLists.txt b/libres/old_tests/config/CMakeLists.txt index f51ccd960fc..bba2479bcb6 100644 --- a/libres/old_tests/config/CMakeLists.txt +++ b/libres/old_tests/config/CMakeLists.txt @@ -16,7 +16,6 @@ foreach( config_node config_typeOK config_typeFail - config_root_path config_include config_content_item config_define @@ -33,9 +32,6 @@ config_test(config_typeFail type_testFail) config_test(config_content_item content_item_test) config_test(config_define define_test) -add_test(NAME config_root_path COMMAND config_root_path - "${TEST_DATA_DIR}/config") - add_test(NAME config_include COMMAND config_include "${TEST_DATA_DIR}/config" include_test) diff --git a/libres/old_tests/config/test_config_content_node.cpp b/libres/old_tests/config/test_config_content_node.cpp index 91abe1d6a50..0ac59a76724 100644 --- a/libres/old_tests/config/test_config_content_node.cpp +++ b/libres/old_tests/config/test_config_content_node.cpp @@ -15,6 +15,7 @@ See the GNU General Public License at for more details. */ +#include #include #include @@ -24,8 +25,8 @@ int main(int argc, char **argv) { config_schema_item_type *schema = config_schema_item_alloc("TEST", true); - config_root_path_type *root_path = config_root_path_alloc(NULL); - config_path_elm_type *cwd = config_path_elm_alloc(root_path, NULL); + config_path_elm_type *cwd = + config_path_elm_alloc(std::filesystem::current_path(), NULL); { config_content_node_type *node = config_content_node_alloc(schema, cwd); config_content_node_add_value(node, "KEY1:VALUE1"); @@ -70,7 +71,6 @@ int main(int argc, char **argv) { config_content_node_free(node); } config_path_elm_free(cwd); - config_root_path_free(root_path); config_schema_item_free(schema); exit(0); } diff --git a/libres/old_tests/config/test_config_include.cpp b/libres/old_tests/config/test_config_include.cpp index c7c016aae59..81f506dcc67 100644 --- a/libres/old_tests/config/test_config_include.cpp +++ b/libres/old_tests/config/test_config_include.cpp @@ -54,34 +54,12 @@ void parse_test( CONFIG_UNRECOGNIZED_IGNORE, true); if (config_content_is_valid(content)) { - char *relpath0 = util_alloc_filename(config_rel_path, path0, NULL); - char *relpath1 = util_alloc_filename(config_rel_path, path1, NULL); - char *relpath2 = util_alloc_filename(config_rel_path, path2, NULL); - char *relpath3 = util_alloc_filename(config_rel_path, path3, NULL); - char *relpath4 = util_alloc_filename(config_rel_path, path4, NULL); - char *abspath0 = util_alloc_filename(config_abs_path, path0, NULL); char *abspath1 = util_alloc_filename(config_abs_path, path1, NULL); char *abspath2 = util_alloc_filename(config_abs_path, path2, NULL); char *abspath3 = util_alloc_filename(config_abs_path, path3, NULL); char *abspath4 = util_alloc_filename(config_abs_path, path4, NULL); - test_assert_string_equal( - config_content_get_value_as_relpath(content, "PATH0"), - relpath0); - test_assert_string_equal( - config_content_get_value_as_relpath(content, "PATH1"), - relpath1); - test_assert_string_equal( - config_content_get_value_as_relpath(content, "PATH2"), - relpath2); - test_assert_string_equal( - config_content_get_value_as_relpath(content, "PATH3"), - relpath3); - test_assert_string_equal( - config_content_get_value_as_relpath(content, "PATH4"), - relpath4); - test_assert_string_equal( config_content_get_value_as_abspath(content, "PATH0"), abspath0); diff --git a/libres/old_tests/config/test_config_path_elm.cpp b/libres/old_tests/config/test_config_path_elm.cpp index f93dafc0445..54113c23997 100644 --- a/libres/old_tests/config/test_config_path_elm.cpp +++ b/libres/old_tests/config/test_config_path_elm.cpp @@ -15,6 +15,7 @@ See the GNU General Public License at for more details. */ +#include #include #include @@ -35,18 +36,14 @@ int main(int argc, char **argv) { char *path_true2 = util_alloc_filename(root, "rel/path/XXX", NULL); util_chdir(ta.original_cwd().c_str()); - config_root_path_type *root_path = config_root_path_alloc(root); + std::filesystem::path root_path = root; { config_path_elm_type *path_elm = config_path_elm_alloc(root_path, rel_path); - test_assert_string_equal(config_path_elm_get_relpath(path_elm), - rel_path); test_assert_string_equal(config_path_elm_get_abspath(path_elm), abs_path); - test_assert_string_equal(config_path_elm_alloc_relpath(path_elm, "XXX"), - rel_true); test_assert_string_equal(config_path_elm_alloc_abspath(path_elm, "XXX"), abs_true); test_assert_string_equal(config_path_elm_alloc_path(path_elm, "XXX"), @@ -58,13 +55,9 @@ int main(int argc, char **argv) { config_path_elm_type *path_elm = config_path_elm_alloc(root_path, abs_path); - test_assert_string_equal(config_path_elm_get_relpath(path_elm), - rel_path); test_assert_string_equal(config_path_elm_get_abspath(path_elm), abs_path); - test_assert_string_equal(config_path_elm_alloc_relpath(path_elm, "XXX"), - rel_true); test_assert_string_equal(config_path_elm_alloc_abspath(path_elm, "XXX"), abs_true); test_assert_string_equal(config_path_elm_alloc_path(path_elm, "XXX"), @@ -72,25 +65,18 @@ int main(int argc, char **argv) { config_path_elm_free(path_elm); } - config_root_path_free(root_path); util_chdir(root); - root_path = config_root_path_alloc(NULL); + root_path = std::filesystem::current_path(); { config_path_elm_type *path_elm = config_path_elm_alloc(root_path, rel_path); - test_assert_string_equal(config_path_elm_get_relpath(path_elm), - rel_path); test_assert_string_equal(config_path_elm_get_abspath(path_elm), abs_path); - test_assert_string_equal(config_path_elm_alloc_relpath(path_elm, "XXX"), - rel_true); test_assert_string_equal(config_path_elm_alloc_abspath(path_elm, "XXX"), abs_true); - test_assert_string_equal(config_path_elm_alloc_path(path_elm, "XXX"), - path_true1); config_path_elm_free(path_elm); } diff --git a/libres/old_tests/config/test_config_root_path.cpp b/libres/old_tests/config/test_config_root_path.cpp deleted file mode 100644 index 066b803e670..00000000000 --- a/libres/old_tests/config/test_config_root_path.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2013 Equinor ASA, Norway. - - The file 'config_root_path.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include - -#include -#include - -#include - -int main(int argc, char **argv) { - char *cwd = util_alloc_cwd(); - - { - config_root_path_type *root_path = config_root_path_alloc(NULL); - - if (!test_check_string_equal(config_root_path_get_abs_path(root_path), - cwd)) - test_error_exit("abs:path:%s expeceted:%s \n", - config_root_path_get_abs_path(root_path), cwd); - - if (!test_check_string_equal(config_root_path_get_input_path(root_path), - NULL)) - test_error_exit("input:path:%s expeceted:%s \n", - config_root_path_get_input_path(root_path), NULL); - - if (!test_check_string_equal(config_root_path_get_rel_path(root_path), - NULL)) - test_error_exit("rel:path:%s expeceted:%s \n", - config_root_path_get_rel_path(root_path), NULL); - - config_root_path_free(root_path); - } - - { - config_root_path_type *root_path = - config_root_path_alloc("/does/not/exist"); - if (root_path != NULL) - test_error_exit( - "Created root_path instance for not-existing input \n"); - } - - { - const char *input_path = argv[1]; - char *cwd = util_alloc_cwd(); - char *rel_path = util_alloc_rel_path(cwd, input_path); - - config_root_path_type *root_path1 = config_root_path_alloc(input_path); - config_root_path_type *root_path2 = config_root_path_alloc(rel_path); - - if (!test_check_string_equal(config_root_path_get_rel_path(root_path1), - config_root_path_get_rel_path(root_path2))) - test_error_exit("Rel: %s != %s \n", - config_root_path_get_rel_path(root_path1), - config_root_path_get_rel_path(root_path2)); - - if (!test_check_string_equal(config_root_path_get_abs_path(root_path1), - config_root_path_get_abs_path(root_path2))) - test_error_exit("Abs: %s != %s \n", - config_root_path_get_abs_path(root_path1), - config_root_path_get_abs_path(root_path2)); - - config_root_path_free(root_path1); - config_root_path_free(root_path2); - } - - exit(0); -} diff --git a/res/config/config_content.py b/res/config/config_content.py index 6ef4e2aebfc..83acb15b639 100644 --- a/res/config/config_content.py +++ b/res/config/config_content.py @@ -14,8 +14,6 @@ # See the GNU General Public License at # for more details. -import os.path - from cwrap import BaseCClass from res import ResPrototype @@ -39,9 +37,6 @@ class ContentNode(BaseCClass): _iget_as_abspath = ResPrototype( "char* config_content_node_iget_as_abspath( content_node , int)" ) - _iget_as_relpath = ResPrototype( - "char* config_content_node_iget_as_relpath( content_node , int)" - ) _iget_as_string = ResPrototype( "char* config_content_node_iget( content_node , int)" ) @@ -95,21 +90,14 @@ def __getitem__(self, index): typed_get = self.typed_get[content_type] return typed_get(self, index) - def getPath(self, index=0, absolute=True, relative_start=None): + def getPath(self, index=0): index = self.__assertIndex(index) content_type = self._iget_type(index) if content_type in [ ContentTypeEnum.CONFIG_EXISTING_PATH, ContentTypeEnum.CONFIG_PATH, ]: - if absolute: - return self._iget_as_abspath(index) - else: - if relative_start is None: - return self._iget_as_relpath(index) - else: - abs_path = self._iget_as_abspath(index) - return os.path.relpath(abs_path, relative_start) + return self._iget_as_abspath(index) else: raise TypeError("The getPath() method can only be called on PATH items") diff --git a/res/config/config_path_elm.py b/res/config/config_path_elm.py index 77612263914..89de9bc3aa6 100644 --- a/res/config/config_path_elm.py +++ b/res/config/config_path_elm.py @@ -23,7 +23,6 @@ class ConfigPathElm(BaseCClass): TYPE_NAME = "config_path_elm" _free = ResPrototype("void config_path_elm_free(config_path_elm)") - _rel_path = ResPrototype("char* config_path_elm_get_relpath(config_path_elm)") _abs_path = ResPrototype("char* config_path_elm_get_abspath(config_path_elm)") def __init__(self): @@ -32,10 +31,6 @@ def __init__(self): def free(self): self._free() - @property - def rel_path(self): - return self._rel_path() - @property def abs_path(self): return self._abs_path() diff --git a/res/enkf/config/gen_kw_config.py b/res/enkf/config/gen_kw_config.py index bfb3c5ba3bc..78ebe81f68a 100644 --- a/res/enkf/config/gen_kw_config.py +++ b/res/enkf/config/gen_kw_config.py @@ -84,10 +84,12 @@ def __init__(self, key, template_file, parameter_file, tag_fmt="<%s>"): self.__str__ = self.__repr__ def getTemplateFile(self): - return self._get_template_file() + path = self._get_template_file() + return None if path is None else os.path.abspath(path) def getParameterFile(self): - return self._get_parameter_file() + path = self._get_parameter_file() + return None if path is None else os.path.abspath(path) def getKeyWords(self) -> StringList: """@rtype: StringList""" diff --git a/res/enkf/enkf_main.py b/res/enkf/enkf_main.py index 7727aadbc40..c7e7f7bd8b4 100644 --- a/res/enkf/enkf_main.py +++ b/res/enkf/enkf_main.py @@ -370,7 +370,7 @@ def __init__(self, config, strict=True, read_only=False): self.runpaths = Runpaths( self.getModelConfig().getJobnameFormat(), self.getModelConfig().getRunpathFormat().format_string, - Path(res_config.config_path).resolve() / res_config.runpath_file, + Path(res_config.runpath_file), self.substituter.substitute, ) diff --git a/test-data/local/poly_example/assert_runpath_file.py b/test-data/local/poly_example/assert_runpath_file.py index 05f53fe92a3..5398e417202 100755 --- a/test-data/local/poly_example/assert_runpath_file.py +++ b/test-data/local/poly_example/assert_runpath_file.py @@ -14,7 +14,7 @@ def run(): curdir = sys.argv[2] runpath_line = ( "{iens:03d} " - "{pwd}/poly_example/poly_out/realization-{iens}/iter-{iter} " + "{pwd}/poly_out/realization-{iens}/iter-{iter} " "poly_{iens} {iter:03d}\n" ) with open(runpath_file) as fh: diff --git a/tests/libres_tests/res/config/test_config.py b/tests/libres_tests/res/config/test_config.py index fbf464dcf84..1a7df1fee9e 100755 --- a/tests/libres_tests/res/config/test_config.py +++ b/tests/libres_tests/res/config/test_config.py @@ -105,7 +105,7 @@ def test_item_types(self): self.assertEqual(type_item.igetString(3), "String") path_value = type_item[4] - self.assertEqual(path_value, "file") + self.assertEqual(path_value, os.path.abspath("file")) self.assertEqual(type_item.igetString(4), "file") # test __getitem__ @@ -249,7 +249,7 @@ def test_parser_content(self): self.assertEqual(line[2], 100) self.assertEqual(line[3], True) self.assertEqual(line[4], 3.14) - self.assertEqual(line[5], "../path/file.txt") + self.assertEqual(line[5], os.path.abspath("../path/file.txt")) self.assertFalse("NOT_IN_CONTENT" in content) item = content["NOT_IN_CONTENT"] @@ -269,16 +269,11 @@ def test_parser_content(self): with self.assertRaises(TypeError): line.getPath() - rel_path = line.getPath(index=5, absolute=False) - self.assertEqual(rel_path, "../path/file.txt") get = line[5] - self.assertEqual(get, "../path/file.txt") + self.assertEqual(get, os.path.abspath("../path/file.txt")) abs_path = line.getPath(index=5) self.assertEqual(abs_path, os.path.join(cwd0, "path/file.txt")) - rel_path = line.getPath(index=5, absolute=False, relative_start="../") - self.assertEqual(rel_path, "path/file.txt") - with self.assertRaises(IndexError): item[10] diff --git a/tests/libres_tests/res/enkf/test_res_config.py b/tests/libres_tests/res/enkf/test_res_config.py index 97c6cf46626..1a2ff1bf44a 100644 --- a/tests/libres_tests/res/enkf/test_res_config.py +++ b/tests/libres_tests/res/enkf/test_res_config.py @@ -696,3 +696,33 @@ def test_res_config_dict_constructor(self): res_config_dict = ResConfig(config_dict=config_data_new) self.assertEqual(res_config_file, res_config_dict) + + +def test_runpath_file(monkeypatch, tmp_path): + """ + There was an issue relating to `ResConfig.runpath_file` returning a + relative path rather than an absolute path. This test simulates the + conditions that caused the original bug. That is, the user starts + somewhere else and points to the ERT config file using a relative + path. + """ + config_path = tmp_path / "model/ert/config.ert" + workdir_path = tmp_path / "start/from/here" + runpath_path = tmp_path / "model/output/my_custom_runpath_path.foo" + + config_path.parent.mkdir(parents=True) + workdir_path.mkdir(parents=True) + monkeypatch.chdir(workdir_path) + + with config_path.open("w") as f: + f.writelines( + [ + "DEFINE foo\n", + "RUNPATH_FILE ../output/my_custom_runpath_path.\n", + # Required for this to be a valid ResConfig + "NUM_REALIZATIONS 1\n", + ] + ) + + config = ResConfig(os.path.relpath(config_path, workdir_path)) + assert config.runpath_file == str(runpath_path)