Fix pack updating & Modrinth overrides

The mechanism that both pack updating and Modrinth overrides use utilize std::filesystem::copy, which with GCC's libstdc++ has a bug on Windows where `overwrite_existing` isn't obeyed. In addition, made it clear what `overrideFolder` does by renaming it and rewriting an error message.
This commit is contained in:
jdp_ 2023-05-07 01:06:30 -04:00
parent 2a9bb95e1f
commit 4eb9085e71
4 changed files with 24 additions and 19 deletions

View File

@ -414,24 +414,29 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
#endif #endif
} }
bool overrideFolder(QString overwritten_path, QString override_path) bool mergeFolders(QString dstpath, QString srcpath)
{ {
using copy_opts = fs::copy_options; std::error_code ec;
fs::path fullSrcPath = srcpath.toStdString();
if (!FS::ensureFolderPathExists(overwritten_path)) fs::path fullDstPath = dstpath.toStdString();
return false; for (auto& entry : fs::recursive_directory_iterator(fullSrcPath))
{
std::error_code err; fs::path relativeChild = fs::relative(entry, fullSrcPath);
fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing; if (entry.is_directory())
if (!fs::exists(fullDstPath / relativeChild))
fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err); fs::create_directory(fullDstPath / relativeChild);
if (entry.is_regular_file())
if (err) { {
qCritical() << QString("Failed to apply override from %1 to %2").arg(override_path, overwritten_path); fs::path childDst = fullDstPath / relativeChild;
qCritical() << "Reason:" << QString::fromStdString(err.message()); if (fs::exists(childDst))
fs::remove(childDst);
fs::copy(entry, childDst, fs::copy_options::none, ec);
if (ec.value() != 0)
qCritical() << QString("File copy failed with: %1. File was %2 -> %3").arg(QString::fromStdString(ec.message()), entry.path().c_str(), childDst.c_str());
}
} }
return err.value() == 0; return ec.value() == 0;
} }
} }

View File

@ -154,5 +154,5 @@ QString getDesktopDir();
// Overrides one folder with the contents of another, preserving items exclusive to the first folder // Overrides one folder with the contents of another, preserving items exclusive to the first folder
// Equivalent to doing QDir::rename, but allowing for overrides // Equivalent to doing QDir::rename, but allowing for overrides
bool overrideFolder(QString overwritten_path, QString override_path); bool mergeFolders(QString dstpath, QString srcpath);
} }

View File

@ -904,7 +904,7 @@ bool InstanceList::commitStagedInstance(const QString& path, InstanceName const&
QString destination = FS::PathCombine(m_instDir, instID); QString destination = FS::PathCombine(m_instDir, instID);
if (should_override) { if (should_override) {
if (!FS::overrideFolder(destination, path)) { if (!FS::mergeFolders(destination, path)) {
qWarning() << "Failed to override" << path << "to" << destination; qWarning() << "Failed to override" << path << "to" << destination;
return false; return false;
} }

View File

@ -195,8 +195,8 @@ bool ModrinthCreationTask::createInstance()
Override::createOverrides("client-overrides", parent_folder, client_override_path); Override::createOverrides("client-overrides", parent_folder, client_override_path);
// Apply the overrides // Apply the overrides
if (!FS::overrideFolder(mcPath, client_override_path)) { if (!FS::mergeFolders(mcPath, client_override_path)) {
setError(tr("Could not rename the client overrides folder:\n") + "client overrides"); setError(tr("Could not overwrite / create new files:\n") + "client overrides");
return false; return false;
} }
} }