Sfoglia il codice sorgente

Fixes #4 Copy files
Fixes #3 Copy dirs
Fixes #2 Overwrite files

isundil 9 mesi fa
parent
commit
737a4c3e1f

+ 14 - 0
Engine/Engine.cpp

@@ -23,11 +23,14 @@ namespace craftlab::fakeraid
 
 		void RemoveFiles(const std::vector<std::string>& paths) const override;
 		void RemoveDirs(const std::vector<std::string>& paths) const override;
+		void CopyItems(const std::vector<CopyInstruction>& itemsToCopy) const override;
 
 	private:
 		FileAndSumList ListFiles(const std::string& root, int repositoryIndex);
 		std::string BuildCurrentDirPath(const std::string& root ="") const;
 
+		void CopyItem(const CopyInstruction& dst) const;
+
 		const std::vector<std::string> rootPaths;
 		std::deque<std::string> currentDir;
 	};
@@ -171,6 +174,17 @@ void Engine::RemoveDirs(const std::vector<std::string>& paths) const
 		std::filesystem::remove_all(path);
 }
 
+void Engine::CopyItem(const IEngine::CopyInstruction& item) const
+{
+	std::filesystem::copy(item.source, item.destination, std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive);
+}
+
+void Engine::CopyItems(const std::vector<IEngine::CopyInstruction>& paths) const
+{
+	for (const CopyInstruction& item: paths)
+		CopyItem(item);
+}
+
 IEngine* EngineManager::Open(const std::vector<std::string>& path)
 {
 	return new Engine(path);

+ 10 - 0
Engine/IEngine.h

@@ -19,8 +19,18 @@ namespace craftlab::fakeraid
 		virtual FileAndSumListByRepositoryIndex ListFiles() =0;
 		virtual void Cd(const std::string& dirName) =0;
 
+		struct CopyInstruction
+		{
+			CopyInstruction() =default;
+			CopyInstruction(const std::string& src, const std::string& dst): source(src), destination(dst) {}
+
+			std::string source;
+			std::string destination;
+		};
+
 		virtual void RemoveFiles(const std::vector<std::string>& paths) const = 0;
 		virtual void RemoveDirs(const std::vector<std::string>& paths) const = 0;
+		virtual void CopyItems(const std::vector<CopyInstruction>& itemsToCopy) const =0;
 	};
 
 	class ENGINEAPI_EXPORT EngineManager

+ 9 - 0
fakeRaid/conflictItemWidget.cpp

@@ -44,6 +44,15 @@ ConflictItemWidget::Action ConflictItemWidget::GetAction() const
 	return currentAction;
 }
 
+int ConflictItemWidget::GetVersionToUse() const
+{
+	if (currentAction == Action::Copy)
+		return 1;
+	if (currentAction != Action::UseVersion)
+		return -1;
+	return qvariant_cast<int>(ui->ddUseVersion->currentData());
+}
+
 std::vector<int> ConflictItemWidget::versionExistsToVersionNumber(const std::vector<bool> exists)
 {
 	std::vector<int> versionNo;

+ 1 - 0
fakeRaid/conflictItemWidget.h

@@ -29,6 +29,7 @@ namespace craftlab::fakeraid
 		Action GetAction() const;
 		void SetAction(Action&& action);
 		std::string GetFileName() const;
+		int GetVersionToUse() const;
 
 	signals:
 		void ActionChanged();

+ 59 - 19
fakeRaid/conflictModal.cpp

@@ -62,6 +62,43 @@ void ConflictModal::UpdateProcessButtonStatus()
 	ui->buttonProcess->setEnabled(!pending);
 }
 
