Recipes is a C++23 application for storing kitchen stock and recipes in SQLite and exporting the result as:
- console output
- JSON
- YAML
It can show either all recipes or only recipes that are currently cookable with the available stock.
- SQLite-backed storage for products and recipes
- cookable recipe selection based on the current inventory
- console, JSON, and YAML reports
- configurable database and output paths
- GoogleTest test suite
| Path | Purpose |
|---|---|
src/app |
Application orchestration |
src/db |
SQLite access layer |
src/io |
CLI parsing and report dispatch |
src/io/console |
Human-readable console reports |
src/io/json |
JSON export |
src/io/yaml |
YAML export |
src/concepts |
Shared C++ concepts |
src/unites |
Strongly typed unit helpers |
src/types |
Domain types and SQL schema |
src/main.cpp |
Application entry point |
tests |
GoogleTest-based tests |
scripts |
Helper scripts for setup and testing |
- CMake 4.1 or newer
- Conan 2
- A C++23-capable compiler
ctestfor running the test suite- Bash for the helper scripts
On Fedora, scripts/create_env.sh also expects Perl and a few core Perl modules.
-
Install dependencies:
./scripts/create_env.sh Debug
Use
Releaseinstead ofDebugif you want a release build environment. -
Configure the project:
cmake --preset conan-debug
-
Build it:
cmake --build --preset conan-debug
If you prefer to run the commands yourself, the same flow is:
conan install . --build=missing -pr:h profiles/Debug -pr:b profiles/Release
cmake --preset conan-debug
cmake --build --preset conan-debugOn Fedora, use the matching profiles/Fedora-Debug and profiles/Fedora-Release files instead.
The easiest way is:
./scripts/run_tests.sh --build-type DebugUseful options:
--build-type Release— run the Release test configuration--build-dir build/Debug— use a custom build directory--jobs 4— limit or increase parallelism
If you want to do it manually:
ctest --test-dir build/Debug --build-config Debug --output-on-failure --parallel 4The tests/data/ directory contains committed fixtures used by integration
tests. In particular, tests/data/certs/server.crt and
tests/data/certs/server.key are a self-signed certificate and private key
created exclusively for local and CI HTTPS tests.
The test private key is intentionally not a secret and must never be reused
in production or deployed to a real server. Runtime files, user data and
SQLite databases belong under data/ or out/ and should not be committed.
After building, run the Recipes executable from your build directory:
./build/Debug/Recipes --helpThe server starts when the --server-config option is provided. The
configuration format is selected by the file extension and can be JSON, YAML
or YML.
Start the HTTP listener using the sample configuration:
./build/Debug/Recipes --server-config=config/server.jsonThe process prints the bound HTTP port and stays alive until it receives
SIGINT or SIGTERM. Stop a foreground process with Ctrl+C.
To enable HTTPS, provide certificate and private-key files and use:
./build/Debug/Recipes --server-config=config/server-https.jsonThe HTTPS listener performs a TLS server handshake before passing the
connection to the same Beast session and REST router used by HTTP. The
certificate paths are relative to the process working directory. The
certificate and key under tests/data/certs/ are test-only assets and are not
valid production credentials.
The application reads from a SQLite database. By default, it expects:
out/data/table.db
and writes reports to:
out/info.json
out/info.yaml
If the database is empty, the reports will be empty too. Populate it through the library API or point the app at an existing SQLite database.
| Option | Meaning |
|---|---|
-h, --help |
Show help |
--db-path <path> |
Use a custom SQLite database |
--all-recipes |
Query all recipes |
--cookable |
Query only cookable recipes |
--full |
Print full recipe details in the console |
--short |
Print only recipe names and ingredient counts |
--console / --no-console |
Enable or disable console output |
--json-out <path> / --no-json |
Control JSON output |
--yaml-out <path> / --no-yaml |
Control YAML output |
By default, console, JSON, and YAML output are all enabled.
Show help:
./build/Debug/Recipes --helpQuery only cookable recipes and print a short console summary:
./build/Debug/Recipes --cookable --short --no-json --no-yamlWrite reports to custom files:
./build/Debug/Recipes \
--db-path ./data/recipes.db \
--json-out ./artifacts/recipes.json \
--yaml-out ./artifacts/recipes.yaml \
--no-consoleUse the full console report:
./build/Debug/Recipes --all-recipes --fullName: Pancake
Ingredients count: 2
[
{
"name": "Tea",
"ingredients": [
{ "name": "Water", "amount": 200, "dimension": "ml" },
{ "name": "Tea leaf", "amount": 5, "dimension": "gr" }
]
}
]- name: Tea
ingredients:
- name: Water
amount: 200
dimension: ml
- name: Tea leaf
amount: 5
dimension: grThe core pieces are also usable from C++ code:
#include "app/App.hpp"
#include "db/DBManager.hpp"
#include "io/Args.hpp"
#include "types/kitchen/Types.hpp"
db::DBManager db;
db.InsertProduct(types::Product{"Milk", 200, types::Dimension::Milliliter});
db.InsertRecipe(types::Recipe{"Pancake", {
types::Product{"Milk", 100, types::Dimension::Milliliter},
}});
io::Args args;
args.AppMutable().recipe_selection = io::RecipeSelection::Cookable;
args.OutMutable().write_json = false;
args.OutMutable().write_yaml = false;
app::Run(args);- The default database path and report paths are relative to the project root.
- The database schema is created automatically when the app opens the database.
- The application uses SQLite, SQLiteCpp, and Glaze for persistence and serialization.