diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index d5f6ea2ee8..7752c04213 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -98,6 +98,11 @@ bool Delete(const fs::path& path) { bool CreateDir(const fs::path& path) { LOG_TRACE(Common_Filesystem, "directory {}", path.string()); + if (Exists(path)) { + LOG_DEBUG(Common_Filesystem, "path exists {}", path.string()); + return true; + } + std::error_code ec; const bool success = fs::create_directory(path, ec); @@ -109,20 +114,41 @@ bool CreateDir(const fs::path& path) { return true; } -bool CreateFullPath(const fs::path& path) { +bool CreateDirs(const fs::path& path) { LOG_TRACE(Common_Filesystem, "path {}", path.string()); + if (Exists(path)) { + LOG_DEBUG(Common_Filesystem, "path exists {}", path.string()); + return true; + } + std::error_code ec; const bool success = fs::create_directories(path, ec); if (!success) { - LOG_ERROR(Common_Filesystem, "Unable to create full path: {}", ec.message()); + LOG_ERROR(Common_Filesystem, "Unable to create directories: {}", ec.message()); return false; } return true; } +bool CreateFullPath(const fs::path& path) { + LOG_TRACE(Common_Filesystem, "path {}", path); + + // Removes trailing slashes and turns any '\' into '/' + const auto new_path = SanitizePath(path.string(), DirectorySeparator::ForwardSlash); + + if (new_path.rfind('.') == std::string::npos) { + // The path is a directory + return CreateDirs(new_path); + } else { + // The path is a file + // Creates directory preceding the last '/' + return CreateDirs(new_path.substr(0, new_path.rfind('/'))); + } +} + bool Rename(const fs::path& src, const fs::path& dst) { LOG_TRACE(Common_Filesystem, "{} --> {}", src.string(), dst.string()); diff --git a/src/common/file_util.h b/src/common/file_util.h index c2ee7ca278..cf006cc9dd 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -54,8 +54,14 @@ enum class UserPath { // Returns true if successful, or path already exists. bool CreateDir(const std::filesystem::path& path); -// Creates the full path of path. Returns true on success -bool CreateFullPath(const std::filesystem::path& path); +// Create all directories in path +// Returns true if successful, or path already exists. +[[nodiscard("Directory creation can fail and must be tested")]] bool CreateDirs( + const std::filesystem::path& path); + +// Creates directories in path. Returns true on success. +[[deprecated("This function is deprecated, use CreateDirs")]] bool CreateFullPath( + const std::filesystem::path& path); // Deletes a given file at the path. // This will also delete empty directories.