+void ConflictModal::ComputeRemovalProcess(const std::string& filename)
+{
+	auto differentFilesIter = diffResult->differentFiles.find(filename);
+	auto missingFilesIter = diffResult->missingFiles.find(filename);
+	auto missingDirsIter = diffResult->missingDirs.find(filename);
+
+	if (differentFilesIter != diffResult->differentFiles.end())
+	{
+		for (int i = 0; i < differentFilesIter->second.size(); ++i)
+			if (differentFilesIter->second[i] > 0)
+				processItems.filesToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), filename));
+	}
+	else if (missingFilesIter != diffResult->missingFiles.end())
+	{
+		for (int i = 0; i < missingFilesIter->second.size(); ++i)
+			if (!missingFilesIter->second[i])
+				processItems.filesToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), filename));
+	}
+	else if (missingDirsIter != diffResult->missingDirs.end())
+	{
+		for (int i = 0; i < missingDirsIter->second.size(); ++i)
+			if (!missingDirsIter->second[i])
+				processItems.dirsToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), filename));
+	}
+}
+
+void ConflictModal::ComputeCopyProcess(const std::string& filename, const std::vector<int> foundVersions, int versionToUse)
+{
+	assert(versionToUse >= 0);
+	assert(std::find(foundVersions.begin(), foundVersions.end(), versionToUse) != foundVersions.end());
+
+	const std::string sourcePath = mergePath(rootPaths[std::distance(foundVersions.begin(), std::find(foundVersions.begin(), foundVersions.end(), versionToUse))], QDir::separator(), filename);
+	for (int i = 0; i < foundVersions.size(); ++i)
+		if (foundVersions[i] != versionToUse)
+			processItems.itemsToCopy.push_back(IEngine::CopyInstruction(sourcePath, mergePath(rootPaths[i], QDir::separator(), filename)));
+}
+
 DiffResult ConflictModal::ComputeOutcome(const std::vector<std::string>& rootPaths)
 {
 	DiffResult result;
@@ -71,28 +108,30 @@ DiffResult ConflictModal::ComputeOutcome(const std::vector<std::string>& rootPat
 	for (const ConflictItemWidget* i : conflicts)
 	{
 		FileAndSum originalFile = diffResult->FileList.at(i->GetFileName());
-		if (i->GetAction() == ConflictItemWidget::Action::Copy || i->GetAction() == ConflictItemWidget::Action::UseVersion)
+		if (i->GetAction() == ConflictItemWidget::Action::Copy)
+		{
 			result.correctFiles.push_back(originalFile);
+			std::vector<int> versions;
+			if (diffResult->missingFiles.find(originalFile.fileName) != diffResult->missingFiles.end())
+				std::transform(diffResult->missingFiles[originalFile.fileName].begin(),
+					diffResult->missingFiles[originalFile.fileName].end(),
+					std::back_inserter(versions),
+					[](bool v) { return v ? 0 : 1; });
+			else
+				std::transform(diffResult->missingDirs[originalFile.fileName].begin(),
+					diffResult->missingDirs[originalFile.fileName].end(),
+					std::back_inserter(versions),
+					[](bool v) { return v ? 0 : 1; });
+			ComputeCopyProcess(originalFile.fileName, versions, i->GetVersionToUse());
+		}
+		else if (i->GetAction() == ConflictItemWidget::Action::UseVersion)
+		{
+			result.correctFiles.push_back(originalFile);
+			ComputeCopyProcess(originalFile.fileName, diffResult->differentFiles[originalFile.fileName], i->GetVersionToUse());
+		}
 		else if (i->GetAction() == ConflictItemWidget::Action::Remove)
 		{
-			if (diffResult->differentFiles.find(originalFile.fileName) != diffResult->differentFiles.end())
-			{
-				for (int i = 0; i < diffResult->differentFiles[originalFile.fileName].size(); ++i)
-					if (diffResult->differentFiles[originalFile.fileName][i] > 0)
-						processItems.filesToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), originalFile.fileName));
-			}
-			else if (diffResult->missingFiles.find(originalFile.fileName) != diffResult->missingFiles.end())
-			{
-				for (int i = 0; i < diffResult->missingFiles[originalFile.fileName].size(); ++i)
-					if (!diffResult->missingFiles[originalFile.fileName][i])
-						processItems.filesToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), originalFile.fileName));
-			}
-			else if (diffResult->missingDirs.find(originalFile.fileName) != diffResult->missingDirs.end())
-			{
-				for (int i = 0; i < diffResult->missingDirs[originalFile.fileName].size(); ++i)
-					if (!diffResult->missingDirs[originalFile.fileName][i])
-						processItems.dirsToRemove.push_back(mergePath(rootPaths[i], QDir::separator(), originalFile.fileName));
-			}
+			ComputeRemovalProcess(originalFile.fileName);
 		}
 		else if (i->GetAction() == ConflictItemWidget::Action::Ignore ||
 			i->GetAction() == ConflictItemWidget::Action::Undefined)
@@ -124,6 +163,7 @@ DiffResult ConflictModal::Display(const IEngine& engine, const DiffResult& diffR
 
 	engine.RemoveFiles(dialog.processItems.filesToRemove);
 	engine.RemoveDirs(dialog.processItems.dirsToRemove);
+	engine.CopyItems(dialog.processItems.itemsToCopy);
 
 	return result;
 }

+ 3 - 0
fakeRaid/conflictModal.h

@@ -33,11 +33,14 @@ namespace craftlab::fakeraid
 		ConflictModal(const std::vector<std::string>& rootPaths, const DiffResult& diffResult);
 
 		void AddConflictingFile(ConflictItemWidget* widget);
+		void ComputeRemovalProcess(const std::string& fileName);
+		void ComputeCopyProcess(const std::string& filename, const std::vector<int> foundVersion, int versionToUse);
 
 		struct ProcessItems
 		{
 			std::vector<std::string> filesToRemove;
 			std::vector<std::string> dirsToRemove;
+			std::vector<IEngine::CopyInstruction> itemsToCopy;
 		};
 
 		ProcessItems processItems;