Add WorkingCopyMode::Cleanup

This commit is contained in:
Martchus 2022-01-08 23:35:01 +01:00
parent ef37ae437c
commit a8fddad804
3 changed files with 32 additions and 15 deletions

View File

@ -114,8 +114,8 @@ set(META_APP_AUTHOR "Martchus")
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}") set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parser, IO and conversion utilities") set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parser, IO and conversion utilities")
set(META_VERSION_MAJOR 5) set(META_VERSION_MAJOR 5)
set(META_VERSION_MINOR 11) set(META_VERSION_MINOR 12)
set(META_VERSION_PATCH 4) set(META_VERSION_PATCH 0)
# find required 3rd party libraries # find required 3rd party libraries
include(3rdParty) include(3rdParty)

View File

@ -9,6 +9,7 @@
#include "../misc/parseerror.h" #include "../misc/parseerror.h"
#include <cerrno> #include <cerrno>
#include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
@ -293,10 +294,11 @@ string TestApplication::workingCopyPathAs(
const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode) const const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode) const
{ {
// ensure working directory is present // ensure working directory is present
auto workingCopyPath = std::string();
if (!dirExists(m_workingDir) && !makeDir(m_workingDir)) { if (!dirExists(m_workingDir) && !makeDir(m_workingDir)) {
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": can't create working directory \"" cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": can't create working directory \""
<< m_workingDir << "\"." << Phrases::EndFlush; << m_workingDir << "\"." << Phrases::EndFlush;
return string(); return workingCopyPath;
} }
// ensure subdirectory exists // ensure subdirectory exists
@ -319,26 +321,37 @@ string TestApplication::workingCopyPathAs(
// fail otherwise // fail otherwise
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeWorkingCopyPath << "\": can't create directory \"" cerr << Phrases::Error << "Unable to create working copy for \"" << relativeWorkingCopyPath << "\": can't create directory \""
<< currentLevel << "\" (inside working directory)." << Phrases::EndFlush; << currentLevel << "\" (inside working directory)." << Phrases::EndFlush;
return string(); return workingCopyPath;
} }
} }
// just return the path if we don't want to actually create a copy workingCopyPath = m_workingDir + relativeWorkingCopyPath;
if (mode == WorkingCopyMode::NoCopy) { switch (mode) {
return m_workingDir + relativeWorkingCopyPath; case WorkingCopyMode::NoCopy:
// just return the path if we don't want to actually create a copy
return workingCopyPath;
case WorkingCopyMode::Cleanup:
// ensure the file does not exist in cleanup mode
if (std::remove(workingCopyPath.data()) != 0 && errno != ENOENT) {
const auto error = std::strerror(errno);
cerr << Phrases::Error << "Unable to delete \"" << workingCopyPath << "\": " << error << Phrases::EndFlush;
workingCopyPath.clear();
}
return workingCopyPath;
default:;
} }
// copy the file // copy the file
const auto origFilePath(testFilePath(relativeTestFilePath)); const auto origFilePath = testFilePath(relativeTestFilePath);
auto workingCopyPath(m_workingDir + relativeWorkingCopyPath);
size_t workingCopyPathAttempt = 0; size_t workingCopyPathAttempt = 0;
NativeFileStream origFile, workingCopy; NativeFileStream origFile, workingCopy;
origFile.open(origFilePath, ios_base::in | ios_base::binary); origFile.open(origFilePath, ios_base::in | ios_base::binary);
if (origFile.fail()) { if (origFile.fail()) {
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath
<< "\": an IO error occurred when opening original file \"" << origFilePath << "\"." << Phrases::EndFlush; << "\": an IO error occurred when opening original file \"" << origFilePath << "\"." << Phrases::EndFlush;
cerr << "error: " << strerror(errno) << endl; cerr << "error: " << std::strerror(errno) << endl;
return string(); workingCopyPath.clear();
return workingCopyPath;
} }
workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc); workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc);
while (workingCopy.fail() && fileSystemItemExists(workingCopyPath)) { while (workingCopy.fail() && fileSystemItemExists(workingCopyPath)) {
@ -351,7 +364,8 @@ string TestApplication::workingCopyPathAs(
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath
<< "\": an IO error occurred when opening target file \"" << workingCopyPath << "\"." << Phrases::EndFlush; << "\": an IO error occurred when opening target file \"" << workingCopyPath << "\"." << Phrases::EndFlush;
cerr << "error: " << strerror(errno) << endl; cerr << "error: " << strerror(errno) << endl;
return string(); workingCopyPath.clear();
return workingCopyPath;
} }
workingCopy << origFile.rdbuf(); workingCopy << origFile.rdbuf();
workingCopy.close(); workingCopy.close();
@ -362,7 +376,8 @@ string TestApplication::workingCopyPathAs(
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": "; cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": ";
if (origFile.fail()) { if (origFile.fail()) {
cerr << "an IO error occurred when reading original file \"" << origFilePath << "\""; cerr << "an IO error occurred when reading original file \"" << origFilePath << "\"";
return string(); workingCopyPath.clear();
return workingCopyPath;
} }
if (workingCopy.fail()) { if (workingCopy.fail()) {
if (origFile.fail()) { if (origFile.fail()) {
@ -371,7 +386,8 @@ string TestApplication::workingCopyPathAs(
cerr << " an IO error occurred when writing to target file \"" << workingCopyPath << "\"."; cerr << " an IO error occurred when writing to target file \"" << workingCopyPath << "\".";
} }
cerr << "error: " << strerror(errno) << endl; cerr << "error: " << strerror(errno) << endl;
return string(); workingCopyPath.clear();
return workingCopyPath;
} }
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX

View File

@ -15,7 +15,8 @@ namespace CppUtilities {
*/ */
enum class WorkingCopyMode { enum class WorkingCopyMode {
CreateCopy, /**< a working copy of the test file is created */ CreateCopy, /**< a working copy of the test file is created */
NoCopy /**< only the directory for the working copy is created but not the test file itself */ NoCopy, /**< only the directory for the working copy is created but not the test file itself */
Cleanup, /**< the directory for the working copy is created if needed or a previously existing file is deleted */
}; };
class CPP_UTILITIES_EXPORT TestApplication { class CPP_UTILITIES_EXPORT TestApplication {