Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/Progmasoft/Runner/TemporaryDirectory.cpp
diff options
context:
space:
mode:
authorLeitwolf2026-10-24 19:03:40 +0300
committerGitHub2026-10-24 19:03:40 +0300
commit4f1c759cffcb14bd6511e1d7c5fbace682e24f2d (patch)
tree415fe5d48a5b48650bba3747beaf245d727c4f61 /src/Progmasoft/Runner/TemporaryDirectory.cpp
parent83c6fc3ac13abe83fa39f7b5f8559ccaf4412233 (diff)
parent622188f9c08e4af35941c146979883ed4882410e (diff)
downloadcatch3-4f1c759cffcb14bd6511e1d7c5fbace682e24f2d.tar.gz
Merge pull request #15 from Progmasoft/feature/catch3-runner
Replace Catch2's runner with the Catch3 runner
Diffstat (limited to 'src/Progmasoft/Runner/TemporaryDirectory.cpp')
-rw-r--r--src/Progmasoft/Runner/TemporaryDirectory.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/Progmasoft/Runner/TemporaryDirectory.cpp b/src/Progmasoft/Runner/TemporaryDirectory.cpp
new file mode 100644
index 00000000..5b2ce5fa
--- /dev/null
+++ b/src/Progmasoft/Runner/TemporaryDirectory.cpp
@@ -0,0 +1,111 @@
+// Copyright (c) 2026 Progmasoft.
+// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1
+#include "TemporaryDirectory.hpp"
+
+#include "Process.hpp"
+
+#include <Progmasoft/Catch3/Runner.hpp>
+
+#include <cstdlib>
+#include <filesystem>
+#include <mutex>
+#include <system_error>
+
+namespace Progmasoft::Catch3::Runner
+{
+ namespace
+ {
+ constexpr std::array<const char *, 3> kVariables = {
+ "TMPDIR", "TMP", "TEMP"};
+
+ std::mutex &
+ CurrentMutex()
+ {
+ static auto *mutex = new std::mutex();
+ return *mutex;
+ }
+
+ std::string &
+ Current()
+ {
+ static auto *directory = new std::string();
+ return *directory;
+ }
+
+ void
+ SetVariable(const char *name, const std::optional<std::string> &value)
+ {
+#if defined(_WIN32)
+ // An empty value removes the variable.
+ _putenv_s(name, value ? value->c_str() : "");
+#else
+ if (value)
+ {
+ setenv(name, value->c_str(), 1);
+ }
+ else
+ {
+ unsetenv(name);
+ }
+#endif
+ }
+ } // namespace
+
+ TemporaryDirectoryScope::TemporaryDirectoryScope(
+ const std::string &directory)
+ {
+ if (directory.empty())
+ {
+ return;
+ }
+ std::error_code error;
+ std::filesystem::create_directories(directory, error);
+ if (error)
+ {
+ return;
+ }
+ active_ = true;
+ for (std::size_t index = 0; index < kVariables.size(); ++index)
+ {
+ if (HasEnvironment(kVariables[index]))
+ {
+ previous_[index] = ReadEnvironment(kVariables[index]);
+ }
+ SetVariable(kVariables[index], directory);
+ }
+ const std::lock_guard lock{CurrentMutex()};
+ Current() = directory;
+ }
+
+ TemporaryDirectoryScope::~TemporaryDirectoryScope()
+ {
+ if (!active_)
+ {
+ return;
+ }
+ for (std::size_t index = 0; index < kVariables.size(); ++index)
+ {
+ SetVariable(kVariables[index], previous_[index]);
+ }
+ const std::lock_guard lock{CurrentMutex()};
+ Current().clear();
+ }
+} // namespace Progmasoft::Catch3::Runner
+
+namespace Progmasoft::Catch3
+{
+ std::filesystem::path
+ TestTemporaryDirectory()
+ {
+ {
+ const std::lock_guard lock{Runner::CurrentMutex()};
+ if (!Runner::Current().empty())
+ {
+ return std::filesystem::path{Runner::Current()};
+ }
+ }
+ std::error_code error;
+ auto directory = std::filesystem::temp_directory_path(error);
+ return error ? std::filesystem::path{"."} : directory;
+ }
+} // namespace Progmasoft::Catch3