| 62 | namespace openstudio { |
| 63 | namespace model { |
| 64 | bool replaceDir(const openstudio::path& sourceDir, const openstudio::path& destinationDir) { |
| 65 | bool result = true; |
| 66 | |
| 67 | // Path **must** exist for `canonical()` to work, `weakly_canonical()` doesn't require this |
| 68 | const auto src = openstudio::filesystem::weakly_canonical(sourceDir); |
| 69 | const auto dest = openstudio::filesystem::weakly_canonical(destinationDir); |
| 70 | |
| 71 | // If both are the same canonical paths, we do nothing |
| 72 | if (src == dest) { |
| 73 | LOG_FREE(Warn, "replaceDir", |
| 74 | "Refusing to copy directory '" << toString(sourceDir) << "' only itself '" << toString(destinationDir) << "' canonical path: '" |
| 75 | << toString(src) << "'"); |
| 76 | return true; // there is no error, just nothing to do |
| 77 | } |
| 78 | |
| 79 | // If the source dir doesn't exist, there's a problem |
| 80 | if (!openstudio::filesystem::exists(src) || !openstudio::filesystem::is_directory(src)) { |
| 81 | LOG_FREE(Error, "replaceDir", "Source directory does not exist: " << toString(src)); |
| 82 | return false; |
| 83 | } |
| 84 | |
| 85 | // If the dest dir exists, remove all entries in it |
| 86 | if (openstudio::filesystem::exists(dest)) { |
| 87 | if (openstudio::filesystem::is_directory(dest)) { |
| 88 | for (openstudio::filesystem::directory_iterator end_dir_it, it(dest); it != end_dir_it; ++it) { |
| 89 | openstudio::filesystem::path path = it->path(); |
| 90 | try { |
| 91 | openstudio::filesystem::remove_all(path); |
| 92 | } catch (const std::exception& e) { |
| 93 | LOG_FREE(Error, "replaceDir", "Error deleting: " << toString(path) << e.what()); |
| 94 | result = false; |
| 95 | } |
| 96 | } |
| 97 | } else { |
| 98 | LOG_FREE(Error, "replaceDir", "Destination exists and is not a directory, aborting: " << toString(dest)); |
| 99 | return false; |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | // Now we recreate it, and it must work! |
| 104 | if (!openstudio::filesystem::exists(dest)) { |
| 105 | try { |
| 106 | if (!openstudio::filesystem::create_directory(dest)) { |
| 107 | LOG_FREE(Error, "replaceDir", "Could not create destination directory: " << toString(dest)); |
| 108 | return false; |
| 109 | } |
| 110 | } catch (const std::exception& e) { |
| 111 | LOG_FREE(Error, "replaceDir", "Error creating directory: " << toString(dest) << e.what()); |
| 112 | return false; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | // Not using PathHelper's copyDirectory because we want clear log messages |
| 117 | for (const auto& dirEnt : openstudio::filesystem::directory_iterator{src}) { |
| 118 | const auto& srcFolderPath = dirEnt.path(); |
| 119 | const auto& relativeFolderPath = openstudio::filesystem::relative(srcFolderPath, src); |
| 120 | |
| 121 | try { |
no test coverage detected