110 lines
3.4 KiB
C++
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();
|
|
};
|
|
|
|
}
|