Less Boilerplate Around Applications
The application framework coordinates executable startup, metadata, command-line options, help and version output, terminal access, error reporting, and exit codes.
Application parts provide a structured way to assemble larger programs, while the resource system compiles required files directly into the executable. Together, these facilities let an application focus on its own workflow without recreating the surrounding infrastructure for every project.
Erbsland Core allows writing script like applications like the following:
auto main(const int argc, char *argv[]) -> int {
auto app = el::Application{argc, argv};
app.setInitializeFn([&app]() -> void {
app.info().setApplicationName("Deployment Label"_el);
app.info().setApplicationVersion(el::Version{1, 0, 0});
app.options()
->addOption({"-e"_el, "--environment"_el, "environment"_el})
.setType(el::OptionType::Text)
.setDefaultValue("staging"_el)
.setHelpDescription("Environment written into the deployment label."_el);
});
app.setMainFn([&app]() -> el::ExitCode {
el::io::printLine("deployment environment: "_el, app.optionValues()->getText("environment"_el));
return el::ExitCode::success();
});
return app.run();
}
… procedural applications …
class ReportApplication final : public el::Application {
public:
using Application::Application;
protected: // implement Application
void initialize() override {
info().setApplicationName("Deployment Report"_el);
info().setApplicationVersion(el::Version{1, 0, 0});
}
void registerCommandLineOptions(const el::OptionsPtr &options) override {
options->addOption("environment"_el)
.setRequired()
.setHelpDescription("Environment summarized by the report."_el);
options->addOption({"-d"_el, "--dry-run"_el, "dry-run"_el})
.setHelpDescription("Marks the report as a simulation."_el);
}
[[nodiscard]] auto main() -> el::ExitCode override {
el::io::printLine("environment: "_el, optionValues()->getText("environment"_el));
el::io::printLine("mode: "_el, optionValues()->getFlag("dry-run"_el) ? "simulation"_el : "deployment"_el);
return el::ExitCode::success();
}
};
auto main(const int argc, char *argv[]) -> int {
auto app = ReportApplication{argc, argv};
return app.run();
}
… fully event-based applications …
class MaintenanceApplication final : public el::Application {
public:
using Application::Application;
protected: // implement Application
void initialize() override {
info().setApplicationName("Maintenance Queue"_el);
info().setApplicationVersion(el::Version{1, 0, 0});
events()->invoke([this]() -> void { runMaintenance(); });
}
private:
void runMaintenance() {
el::io::printLine("maintenance job started"_el);
events()->invoke([this]() -> void {
el::io::printLine("maintenance job completed"_el);
quit();
});
}
};
auto main(const int argc, char *argv[]) -> int {
auto app = MaintenanceApplication{argc, argv};
return app.run();
}
… up to large and complex applications with independent internal services, dependencies, and communications.
auto main(const int argc, char *argv[]) -> int {
auto app = el::Application{argc, argv};
app.info().setApplicationName("Catalog Service"_el);
app.registerPart<CatalogStoragePart>();
app.registerPart<CatalogServerPart>();
app.registerPart<CatalogUIPart>();
app.registerPart<CatalogClientPart>();
return app.run();
}