/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2022, Danny Robson */ #pragma once #include "concepts/named.hpp" #include #include /////////////////////////////////////////////////////////////////////////////// namespace cruft::paths { /// Return the path to the system's temporary directory. std::filesystem::path temp (void); /// Expand paths that contain platform specific variables /// /// eg, "$TMPDIR/foo" and "%HOMEPATH%/foo" std::filesystem::path expand (std::filesystem::path const&); /// Given a relative path, and a collection of candidate base paths, /// return the first path that exists. /// /// Or, if none do, return the relative path itself (if it exists). /// /// Else throw a runtime_error. /// /// Note: there's a good chance if you're using this then it's likely /// you'll run into TOCTOU errors. template std::filesystem::path resolve_first (std::filesystem::path const &relative, ContainerT bases) { for (auto const &base: bases) { auto const candidate = base / relative; if (std::filesystem::exists (candidate)) return candidate; } if (exists (relative)) return relative; throw std::runtime_error ("no path"); } }