Commit 5d638863 authored by GILLES Sebastien's avatar GILLES Sebastien

#1480 Directory: add comments, rename the enum class and add explicitly the...

#1480 Directory: add comments, rename the enum class and add explicitly the case of read-only directory.
parent 4ca2f7c6
......@@ -56,14 +56,14 @@ BOOST_FIXTURE_TEST_CASE(overwrite, fixture)
FilesystemNS::Directory overwrite(mpi,
test_dir + "/directory_test",
FilesystemNS::if_already_exist::overwrite,
FilesystemNS::behaviour::overwrite,
__FILE__, __LINE__);
BOOST_CHECK(FilesystemNS::Folder::DoExist(overwrite));
FilesystemNS::Directory overwrite_once_again(mpi,
test_dir + "/directory_test",
FilesystemNS::if_already_exist::overwrite,
FilesystemNS::behaviour::overwrite,
__FILE__, __LINE__);
}
......@@ -80,10 +80,18 @@ BOOST_FIXTURE_TEST_CASE(read_case, fixture) // 'read' can't be used here hence t
FilesystemNS::Directory read(mpi,
directory_test,
FilesystemNS::if_already_exist::ignore,
FilesystemNS::behaviour::read,
__FILE__, __LINE__);
BOOST_CHECK_EQUAL(read.GetPath(), directory_test + "/Rank_" + std::to_string(mpi.GetRank<int>()) + "/");
BOOST_CHECK_THROW(FilesystemNS::Directory read_inexistant(mpi,
directory_test + "/qwert",
FilesystemNS::behaviour::read,
__FILE__, __LINE__),
Exception);
}
......@@ -100,7 +108,7 @@ BOOST_FIXTURE_TEST_CASE(quit, fixture)
BOOST_CHECK_THROW(FilesystemNS::Directory read(mpi,
directory_test,
FilesystemNS::if_already_exist::quit,
FilesystemNS::behaviour::quit,
__FILE__, __LINE__),
ExceptionNS::GracefulExit);
}
......@@ -120,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE(ask_yes, fixture)
FilesystemNS::Directory ask_yes(mpi,
directory_test,
FilesystemNS::if_already_exist::ask,
FilesystemNS::behaviour::ask,
__FILE__, __LINE__);
}
......@@ -139,7 +147,7 @@ BOOST_FIXTURE_TEST_CASE(ask_no, fixture)
BOOST_CHECK_THROW(FilesystemNS::Directory ask_no(mpi,
directory_test,
FilesystemNS::if_already_exist::ask,
FilesystemNS::behaviour::ask,
__FILE__, __LINE__),
ExceptionNS::GracefulExit);
}
......@@ -172,7 +180,7 @@ BOOST_FIXTURE_TEST_CASE(ask_on_rank, fixture)
FilesystemNS::Directory ask_yes(mpi,
directory_test,
FilesystemNS::if_already_exist::ask,
FilesystemNS::behaviour::ask,
__FILE__, __LINE__);
}
}
......
......@@ -44,10 +44,10 @@ namespace MoReFEM::FilesystemNS
Directory::Directory(const Wrappers::Mpi& mpi,
const std::string& a_path,
if_already_exist if_already_exist_behaviour,
behaviour directory_behaviour,
const char* invoking_file, int invoking_line)
: mpi_(mpi),
if_already_exist_behaviour_(if_already_exist_behaviour)
directory_behaviour_(directory_behaviour)
{
std::ostringstream oconv;
oconv << a_path << "/Rank_";
......@@ -72,38 +72,59 @@ namespace MoReFEM::FilesystemNS
// - Root processor asks whether the directories must be overwritten or not. If 'no', a GracefulExit occurs.
// - Then root processor must tell the other processors to remove the directories.
// All the other policies may be handled without interprocessor communication.
if (if_already_exist_behaviour_ == if_already_exist::ask)
if (directory_behaviour_ == behaviour::ask)
CollectAnswer(invoking_file, invoking_line);
// At this point, each rank may do its own bidding.
if (Folder::DoExist(path_))
{
switch(if_already_exist_behaviour_)
switch(directory_behaviour_)
{
case if_already_exist::ask:
case if_already_exist::overwrite:
case behaviour::ask:
case behaviour::overwrite:
Folder::Remove(path_, invoking_file, invoking_line);
assert(!Folder::DoExist(path_));
Folder::Create(path_, invoking_file, invoking_line);
break;
case if_already_exist::ignore:
case behaviour::ignore:
break;
case if_already_exist::quit:
case behaviour::quit:
{
std::cout << "Directory '" << path_ << "' already exists; an abortion of the program is therefore "
"scheduled." << std::endl;
throw ExceptionNS::GracefulExit(invoking_file, invoking_line);
}
case behaviour::read:
// Do nothing: we expects it to exist!
break;
}
}
else
Folder::Create(path_, invoking_file, invoking_line);
{
switch(directory_behaviour_)
{
case behaviour::ask:
case behaviour::overwrite:
case behaviour::ignore:
case behaviour::quit:
Folder::Create(path_, invoking_file, invoking_line);
break;
case behaviour::read:
if (!Folder::DoExist(path_))
{
std::ostringstream oconv;
oconv << "Directory '" << path_ << "' was expected to exist and could not be found.";
throw Exception(oconv.str(), __FILE__, __LINE__);
}
break;
}
}
}
void Directory::CollectAnswer(const char* invoking_file, int invoking_line) const
{
assert(if_already_exist_behaviour_ == if_already_exist::ask);
assert(directory_behaviour_ == behaviour::ask);
decltype(auto) mpi = GetMpi();
......
......@@ -45,7 +45,7 @@ namespace MoReFEM::FilesystemNS
/*!
* \brief Enum class to determine what to do when a directory already exists.
* \class doxygen_hide_directory_behaviour_desc
*
* - overwrite: Remove the pre-existing one and recreate it.
* - ask: Ask the end user if he wants to override or not. If he chooses not to do so, the program ends.
......@@ -53,18 +53,36 @@ namespace MoReFEM::FilesystemNS
* communicate with stdin).
* - quit: Quit the program if the directory exists.
* - ignore: Do not create the directory and use the existing one (including possible previous content).
* - read: this mode expects the directory to exist and throws an exception otherwise.
*/
enum class if_already_exist
/*!
* \brief Enum class to determine how to handle the case
*
* \copydoc doxygen_hide_directory_behaviour_desc
*/
enum class behaviour
{
overwrite,
ask,
quit,
ignore
ignore,
read
};
/*!
* \class doxygen_hide_directory_behaviour_param
*
* \param[in] directory_behaviour Behaviour of the directory, among:
*
* \copydoc doxygen_hide_directory_behaviour_desc
*/
/*!
* \brief Class to manage properly creation if needed of directory.
* \brief Class to manage directories and ensure they behave as expected (check path already exists or if not
* whether it should create it or not, etc...)
*
*/
class Directory
......@@ -79,15 +97,29 @@ namespace MoReFEM::FilesystemNS
* \brief Constructor.
*
* \copydoc doxygen_hide_invoking_file_and_line
* \copydoc doxygen_hide_mpi_param
* \copydoc doxygen_hide_directory_behaviour_param
* \param[in] path Unix path of the directory.
*/
explicit Directory(const Wrappers::Mpi& mpi,
const std::string& path,
if_already_exist if_already_exist_behaviour,
behaviour directory_behaviour,
const char* invoking_file, int invoking_line);
/*!
* \brief Constructor of a \a Directory which is a subdirectory on an already existing \a Directory.
*
* \param[in] parent_directory The directory into which the new one is created (or read - depends on behaviour).
* The constructed directory takes the same attributes than its parent directory - except obviously for the path.
* \param[in] subdirectory Name of the subdirectory relative to \a parent_directory.
* \copydoc doxygen_hide_invoking_file_and_line
*
* \tparam StringT Type of \a subdirectory, which may actually be anything for which operator<< has been
* overloaded (avoid nonetheless values with spaces inside...)
*/
template<class StringT>
explicit Directory(const Directory& directory,
explicit Directory(const Directory& parent_directory,
const StringT& subdirectory,
const char* invoking_file, int invoking_line);
......@@ -108,26 +140,42 @@ namespace MoReFEM::FilesystemNS
///@}
//! Get the underlying Unix path.
const std::string& GetPath() const noexcept;
//! Conversion operator which does the same as \a GetPath().
operator const std::string& () const noexcept;
private:
//!
/*!
* \brief Helper method used in both constructors.
*
* \copydoc doxygen_hide_invoking_file_and_line
*/
void Construct(const char* invoking_file, int invoking_line) const;
/*!
* \brief Helper method for the 'ask' behaviour.
*
* This behaviour requires inter-processor communication: each rank must tell root processor whether the
* directory already exist or not, and if some do root processor must ask the user what to do. Then
* it musts transmit back answers to each rank, which then must take action.
*
* \copydoc doxygen_hide_invoking_file_and_line
*/
void CollectAnswer(const char* invoking_file, int invoking_line) const;
//!
//! Accessor to Mpi object.
const Wrappers::Mpi& GetMpi() const noexcept;
//!
if_already_exist GetIfAlreadyExistBehaviour() const noexcept;
//! Returns the behaviour.
behaviour GetBehaviour() const noexcept;
//! For root processor only: returns the path with a wildcard instead of the rank number. Just for printing
//! the message on screen.
const std::string& GetWildcardPath() const noexcept;
private:
......@@ -138,11 +186,17 @@ namespace MoReFEM::FilesystemNS
//! Generic path with wildcard instead of rank. Only filled for root processor.
std::string wildcard_path_;
//!
//! \a Mpi object.
const Wrappers::Mpi& mpi_;
//! What to do if the directory already exists.
if_already_exist if_already_exist_behaviour_;
/*!
* \brief What to do at the construction of the \a Directory object.
*
* Options are:
*
* \copydoc doxygen_hide_directory_behaviour_desc
*/
behaviour directory_behaviour_;
};
......
......@@ -22,7 +22,7 @@ namespace MoReFEM::FilesystemNS
const char* invoking_file, int invoking_line)
: Directory(directory.GetMpi(),
directory.GetPath(),
if_already_exist::ignore, // By definition this directory should already exists!
behaviour::ignore, // By definition this directory should already exists!
invoking_file, invoking_line)
{
std::ostringstream oconv;
......@@ -38,7 +38,7 @@ namespace MoReFEM::FilesystemNS
path_ = oconv.str();
// Use the same policy as for the parent directoru.
if_already_exist_behaviour_ = directory.GetIfAlreadyExistBehaviour();
directory_behaviour_ = directory.GetBehaviour();
Construct(invoking_file, invoking_line);
}
......@@ -56,9 +56,9 @@ namespace MoReFEM::FilesystemNS
}
inline if_already_exist Directory::GetIfAlreadyExistBehaviour() const noexcept
inline behaviour Directory::GetBehaviour() const noexcept
{
return if_already_exist_behaviour_;
return directory_behaviour_;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment