diff options
-rw-r--r-- | libbutl/default-options.mxx | 8 | ||||
-rw-r--r-- | libbutl/default-options.txx | 76 | ||||
-rw-r--r-- | libbutl/git.cxx | 3 |
3 files changed, 60 insertions, 27 deletions
diff --git a/libbutl/default-options.mxx b/libbutl/default-options.mxx index d7aa70b..62c7f92 100644 --- a/libbutl/default-options.mxx +++ b/libbutl/default-options.mxx @@ -7,7 +7,8 @@ #endif #ifndef __cpp_lib_modules_ts -#include <utility> // move(), forward() +#include <utility> // move(), forward(), make_pair() +#include <system_error> #endif // Other includes. @@ -63,8 +64,9 @@ LIBBUTL_MODEXPORT namespace butl // // void (const path&, bool remote) // - // Throw std::system_error on the underlying OS error and pass through - // exceptions thrown by the options scanner/parser. + // Throw `pair<path, system_error>` on the underlying OS error with the + // first half referring the filesystem entry the error relates to and pass + // through exceptions thrown by the options scanner/parser. // // Search order: // diff --git a/libbutl/default-options.txx b/libbutl/default-options.txx index 2ed12e4..996ee33 100644 --- a/libbutl/default-options.txx +++ b/libbutl/default-options.txx @@ -4,6 +4,17 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. { + inline bool + options_dir_exists (const dir_path& d) + try + { + return dir_exists (d); + } + catch (std::system_error& e) + { + throw std::make_pair (path_cast<path> (d), std::move (e)); + } + // Search for and parse the options files in the specified directory and // its local/ subdirectory, if exists, and append the options to the // resulting list. @@ -33,22 +44,31 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. { path p (d / f); - if (file_exists (p)) // Follows symlinks. + try { - fn (p, remote); - - S s (p.string ()); - - // @@ Note that the potentially thrown exceptions (unknown option, - // unexpected argument, etc) will not contain any location - // information. Intercepting exception handling to add the file - // attribution feels too hairy for now. Maybe we should support - // this in CLI. - // - O o; - o.parse (s, U::fail, U::fail); - - r.push_back (default_options_entry<O> {move (p), move (o), remote}); + if (file_exists (p)) // Follows symlinks. + { + fn (p, remote); + + S s (p.string ()); + + // @@ Note that the potentially thrown exceptions (unknown option, + // unexpected argument, etc) will not contain any location + // information. Intercepting exception handling to add the file + // attribution feels too hairy for now. Maybe we should support + // this in CLI. + // + O o; + o.parse (s, U::fail, U::fail); + + r.push_back (default_options_entry<O> {move (p), + move (o), + remote}); + } + } + catch (std::system_error& e) + { + throw std::make_pair (move (p), std::move (e)); } } }; @@ -57,7 +77,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. dir_path ld (d / dir_path ("local")); - if (dir_exists (ld)) + if (options_dir_exists (ld)) load (ld, remote); } @@ -78,15 +98,23 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. return false; bool remote (load_default_options_files<O, S, U> (start_dir.directory (), - home_dir, - fs, - std::forward<F> (fn), - r) || - git_repository (start_dir)); + home_dir, + fs, + std::forward<F> (fn), + r)); + if (!remote) + try + { + remote = git_repository (start_dir); + } + catch (std::system_error& e) + { + throw std::make_pair (start_dir / ".git", std::move (e)); + } dir_path d (start_dir / dir_path (".build2")); - if (dir_exists (d)) + if (options_dir_exists (d)) load_default_options_files<O, S, U> (d, remote, fs, @@ -109,7 +137,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. { assert (sys_dir->absolute () && sys_dir->normalized ()); - if (dir_exists (*sys_dir)) + if (options_dir_exists (*sys_dir)) load_default_options_files<O, S, U> (*sys_dir, false /* remote */, ofs.files, @@ -123,7 +151,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. dir_path d (*home_dir / dir_path (".build2")); - if (dir_exists (d)) + if (options_dir_exists (d)) load_default_options_files<O, S, U> (d, false /* remote */, ofs.files, diff --git a/libbutl/git.cxx b/libbutl/git.cxx index 0f58398..aa0a687 100644 --- a/libbutl/git.cxx +++ b/libbutl/git.cxx @@ -50,6 +50,9 @@ namespace butl // .git can be either a directory or a file in case of a submodule or a // separate working tree. // + // NOTE: remember to update load_default_options_files() if changing + // anything here! + // return entry_exists (d / ".git", true /* follow_symlinks */, true /* ignore_errors */); |