Add project files
This commit is contained in:
commit
f2fe6b8855
114 files changed
+20525
No files matched your search
@@ -0,0 +1,872 @@
|
||||
#include "Commands.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include "breeze/Build.hpp"
|
||||
#include "breeze/Cli.hpp"
|
||||
#include "breeze/Config.hpp"
|
||||
#include "breeze/Error.hpp"
|
||||
#include "breeze/Fs.hpp"
|
||||
#include "breeze/Modules.hpp"
|
||||
#include "breeze/Presets.hpp"
|
||||
#include "breeze/Process.hpp"
|
||||
#include "breeze/Project.hpp"
|
||||
#include "breeze/Sdks.hpp"
|
||||
#include "breeze/Text.hpp"
|
||||
#include "breeze/Tools.hpp"
|
||||
|
||||
namespace breeze::cli
|
||||
{
|
||||
|
||||
int& exitCode()
|
||||
{
|
||||
static int s_code = 0;
|
||||
return s_code;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
using Str = std::optional<std::string>;
|
||||
using Strs = std::vector<std::string>;
|
||||
|
||||
// ---------------------------------------------------------------- project
|
||||
|
||||
void showOrSet(Setting which, const Str& set)
|
||||
{
|
||||
Project project = requireProject();
|
||||
if (set)
|
||||
{
|
||||
std::string before = readSetting(project, which);
|
||||
writeSetting(project, which, *set);
|
||||
std::cout << before << " -> " << *set << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << readSetting(project, which) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- config
|
||||
|
||||
void configValue(const char* key, const Str& set)
|
||||
{
|
||||
GlobalConfig cfg = GlobalConfig::load();
|
||||
if (set)
|
||||
{
|
||||
if (*set == "none")
|
||||
cfg.erase(key);
|
||||
else
|
||||
cfg.set(key, *set);
|
||||
cfg.save();
|
||||
std::cout << key << " = " << (*set == "none" ? "<not set>" : *set) << "\n";
|
||||
return;
|
||||
}
|
||||
std::optional<std::string> value = cfg.effective(key);
|
||||
std::cout << (value ? *value : "<not set>") << "\n";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- defaults
|
||||
|
||||
void defaultsBuild(const char* key, const Str& set)
|
||||
{
|
||||
Project project = requireProject();
|
||||
Defaults defaults = Defaults::load(project);
|
||||
if (!set)
|
||||
{
|
||||
std::optional<std::string> v = defaults.build(key);
|
||||
std::cout << (v ? *v : "<not set>") << "\n";
|
||||
return;
|
||||
}
|
||||
if (*set == "none")
|
||||
{
|
||||
defaults.clearBuild(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string value = *set;
|
||||
std::string k = key;
|
||||
if (k == "mode")
|
||||
value = buildTypeFor(value) == "RelWithDebInfo" ? "ReleaseDebugSymbols"
|
||||
: buildTypeFor(value);
|
||||
if (k == "preset")
|
||||
{
|
||||
std::optional<std::string> canonical;
|
||||
for (const Preset& p : listPresets(project))
|
||||
{
|
||||
if (text::normalized(p.name) == text::normalized(value))
|
||||
canonical = p.name;
|
||||
}
|
||||
if (!canonical)
|
||||
throw Error("'" + value +
|
||||
"' is not a preset of this project for this machine "
|
||||
"(see `cmake --list-presets`)");
|
||||
value = *canonical;
|
||||
}
|
||||
defaults.setBuild(key, value);
|
||||
}
|
||||
defaults.save(project);
|
||||
std::cout << "default build " << key << " = "
|
||||
<< defaults.build(key).value_or("<not set>") << "\n";
|
||||
}
|
||||
|
||||
void defaultsRun(const Str& set)
|
||||
{
|
||||
Project project = requireProject();
|
||||
Defaults defaults = Defaults::load(project);
|
||||
if (!set)
|
||||
{
|
||||
std::optional<std::string> v = defaults.run();
|
||||
std::cout << (v ? *v : "<not set>") << "\n";
|
||||
return;
|
||||
}
|
||||
if (*set == "none")
|
||||
{
|
||||
defaults.clearRun();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<Module> modules = scanModules(project);
|
||||
const Module* m = findModule(modules, *set);
|
||||
if (m == nullptr || (m->kind != ModuleKind::Exec && m->kind != ModuleKind::Test &&
|
||||
m->kind != ModuleKind::Example))
|
||||
throw Error("'" + *set + "' is not an executable module of this project");
|
||||
defaults.setRun(m->id);
|
||||
}
|
||||
defaults.save(project);
|
||||
std::cout << "default run = "
|
||||
<< (*set == "none" ? "<not set>" : defaults.run().value_or("")) << "\n";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- generation
|
||||
|
||||
PresetQuery queryOf(const Str& preset, const Str& platform, const Str& arch,
|
||||
const Str& compiler)
|
||||
{
|
||||
PresetQuery q;
|
||||
q.preset = preset;
|
||||
q.platform = platform;
|
||||
q.arch = arch;
|
||||
q.compiler = compiler;
|
||||
return q;
|
||||
}
|
||||
|
||||
void clean(bool noBuild, bool docs)
|
||||
{
|
||||
Project project = requireProject();
|
||||
std::vector<std::string> removed = breeze::clean(project, noBuild, docs);
|
||||
if (removed.empty())
|
||||
std::cout << "nothing to clean\n";
|
||||
for (const std::string& r : removed)
|
||||
std::cout << "removed " << r << "\n";
|
||||
}
|
||||
|
||||
BuildRequest requestOf(const Str& platform, const Str& arch, const Str& compiler,
|
||||
const Str& mode, const std::optional<std::int32_t>& jobs,
|
||||
const Str& preset, const Strs& cargs, const Strs& bargs,
|
||||
bool noConfigure, bool noBuild)
|
||||
{
|
||||
BuildRequest r;
|
||||
r.preset = queryOf(preset, platform, arch, compiler);
|
||||
r.mode = mode;
|
||||
if (jobs)
|
||||
{
|
||||
if (*jobs < 1)
|
||||
throw Error("--jobs must be at least 1");
|
||||
r.jobs = *jobs;
|
||||
}
|
||||
r.configureArgs = cargs;
|
||||
r.buildArgs = bargs;
|
||||
r.noConfigure = noConfigure;
|
||||
r.noBuild = noBuild;
|
||||
return r;
|
||||
}
|
||||
|
||||
void build(const Str& platform, const Str& arch, const Str& compiler, const Str& mode,
|
||||
const std::optional<std::int32_t>& jobs, const Str& preset, const Strs& cargs,
|
||||
const Strs& bargs, bool noConfigure)
|
||||
{
|
||||
exitCode() = breeze::build(requireProject(),
|
||||
requestOf(platform, arch, compiler, mode, jobs, preset,
|
||||
cargs, bargs, noConfigure, false));
|
||||
}
|
||||
|
||||
void install(const Str& platform, const Str& arch, const Str& compiler, const Str& mode,
|
||||
const std::optional<std::int32_t>& jobs, const Str& preset, const Strs& cargs,
|
||||
const Strs& bargs, bool noConfigure, bool noBuild)
|
||||
{
|
||||
exitCode() = breeze::install(requireProject(),
|
||||
requestOf(platform, arch, compiler, mode, jobs, preset,
|
||||
cargs, bargs, noConfigure, noBuild));
|
||||
}
|
||||
|
||||
void docs()
|
||||
{
|
||||
exitCode() = breeze::docs(requireProject());
|
||||
}
|
||||
|
||||
void runOne(const Str& id, const Str& preset, const Str& platform, const Str& arch,
|
||||
const Str& compiler, const Str& mode, const Strs& args)
|
||||
{
|
||||
(void)mode; // the SDK keeps one build directory per preset, so the mode is part of what
|
||||
// was built
|
||||
exitCode() =
|
||||
breeze::run(requireProject(), id, queryOf(preset, platform, arch, compiler), args);
|
||||
}
|
||||
|
||||
void runDefault(const Str& preset, const Str& platform, const Str& arch,
|
||||
const Str& compiler, const Str& mode, const Strs& args)
|
||||
{
|
||||
runOne(std::nullopt, preset, platform, arch, compiler, mode, args);
|
||||
}
|
||||
|
||||
void runById(const std::string& id, const Str& preset, const Str& platform, const Str& arch,
|
||||
const Str& compiler, const Str& mode, const Strs& args)
|
||||
{
|
||||
runOne(id, preset, platform, arch, compiler, mode, args);
|
||||
}
|
||||
|
||||
void setup(bool required, bool all)
|
||||
{
|
||||
exitCode() = breeze::setup(requireProject(), required, all);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- modules
|
||||
|
||||
void add(ModuleKind kind, const std::string& name, const Str& id, const Strs& deps,
|
||||
LibType type)
|
||||
{
|
||||
Project project = requireProject();
|
||||
NewModule request;
|
||||
request.kind = kind;
|
||||
request.name = name;
|
||||
request.id = id;
|
||||
request.deps = deps;
|
||||
request.libType = type;
|
||||
Module m = addModule(project, request);
|
||||
std::cout << "added " << kindName(m.kind) << " module '" << m.id << "' in "
|
||||
<< fs::generic(std::filesystem::relative(m.dir, project.root)) << "\n";
|
||||
}
|
||||
|
||||
void addExec(const std::string& name, const Str& id, const Strs& deps)
|
||||
{
|
||||
add(ModuleKind::Exec, name, id, deps, LibType::Unspecified);
|
||||
}
|
||||
|
||||
void addLib(const std::string& name, const Str& id, const Strs& deps, bool isStatic,
|
||||
bool isShared)
|
||||
{
|
||||
if (isStatic == isShared)
|
||||
throw Error("a library is either --static or --shared; say which (not both)");
|
||||
add(ModuleKind::Lib, name, id, deps, isShared ? LibType::Shared : LibType::Static);
|
||||
}
|
||||
|
||||
void addObj(const std::string& name, const Str& id, const Strs& deps)
|
||||
{
|
||||
add(ModuleKind::Obj, name, id, deps, LibType::Unspecified);
|
||||
}
|
||||
|
||||
void addTest(const std::string& name, const Str& id, const Strs& deps)
|
||||
{
|
||||
add(ModuleKind::Test, name, id, deps, LibType::Unspecified);
|
||||
}
|
||||
|
||||
void addExample(const std::string& name, const Str& id, const Strs& deps)
|
||||
{
|
||||
add(ModuleKind::Example, name, id, deps, LibType::Unspecified);
|
||||
}
|
||||
|
||||
void deleteIt(const std::string& id, bool yes)
|
||||
{
|
||||
Project project = requireProject();
|
||||
std::vector<Module> modules = scanModules(project);
|
||||
const Module* m = findModule(modules, id);
|
||||
if (m == nullptr)
|
||||
throw Error("there is no module '" + id + "' (see `breeze ls`)");
|
||||
std::string where = fs::generic(std::filesystem::relative(m->dir, project.root));
|
||||
if (!yes)
|
||||
{
|
||||
if (!proc::stdinIsTerminal())
|
||||
throw Error("deleting '" + m->id + "' removes " + where +
|
||||
"; pass --yes to do it without asking");
|
||||
std::cout << "Delete module '" << m->id << "' and everything in " << where
|
||||
<< "? [y/N] " << std::flush;
|
||||
std::string answer;
|
||||
std::getline(std::cin, answer);
|
||||
if (text::lower(text::trim(answer)) != "y" &&
|
||||
text::lower(text::trim(answer)) != "yes")
|
||||
{
|
||||
std::cout << "not deleted\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
deleteModule(project, id);
|
||||
std::cout << "deleted " << where << "\n";
|
||||
}
|
||||
|
||||
void rename(const std::string& id, const Str& name, const Str& newId)
|
||||
{
|
||||
Project project = requireProject();
|
||||
RenameResult r = renameModule(project, id, name, newId);
|
||||
if (r.oldDir != r.newDir)
|
||||
std::cout << "directory " << r.oldDir << " -> " << r.newDir << "\n";
|
||||
if (r.oldId != r.newId)
|
||||
std::cout << "id " << r.oldId << " -> " << r.newId << "\n";
|
||||
for (const std::string& d : r.updatedDependents)
|
||||
std::cout << "updated DEPENDS in " << d << "\n";
|
||||
}
|
||||
|
||||
void list(const Str& filter, bool exec, bool obj, bool lib, bool test, bool example,
|
||||
bool isShared, bool isStatic)
|
||||
{
|
||||
Project project = requireProject();
|
||||
std::vector<Module> modules = scanModules(project);
|
||||
bool anyKind = exec || obj || lib || test || example;
|
||||
std::size_t idWidth = 2;
|
||||
std::size_t dirWidth = 3;
|
||||
std::size_t kindWidth = 4;
|
||||
std::vector<const Module*> shown;
|
||||
for (const Module& m : modules)
|
||||
{
|
||||
bool kindOk = !anyKind || (m.kind == ModuleKind::Exec && exec) ||
|
||||
(m.kind == ModuleKind::Obj && obj) ||
|
||||
(m.kind == ModuleKind::Lib && lib) ||
|
||||
(m.kind == ModuleKind::Test && test) ||
|
||||
(m.kind == ModuleKind::Example && example);
|
||||
if (!kindOk)
|
||||
continue;
|
||||
if (isShared && !(m.kind == ModuleKind::Lib && m.libType == LibType::Shared))
|
||||
continue;
|
||||
if (isStatic && !(m.kind == ModuleKind::Lib && m.libType == LibType::Static))
|
||||
continue;
|
||||
if (filter && text::lower(m.id).find(text::lower(*filter)) == std::string::npos &&
|
||||
text::lower(m.dirName).find(text::lower(*filter)) == std::string::npos)
|
||||
continue;
|
||||
shown.push_back(&m);
|
||||
kindWidth = std::max(
|
||||
kindWidth,
|
||||
kindName(m.kind).size() +
|
||||
(m.kind == ModuleKind::Lib && m.libType != LibType::Unspecified ? 7 : 0));
|
||||
idWidth = std::max(idWidth, m.id.size());
|
||||
dirWidth = std::max(
|
||||
dirWidth, fs::generic(std::filesystem::relative(m.dir, project.root)).size());
|
||||
}
|
||||
if (shown.empty())
|
||||
{
|
||||
std::cout << "no modules\n";
|
||||
return;
|
||||
}
|
||||
std::cout << std::left << std::setw(static_cast<int>(idWidth) + 2) << "ID"
|
||||
<< std::setw(static_cast<int>(kindWidth) + 2) << "KIND"
|
||||
<< std::setw(static_cast<int>(dirWidth) + 2) << "DIRECTORY" << "DEPENDS\n";
|
||||
for (const Module* m : shown)
|
||||
{
|
||||
std::string kind = kindName(m->kind);
|
||||
if (m->kind == ModuleKind::Lib && m->libType != LibType::Unspecified)
|
||||
kind += m->libType == LibType::Shared ? "/shared" : "/static";
|
||||
std::string dir = fs::generic(std::filesystem::relative(m->dir, project.root));
|
||||
std::cout << std::left << std::setw(static_cast<int>(idWidth) + 2) << m->id
|
||||
<< std::setw(static_cast<int>(kindWidth) + 2) << kind;
|
||||
if (m->deps.empty())
|
||||
std::cout << dir << "\n";
|
||||
else
|
||||
std::cout << std::setw(static_cast<int>(dirWidth) + 2) << dir
|
||||
<< text::join(m->deps, " ") << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void printTree(const std::vector<Module>& modules, const std::string& id, bool dependencies,
|
||||
int depth, std::set<std::string>& onPath)
|
||||
{
|
||||
const Module* m = findModule(modules, id);
|
||||
std::vector<std::string> next;
|
||||
if (m != nullptr)
|
||||
{
|
||||
next = dependencies ? m->deps : dependentsOf(modules, *m, false);
|
||||
}
|
||||
for (const std::string& n : next)
|
||||
{
|
||||
bool known = findModule(modules, n) != nullptr;
|
||||
std::cout << std::string(static_cast<std::size_t>(depth) * 2, ' ') << n
|
||||
<< (known ? "" : " (external)") << "\n";
|
||||
if (known && onPath.insert(n).second)
|
||||
{
|
||||
printTree(modules, n, dependencies, depth + 1, onPath);
|
||||
onPath.erase(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deps(bool of, const std::string& module, bool recursive)
|
||||
{
|
||||
Project project = requireProject();
|
||||
std::vector<Module> modules = scanModules(project);
|
||||
const Module* m = findModule(modules, module);
|
||||
if (m == nullptr)
|
||||
throw Error("there is no module '" + module + "' (see `breeze ls`)");
|
||||
std::vector<std::string> direct =
|
||||
of ? dependenciesOf(modules, *m, false) : dependentsOf(modules, *m, false);
|
||||
if (direct.empty())
|
||||
{
|
||||
std::cout << (of ? m->id + " depends on nothing\n"
|
||||
: "nothing depends on " + m->id + "\n");
|
||||
return;
|
||||
}
|
||||
if (!recursive)
|
||||
{
|
||||
for (const std::string& d : direct)
|
||||
std::cout << d << (findModule(modules, d) != nullptr ? "" : " (external)")
|
||||
<< "\n";
|
||||
return;
|
||||
}
|
||||
std::set<std::string> onPath{m->id};
|
||||
printTree(modules, m->id, of, 0, onPath);
|
||||
}
|
||||
|
||||
void sdkVersion()
|
||||
{
|
||||
Project project = requireProject();
|
||||
std::cout << project.sdk.describe() << "\n";
|
||||
}
|
||||
|
||||
void sdkUpdate()
|
||||
{
|
||||
sdk::update(requireProject());
|
||||
}
|
||||
|
||||
void sdkUpgrade()
|
||||
{
|
||||
sdk::upgrade(requireProject());
|
||||
}
|
||||
|
||||
void sdkMigrate(const std::string& version)
|
||||
{
|
||||
sdk::migrate(requireProject(), version);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- cli
|
||||
|
||||
void cliVersion()
|
||||
{
|
||||
std::cout << self::version() << "\n";
|
||||
}
|
||||
|
||||
void cliPick(const std::string& version)
|
||||
{
|
||||
self::pick(version);
|
||||
}
|
||||
|
||||
void cliInstall(const std::string& version)
|
||||
{
|
||||
self::install(version);
|
||||
}
|
||||
|
||||
void cliUninstall(const std::string& version)
|
||||
{
|
||||
self::uninstall(version);
|
||||
}
|
||||
|
||||
void cliList()
|
||||
{
|
||||
self::list();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- tools
|
||||
|
||||
void toolInstall(const std::string& repo)
|
||||
{
|
||||
tools::install(requireProject(), repo);
|
||||
}
|
||||
|
||||
void toolUninstall(const std::string& id)
|
||||
{
|
||||
tools::uninstall(requireProject(), id);
|
||||
}
|
||||
|
||||
void toolUpdate(const std::string& id)
|
||||
{
|
||||
tools::update(requireProject(), id);
|
||||
}
|
||||
|
||||
void toolUpgrade(const std::string& id)
|
||||
{
|
||||
tools::upgrade(requireProject(), id);
|
||||
}
|
||||
|
||||
void toolMigrate(const std::string& id, const std::string& version)
|
||||
{
|
||||
tools::migrate(requireProject(), id, version);
|
||||
}
|
||||
|
||||
void toolList()
|
||||
{
|
||||
tools::list(requireProject());
|
||||
}
|
||||
|
||||
// Only here so that `breeze --help` shows it: main() hands `tool <id> ...` to the tool
|
||||
// before CLIForge sees it.
|
||||
void toolRun(const std::string& /*id*/, const Strs& /*arguments*/)
|
||||
{
|
||||
}
|
||||
|
||||
void projectNew(const std::string& name, const Str& id, const Str& sdkVersion)
|
||||
{
|
||||
sdk::createProject(name, id, sdkVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void registerCommands(cliforge::Engine& cli)
|
||||
{
|
||||
using std::int32_t;
|
||||
|
||||
// ---- cli
|
||||
cli.command()
|
||||
.keyword("cli")
|
||||
.keyword("version")
|
||||
.describe("Shows this CLI's version")
|
||||
.action(&cliVersion);
|
||||
cli.command()
|
||||
.keyword("cli")
|
||||
.keyword("pick")
|
||||
.parameter<std::string>("version", "An installed CLI version")
|
||||
.describe("Picks the CLI version that runs from now on")
|
||||
.action(&cliPick);
|
||||
cli.command()
|
||||
.keyword("cli")
|
||||
.keyword("install")
|
||||
.parameter<std::string>("version", "The CLI version to install")
|
||||
.describe(
|
||||
"Installs a CLI version (this program's own, or a release from the CLI source)")
|
||||
.action(&cliInstall);
|
||||
cli.command()
|
||||
.keyword("cli")
|
||||
.keyword("uninstall")
|
||||
.parameter<std::string>("version", "An installed CLI version")
|
||||
.describe("Uninstalls a CLI version")
|
||||
.action(&cliUninstall);
|
||||
cli.command()
|
||||
.keyword("cli")
|
||||
.keyword("ls")
|
||||
.describe("Lists the installed CLI versions")
|
||||
.action(&cliList);
|
||||
|
||||
// ---- project
|
||||
cli.command()
|
||||
.keyword("project")
|
||||
.keyword("new")
|
||||
.parameter<std::string>("name", "The new project's name (and directory)")
|
||||
.option<std::string>("id", '\0', "The project's id (default: the name in lower case)")
|
||||
.option<std::string>("sdk", '\0', "The SDK version to start from (default: the latest)")
|
||||
.describe("Creates a new project")
|
||||
.action(&projectNew);
|
||||
cli.command()
|
||||
.keyword("project")
|
||||
.keyword("version")
|
||||
.option<std::string>("set", '\0', "Sets the project's version (major.minor[.patch])")
|
||||
.describe("Shows or sets the project's version")
|
||||
.action([](const Str& set) { showOrSet(Setting::Version, set); });
|
||||
cli.command()
|
||||
.keyword("project")
|
||||
.keyword("name")
|
||||
.option<std::string>("set", '\0', "Sets the project's name")
|
||||
.describe("Shows or sets the project's name (the CMake project() name)")
|
||||
.action([](const Str& set) { showOrSet(Setting::Name, set); });
|
||||
cli.command()
|
||||
.keyword("project")
|
||||
.keyword("id")
|
||||
.option<std::string>("set", '\0', "Sets the project's id")
|
||||
.describe("Shows or sets the project's id (lower-case; the install component)")
|
||||
.action([](const Str& set) { showOrSet(Setting::Id, set); });
|
||||
|
||||
// ---- setup
|
||||
cli.command()
|
||||
.keyword("setup")
|
||||
.flag("required", '\0', "Install the required tools without asking")
|
||||
.flag("all", '\0', "Also install the optional tools without asking")
|
||||
.describe(
|
||||
"Checks the tools the project builds with and offers to install what is missing")
|
||||
.action(&setup);
|
||||
|
||||
// ---- config
|
||||
cli.command()
|
||||
.keyword("config")
|
||||
.keyword("editor")
|
||||
.option<std::string>("set", '\0', "Sets the editor ('none' clears it)")
|
||||
.describe("Shows or sets the editor the CLI opens files with")
|
||||
.action([](const Str& set) { configValue(config::Editor, set); });
|
||||
cli.command()
|
||||
.keyword("config")
|
||||
.keyword("sdk-source")
|
||||
.option<std::string>("set", '\0',
|
||||
"Sets the SDK source: a git repository (URL or path), or a "
|
||||
"directory of versions ('none' clears it)")
|
||||
.describe("Shows or sets where SDK versions come from")
|
||||
.action([](const Str& set) { configValue(config::SdkSource, set); });
|
||||
cli.command()
|
||||
.keyword("config")
|
||||
.keyword("cli-source")
|
||||
.option<std::string>(
|
||||
"set", '\0',
|
||||
"Sets the CLI source: a URL or directory of releases ('none' clears it)")
|
||||
.describe("Shows or sets where CLI versions come from")
|
||||
.action([](const Str& set) { configValue(config::CliSource, set); });
|
||||
|
||||
// ---- generation
|
||||
cli.command()
|
||||
.keyword("clean")
|
||||
.flag("no-build", 'b', "Do not clean build artifacts")
|
||||
.flag("docs", 'd', "Clean documentation artifacts")
|
||||
.describe("Cleans build artifacts")
|
||||
.action(&clean);
|
||||
|
||||
cli.command()
|
||||
.keyword("build")
|
||||
.option<std::string>("platform", 'P', "The desired platform (Windows, macOS, Linux)")
|
||||
.option<std::string>("arch", 'A', "The desired architecture (x64, x86, arm32, arm64)")
|
||||
.option<std::string>(
|
||||
"compiler", 'C',
|
||||
"The desired compiler (MSVC, Clang, ClangCl, GCC, MinGW32, MinGW64, ...)")
|
||||
.option<std::string>("mode", 'M',
|
||||
"The configuration (Release, Debug, ReleaseDebugSymbols)")
|
||||
.option<int32_t>("jobs", 'j', "The job count for the compilation")
|
||||
.option<std::string>("preset", 'p', "The CMake preset to use")
|
||||
.option<std::string>("cargs", '\0', "CMake configuration arguments", true)
|
||||
.option<std::string>("bargs", '\0', "CMake build arguments", true)
|
||||
.flag("no-configure", '\0', "Do not perform CMake configure")
|
||||
.describe("Configures and builds the project")
|
||||
.action(&build);
|
||||
|
||||
cli.command()
|
||||
.keyword("install")
|
||||
.option<std::string>("platform", 'P', "The desired platform (Windows, macOS, Linux)")
|
||||
.option<std::string>("arch", 'A', "The desired architecture (x64, x86, arm32, arm64)")
|
||||
.option<std::string>(
|
||||
"compiler", 'C',
|
||||
"The desired compiler (MSVC, Clang, ClangCl, GCC, MinGW32, MinGW64, ...)")
|
||||
.option<std::string>("mode", 'M',
|
||||
"The configuration (Release, Debug, ReleaseDebugSymbols)")
|
||||
.option<int32_t>("jobs", 'j', "The job count for the compilation")
|
||||
.option<std::string>("preset", 'p', "The CMake preset to use")
|
||||
.option<std::string>("cargs", '\0', "CMake configuration arguments", true)
|
||||
.option<std::string>("bargs", '\0', "CMake build arguments", true)
|
||||
.flag("no-configure", '\0', "Do not perform CMake configure")
|
||||
.flag("no-build", '\0', "Do not perform CMake build")
|
||||
.describe("Configures, builds and installs the project")
|
||||
.action(&install);
|
||||
|
||||
cli.command().keyword("docs").describe("Builds the project documentation").action(&docs);
|
||||
|
||||
// ---- defaults
|
||||
for (const char* key : {"platform", "arch", "compiler", "preset", "mode"})
|
||||
{
|
||||
cli.command()
|
||||
.keyword("defaults")
|
||||
.keyword("build")
|
||||
.keyword(key)
|
||||
.option<std::string>("set", '\0',
|
||||
"Sets this default to the given value ('none' clears it)")
|
||||
.describe(std::string("Gets or sets the project default build ") + key)
|
||||
.action([key](const Str& set) { defaultsBuild(key, set); });
|
||||
}
|
||||
cli.command()
|
||||
.keyword("defaults")
|
||||
.keyword("run")
|
||||
.option<std::string>("set", '\0',
|
||||
"Sets this default to the given value ('none' clears it)")
|
||||
.describe(
|
||||
"Gets or sets the default executable to run if no `id` is given to `breeze run`")
|
||||
.action(&defaultsRun);
|
||||
|
||||
// ---- run (the id is optional: two commands)
|
||||
cli.command()
|
||||
.keyword("run")
|
||||
.option<std::string>("preset", 'p', "The preset to run")
|
||||
.option<std::string>("platform", 'P', "The desired platform (Windows, macOS, Linux)")
|
||||
.option<std::string>("arch", 'A', "The desired architecture (x64, x86, arm32, arm64)")
|
||||
.option<std::string>(
|
||||
"compiler", 'C',
|
||||
"The desired compiler (MSVC, Clang, ClangCl, GCC, MinGW32, MinGW64, ...)")
|
||||
.option<std::string>("mode", 'M',
|
||||
"The configuration (Release, Debug, ReleaseDebugSymbols)")
|
||||
.option<std::string>("args", 'x', "The arguments to pass to the executable", true)
|
||||
.describe("Runs the default executable (see `breeze defaults run`)")
|
||||
.action(&runDefault);
|
||||
cli.command()
|
||||
.keyword("run")
|
||||
.parameter<std::string>("id", "The executable module to run")
|
||||
.option<std::string>("preset", 'p', "The preset to run")
|
||||
.option<std::string>("platform", 'P', "The desired platform (Windows, macOS, Linux)")
|
||||
.option<std::string>("arch", 'A', "The desired architecture (x64, x86, arm32, arm64)")
|
||||
.option<std::string>(
|
||||
"compiler", 'C',
|
||||
"The desired compiler (MSVC, Clang, ClangCl, GCC, MinGW32, MinGW64, ...)")
|
||||
.option<std::string>("mode", 'M',
|
||||
"The configuration (Release, Debug, ReleaseDebugSymbols)")
|
||||
.option<std::string>("args", 'x', "The arguments to pass to the executable", true)
|
||||
.describe("Runs an executable (primary executable, test or example)")
|
||||
.action(&runById);
|
||||
|
||||
// ---- modules
|
||||
cli.command()
|
||||
.keyword("add")
|
||||
.keyword("exec")
|
||||
.parameter<std::string>("name", "The module's name (its directory)")
|
||||
.option<std::string>("id", '\0', "The CMake target id (default: <name>_exe)")
|
||||
.option<std::string>("deps", '\0', "Modules or targets it depends on", true)
|
||||
.describe("Adds an executable module")
|
||||
.action(&addExec);
|
||||
cli.command()
|
||||
.keyword("add")
|
||||
.keyword("lib")
|
||||
.parameter<std::string>("name", "The module's name (its directory)")
|
||||
.option<std::string>("id", '\0', "The CMake target id (default: <name>_lib)")
|
||||
.option<std::string>("deps", '\0', "Modules or targets it depends on", true)
|
||||
.flag("static", '\0', "A static library")
|
||||
.flag("shared", '\0', "A shared library")
|
||||
.describe("Adds a library module")
|
||||
.action(&addLib);
|
||||
cli.command()
|
||||
.keyword("add")
|
||||
.keyword("obj")
|
||||
.parameter<std::string>("name", "The module's name (its directory)")
|
||||
.option<std::string>("id", '\0', "The CMake target id (default: <name>_obj)")
|
||||
.option<std::string>("deps", '\0', "Modules or targets it depends on", true)
|
||||
.describe("Adds an objects module: compiled to object files that a library or "
|
||||
"executable takes in")
|
||||
.action(&addObj);
|
||||
cli.command()
|
||||
.keyword("add")
|
||||
.keyword("test")
|
||||
.parameter<std::string>("name", "The module's name (its directory)")
|
||||
.option<std::string>("id", '\0', "The CMake target id (default: <name>_test)")
|
||||
.option<std::string>("deps", '\0', "Modules or targets it depends on", true)
|
||||
.describe("Adds a test module")
|
||||
.action(&addTest);
|
||||
cli.command()
|
||||
.keyword("add")
|
||||
.keyword("example")
|
||||
.parameter<std::string>("name", "The module's name (its directory)")
|
||||
.option<std::string>("id", '\0', "The CMake target id (default: <name>_example)")
|
||||
.option<std::string>("deps", '\0', "Modules or targets it depends on", true)
|
||||
.describe("Adds an example module")
|
||||
.action(&addExample);
|
||||
|
||||
cli.command()
|
||||
.keyword("delete")
|
||||
.parameter<std::string>("id", "The module's id (or directory name)")
|
||||
.flag("yes", 'y', "Delete without asking")
|
||||
.describe("Deletes a module")
|
||||
.action(&deleteIt);
|
||||
cli.command()
|
||||
.keyword("rename")
|
||||
.parameter<std::string>("id", "The module's id (or directory name)")
|
||||
.option<std::string>("name", '\0', "The new name (directory)")
|
||||
.option<std::string>("id", '\0', "The new id")
|
||||
.describe(
|
||||
"Renames a module's directory and/or id, updating the modules that depend on it")
|
||||
.action(&rename);
|
||||
cli.command()
|
||||
.keyword("ls")
|
||||
.option<std::string>("filter", '\0',
|
||||
"Only modules whose id or directory contains this text")
|
||||
.flag("exec", '\0', "Executable modules")
|
||||
.flag("obj", '\0', "Objects modules")
|
||||
.flag("lib", '\0', "Library modules")
|
||||
.flag("test", '\0', "Test modules")
|
||||
.flag("example", '\0', "Example modules")
|
||||
.flag("shared", '\0', "Only shared libraries")
|
||||
.flag("static", '\0', "Only static libraries")
|
||||
.describe("Lists the project's modules")
|
||||
.action(&list);
|
||||
|
||||
// ---- deps
|
||||
cli.command()
|
||||
.keyword("deps")
|
||||
.keyword("of")
|
||||
.parameter<std::string>("module", "The module's id (or directory name)")
|
||||
.flag("recursive", '\0', "Follow dependencies of dependencies")
|
||||
.describe("Lists what a module depends on")
|
||||
.action([](const std::string& module, bool recursive)
|
||||
{ deps(true, module, recursive); });
|
||||
cli.command()
|
||||
.keyword("deps")
|
||||
.keyword("on")
|
||||
.parameter<std::string>("module", "The module's id (or directory name)")
|
||||
.flag("recursive", '\0', "Follow dependents of dependents")
|
||||
.describe("Lists the modules that depend on a module")
|
||||
.action([](const std::string& module, bool recursive)
|
||||
{ deps(false, module, recursive); });
|
||||
|
||||
// ---- tools
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("install")
|
||||
.parameter<std::string>("repo", "The tool's git repository (URL or path)")
|
||||
.describe("Installs a tool into the project")
|
||||
.action(&toolInstall);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("uninstall")
|
||||
.parameter<std::string>("id", "The tool's id")
|
||||
.describe("Uninstalls a tool from the project")
|
||||
.action(&toolUninstall);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("update")
|
||||
.parameter<std::string>("id", "The tool's id")
|
||||
.describe("Looks for newer versions of a tool")
|
||||
.action(&toolUpdate);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("upgrade")
|
||||
.parameter<std::string>("id", "The tool's id")
|
||||
.describe("Moves a tool to the newest version of its major version")
|
||||
.action(&toolUpgrade);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("migrate")
|
||||
.parameter<std::string>("id", "The tool's id")
|
||||
.parameter<std::string>("version", "The version to move to")
|
||||
.describe("Moves a tool to a given version")
|
||||
.action(&toolMigrate);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.keyword("ls")
|
||||
.describe("Lists the project's tools")
|
||||
.action(&toolList);
|
||||
cli.command()
|
||||
.keyword("tool")
|
||||
.parameter<std::string>("id", "An installed tool")
|
||||
.parameter<std::string>("arguments", "What the tool is asked to do", true)
|
||||
.describe("Runs a command a tool adds: breeze tool <id> <arguments...>")
|
||||
.action(&toolRun);
|
||||
|
||||
// ---- sdk
|
||||
cli.command()
|
||||
.keyword("sdk")
|
||||
.keyword("version")
|
||||
.describe("Shows the project's SDK version")
|
||||
.action(&sdkVersion);
|
||||
cli.command()
|
||||
.keyword("sdk")
|
||||
.keyword("update")
|
||||
.describe("Looks for newer SDK versions")
|
||||
.action(&sdkUpdate);
|
||||
cli.command()
|
||||
.keyword("sdk")
|
||||
.keyword("upgrade")
|
||||
.describe("Moves the project to the newest SDK version of its major version")
|
||||
.action(&sdkUpgrade);
|
||||
cli.command()
|
||||
.keyword("sdk")
|
||||
.keyword("migrate")
|
||||
.parameter<std::string>("version", "The SDK version to move to")
|
||||
.describe("Moves the project to a given SDK version (across majors, and from the "
|
||||
"legacy layout)")
|
||||
.action(&sdkMigrate);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user