Files
Breeze/source/BreezeCore/include/breeze/Project.hpp
T
2026-10-24 09:53:48 -03:00

110 lines
3.4 KiB
C++

#pragma once
#include <filesystem>
#include <optional>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
#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> version;
/// <root>/breeze, or <root> 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;
/// <root>/.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/<name>.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<Sdk> detectSdk(const std::filesystem::path& root);
/// The nearest project at or above `start`.
std::optional<Project> 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<std::string> 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<std::string> run() const;
void setRun(const std::string& id);
void clearRun();
void save(const Project& project) const;
private:
nlohmann::json m_data = nlohmann::json::object();
};
}