#pragma once #include #include #include #include #include #include "breeze/Version.hpp" /// Finding a breeze project, telling which SDK it has, and reading and writing the project's own /// settings. /// /// The CLI is global and projects carry their SDK (the template's breeze/ folder), so each project /// may be on a different SDK version -- or on the layout before breeze/ existed, with scripts/ and /// cmake/ at the root. Everything here asks the project's Sdk where things are instead of assuming. namespace breeze { enum class SdkLayout { /// breeze/ (the SDK) and project/ (the project's settings). Breeze, /// The flat layout that came before: scripts/, cmake/ and Configuration.cmake at the root. Legacy }; struct Sdk { SdkLayout layout = SdkLayout::Breeze; /// breeze/VERSION. Empty for the legacy layout and for a breeze/ that predates the file. std::optional version; /// /breeze, or in the legacy layout. std::filesystem::path dir; std::filesystem::path scriptsDir; std::filesystem::path cmakeDir; /// project/Configuration.cmake, or Configuration.cmake in the legacy layout. std::filesystem::path settingsFile; /// Does this SDK have add_objects_module? bool supportsObjects = false; /// "1.0.0", "unversioned (breeze/ layout)" or "legacy (flat layout, unversioned)". [[nodiscard]] std::string describe() const; }; struct Project { std::filesystem::path root; Sdk sdk; /// /.breeze: what the CLI keeps in the project (defaults, installed tools). [[nodiscard]] std::filesystem::path metaDir() const; [[nodiscard]] std::filesystem::path defaultsFile() const; [[nodiscard]] std::filesystem::path toolsDir() const; /// The SDK's script `name` for this OS: scripts/.sh, or .bat on Windows. [[nodiscard]] std::filesystem::path script(const std::string& name) const; }; /// Does `root` hold a breeze project, and with which SDK? std::optional detectSdk(const std::filesystem::path& root); /// The nearest project at or above `start`. std::optional findProject(const std::filesystem::path& start); /// findProject, or an Error explaining that the command needs a project. Project requireProject(const std::filesystem::path& start = std::filesystem::current_path()); enum class Setting { Name, // CMake's project() name Version, // the project's own version, major.minor[.patch[.tweak]] Id // the machine-friendly identifier (PROJECT_CODE_NAME) }; std::string readSetting(const Project& project, Setting which); /// Validates the value, then changes just that value in the file, leaving everything else as it /// is. void writeSetting(const Project& project, Setting which, const std::string& value); /// The CLI's per-project defaults, in .breeze/defaults.json (meant to be committed). class Defaults { public: static Defaults load(const Project& project); /// key: platform, arch, compiler, preset or mode. [[nodiscard]] std::optional build(const std::string& key) const; void setBuild(const std::string& key, const std::string& value); void clearBuild(const std::string& key); /// The module id `breeze run` runs when it is given none. [[nodiscard]] std::optional run() const; void setRun(const std::string& id); void clearRun(); void save(const Project& project) const; private: nlohmann::json m_data = nlohmann::json::object(); }; }