#!/usr/bin/env bash # init_cpp_app — Scaffolder estandar de apps C++ del registry. # # Genera la estructura canonica (main.cpp, CMakeLists.txt, app.md), registra # la app en cpp/CMakeLists.txt, inicializa git + repo Gitea dataforge/, # y ejecuta fn index. La plantilla cumple cpp/PATTERNS.md y .claude/rules/cpp_apps.md. # # Uso: # init_cpp_app [--project

] [--domain ] [--desc "..."] [--tags "a,b"] # # Por defecto domain=tools, sin proyecto (cpp/apps//). set -euo pipefail # Carga helpers del registry FN_ROOT="${FN_REGISTRY_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}" # shellcheck source=/dev/null source "$FN_ROOT/bash/functions/infra/ensure_repo_synced.sh" init_cpp_app() { local name="" local project="" local domain="tools" local desc="" local tags="" while [[ $# -gt 0 ]]; do case "$1" in --project) project="$2"; shift 2 ;; --domain) domain="$2"; shift 2 ;; --desc) desc="$2"; shift 2 ;; --tags) tags="$2"; shift 2 ;; -*) echo "init_cpp_app: flag desconocido: $1" >&2; return 2 ;; *) if [[ -z "$name" ]]; then name="$1"; else echo "init_cpp_app: argumento extra: $1" >&2; return 2 fi shift ;; esac done if [[ -z "$name" ]]; then echo "init_cpp_app: se requiere " >&2 echo "Uso: init_cpp_app [--project

] [--domain ] [--desc \"...\"] [--tags \"a,b\"]" >&2 return 2 fi [[ -z "$desc" ]] && desc="App C++ del registry" # Resolver dir destino local rel_dir abs_dir if [[ -n "$project" ]]; then if [[ ! -f "$FN_ROOT/projects/$project/project.md" ]]; then echo "init_cpp_app: proyecto '$project' no existe (falta projects/$project/project.md)" >&2 return 1 fi rel_dir="projects/$project/apps/$name" else rel_dir="cpp/apps/$name" fi abs_dir="$FN_ROOT/$rel_dir" if [[ -e "$abs_dir" ]]; then echo "init_cpp_app: $rel_dir ya existe" >&2 return 1 fi mkdir -p "$abs_dir" # ---------- main.cpp ---------- cat > "$abs_dir/main.cpp" < #include "framework/app_base.h" #include "core/icons_tabler.h" #include "core/logger.h" // Toggles de paneles (visibles desde el menu View del menubar canonico) static bool g_show_main = true; static void draw_main() { if (!ImGui::Begin(TI_HOME " Main", &g_show_main)) { ImGui::End(); return; } ImGui::TextUnformatted("Hello from $name"); ImGui::End(); } static void render() { // El framework dibuja menubar (View/Layouts/Settings/About) y un // DockSpaceOverViewport central (auto_dockspace=true por defecto). // Aqui solo se dibujan los paneles propios de la app. if (g_show_main) draw_main(); } int main(int /*argc*/, char** /*argv*/) { static fn_ui::PanelToggle panels[] = { { "Main", nullptr, &g_show_main }, }; fn::AppConfig cfg; cfg.title = "$name — $desc"; cfg.about = { "$name", "0.1.0", "$desc" }; cfg.log = { "$name.log", 1 }; cfg.panels = panels; cfg.panel_count = sizeof(panels) / sizeof(panels[0]); return fn::run_app(cfg, render); } EOF # ---------- CMakeLists.txt ---------- cat > "$abs_dir/CMakeLists.txt" < "[a, b, c]" tags_yaml="[$(echo "$tags" | sed 's/,/, /g'), imgui]" fi cat > "$abs_dir/app.md" <> "$cpp_cmake" <> "$cpp_cmake" <&2 else echo "init_cpp_app: GITEA_URL/GITEA_TOKEN no seteados, omitiendo creacion de repo Gitea" >&2 (cd "$abs_dir" && git init -b master >/dev/null 2>&1 || git init >/dev/null 2>&1) fi # ---------- fn index ---------- if [[ -x "$FN_ROOT/fn" ]]; then (cd "$FN_ROOT" && ./fn index >/dev/null 2>&1) || \ echo "init_cpp_app: warning — fn index fallo" >&2 fi echo "init_cpp_app: $rel_dir creada" echo " - Build: cd $FN_ROOT/cpp && cmake --build build --target $name -j" echo " - app.md: $rel_dir/app.md (rellena uses_functions cuando uses funciones del registry)" } # Permitir invocacion directa via 'fn run init_cpp_app ...' if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then init_cpp_app "$@" fi