feat(symlinks): make recursive links explicit

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2023-02-08 18:39:17 -07:00
parent 5978882378
commit 1bed7754e0
7 changed files with 59 additions and 7 deletions

View File

@ -103,6 +103,11 @@ bool InstanceCopyPrefs::isUseHardLinksEnabled() const
return useHardLinks; return useHardLinks;
} }
bool InstanceCopyPrefs::isLinkRecursivelyEnabled() const
{
return linkRecursively;
}
bool InstanceCopyPrefs::isDontLinkSavesEnabled() const bool InstanceCopyPrefs::isDontLinkSavesEnabled() const
{ {
return dontLinkSaves; return dontLinkSaves;
@ -154,6 +159,11 @@ void InstanceCopyPrefs::enableLinkFiles(bool b)
linkFiles = b; linkFiles = b;
} }
void InstanceCopyPrefs::enableLinkRecursively(bool b)
{
linkRecursively = b;
}
void InstanceCopyPrefs::enableUseHardLinks(bool b) void InstanceCopyPrefs::enableUseHardLinks(bool b)
{ {
useHardLinks = b; useHardLinks = b;

View File

@ -20,6 +20,7 @@ struct InstanceCopyPrefs {
[[nodiscard]] bool isCopyModsEnabled() const; [[nodiscard]] bool isCopyModsEnabled() const;
[[nodiscard]] bool isCopyScreenshotsEnabled() const; [[nodiscard]] bool isCopyScreenshotsEnabled() const;
[[nodiscard]] bool isLinkFilesEnabled() const; [[nodiscard]] bool isLinkFilesEnabled() const;
[[nodiscard]] bool isLinkRecursivelyEnabled() const;
[[nodiscard]] bool isUseHardLinksEnabled() const; [[nodiscard]] bool isUseHardLinksEnabled() const;
[[nodiscard]] bool isDontLinkSavesEnabled() const; [[nodiscard]] bool isDontLinkSavesEnabled() const;
// Setters // Setters
@ -32,6 +33,7 @@ struct InstanceCopyPrefs {
void enableCopyMods(bool b); void enableCopyMods(bool b);
void enableCopyScreenshots(bool b); void enableCopyScreenshots(bool b);
void enableLinkFiles(bool b); void enableLinkFiles(bool b);
void enableLinkRecursively(bool b);
void enableUseHardLinks(bool b); void enableUseHardLinks(bool b);
void enableDontLinkSaves(bool b); void enableDontLinkSaves(bool b);
@ -45,6 +47,7 @@ struct InstanceCopyPrefs {
bool copyMods = true; bool copyMods = true;
bool copyScreenshots = true; bool copyScreenshots = true;
bool linkFiles = false; bool linkFiles = false;
bool linkRecursively = false;
bool useHardLinks = false; bool useHardLinks = false;
bool dontLinkSaves = false; bool dontLinkSaves = false;
}; };

View File

@ -12,9 +12,11 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP
QString filters = prefs.getSelectedFiltersAsRegex(); QString filters = prefs.getSelectedFiltersAsRegex();
m_useLinks = prefs.isLinkFilesEnabled(); m_useLinks = prefs.isLinkFilesEnabled();
m_useHardLinks = prefs.isUseHardLinksEnabled(); m_linkRecursively = prefs.isLinkRecursivelyEnabled();
m_copySaves = prefs.isDontLinkSavesEnabled() && prefs.isCopySavesEnabled(); m_useHardLinks = prefs.isLinkRecursivelyEnabled() && prefs.isUseHardLinksEnabled();
m_copySaves = prefs.isLinkRecursivelyEnabled() && prefs.isDontLinkSavesEnabled() && prefs.isCopySavesEnabled();
if (!filters.isEmpty()) if (!filters.isEmpty())
{ {
@ -32,7 +34,7 @@ void InstanceCopyTask::executeTask()
auto copySaves = [&](){ auto copySaves = [&](){
FS::copy savesCopy(FS::PathCombine(m_origInstance->instanceRoot(), "saves") , FS::PathCombine(m_stagingPath, "saves")); FS::copy savesCopy(FS::PathCombine(m_origInstance->instanceRoot(), "saves") , FS::PathCombine(m_stagingPath, "saves"));
savesCopy.followSymlinks(false); savesCopy.followSymlinks(true);
return savesCopy(); return savesCopy();
}; };
@ -40,7 +42,7 @@ void InstanceCopyTask::executeTask()
m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this, copySaves]{ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this, copySaves]{
if (m_useLinks) { if (m_useLinks) {
FS::create_link folderLink(m_origInstance->instanceRoot(), m_stagingPath); FS::create_link folderLink(m_origInstance->instanceRoot(), m_stagingPath);
folderLink.linkRecursively(true).useHardLinks(m_useHardLinks).matcher(m_matcher.get()); folderLink.linkRecursively(m_linkRecursively).useHardLinks(m_useHardLinks).matcher(m_matcher.get());
bool there_were_errors = false; bool there_were_errors = false;

View File

@ -32,5 +32,6 @@ private:
bool m_keepPlaytime; bool m_keepPlaytime;
bool m_useLinks = false; bool m_useLinks = false;
bool m_useHardLinks = false; bool m_useHardLinks = false;
bool m_copySaves = true; bool m_copySaves = false;
bool m_linkRecursively = false;
}; };

View File

@ -87,6 +87,7 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
ui->copyScreenshotsCheckbox->setChecked(m_selectedOptions.isCopyScreenshotsEnabled()); ui->copyScreenshotsCheckbox->setChecked(m_selectedOptions.isCopyScreenshotsEnabled());
ui->linkFilesGroup->setChecked(m_selectedOptions.isLinkFilesEnabled()); ui->linkFilesGroup->setChecked(m_selectedOptions.isLinkFilesEnabled());
ui->recursiveLinkCheckbox->setChecked(m_selectedOptions.isLinkRecursivelyEnabled());
ui->hardLinksCheckbox->setChecked(m_selectedOptions.isUseHardLinksEnabled()); ui->hardLinksCheckbox->setChecked(m_selectedOptions.isUseHardLinksEnabled());
ui->dontLinkSavesCheckbox->setChecked(m_selectedOptions.isDontLinkSavesEnabled()); ui->dontLinkSavesCheckbox->setChecked(m_selectedOptions.isDontLinkSavesEnabled());
} }
@ -231,9 +232,22 @@ void CopyInstanceDialog::on_linkFilesGroup_toggled(bool checked)
m_selectedOptions.enableLinkFiles(checked); m_selectedOptions.enableLinkFiles(checked);
} }
void CopyInstanceDialog::on_recursiveLinkCheckbox_stateChanged(int state)
{
m_selectedOptions.enableLinkRecursively(state == Qt::Checked);
if (state != Qt::Checked) {
ui->hardLinksCheckbox->setChecked(false);
ui->dontLinkSavesCheckbox->setChecked(false);
}
}
void CopyInstanceDialog::on_hardLinksCheckbox_stateChanged(int state) void CopyInstanceDialog::on_hardLinksCheckbox_stateChanged(int state)
{ {
m_selectedOptions.enableUseHardLinks(state == Qt::Checked); m_selectedOptions.enableUseHardLinks(state == Qt::Checked);
if (state == Qt::Checked && !ui->recursiveLinkCheckbox->isChecked()) {
ui->recursiveLinkCheckbox->setChecked(true);
}
} }
void CopyInstanceDialog::on_dontLinkSavesCheckbox_stateChanged(int state) void CopyInstanceDialog::on_dontLinkSavesCheckbox_stateChanged(int state)

View File

@ -56,6 +56,7 @@ slots:
void on_copyModsCheckbox_stateChanged(int state); void on_copyModsCheckbox_stateChanged(int state);
void on_copyScreenshotsCheckbox_stateChanged(int state); void on_copyScreenshotsCheckbox_stateChanged(int state);
void on_linkFilesGroup_toggled(bool checked); void on_linkFilesGroup_toggled(bool checked);
void on_recursiveLinkCheckbox_stateChanged(int state);
void on_hardLinksCheckbox_stateChanged(int state); void on_hardLinksCheckbox_stateChanged(int state);
void on_dontLinkSavesCheckbox_stateChanged(int state); void on_dontLinkSavesCheckbox_stateChanged(int state);

View File

@ -209,6 +209,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="advancedOptionsLabel">
<property name="text">
<string>Advanced Copy Options</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item> <item>
<layout class="QVBoxLayout" name="copyModeLayout"> <layout class="QVBoxLayout" name="copyModeLayout">
<item> <item>
@ -229,8 +239,18 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QVBoxLayout" name="linkOptionsLayout"> <layout class="QVBoxLayout" name="linkOptionsLayout">
<item>
<widget class="QCheckBox" name="recursiveLinkCheckbox">
<property name="text">
<string>Link files recursively</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="hardLinksCheckbox"> <widget class="QCheckBox" name="hardLinksCheckbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Use hard links instead of symbolic links</string> <string>Use hard links instead of symbolic links</string>
</property> </property>
@ -242,7 +262,7 @@
<item> <item>
<widget class="QCheckBox" name="dontLinkSavesCheckbox"> <widget class="QCheckBox" name="dontLinkSavesCheckbox">
<property name="toolTip"> <property name="toolTip">
<string>If "copy saves" is selected world save data will be copied instead of linked and thus not shared between instances.</string> <string>If &quot;copy saves&quot; is selected world save data will be copied instead of linked and thus not shared between instances.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Don't link saves</string> <string>Don't link saves</string>
@ -283,8 +303,9 @@
<tabstop>copyResPacksCheckbox</tabstop> <tabstop>copyResPacksCheckbox</tabstop>
<tabstop>copyModsCheckbox</tabstop> <tabstop>copyModsCheckbox</tabstop>
<tabstop>linkFilesGroup</tabstop> <tabstop>linkFilesGroup</tabstop>
<tabstop>recursiveLinkCheckbox</tabstop>
<tabstop>hardLinksCheckbox</tabstop> <tabstop>hardLinksCheckbox</tabstop>
<tabstop>linkWorldsCheckbox</tabstop> <tabstop>dontLinkSavesCheckbox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>