feat(kotlin-compose): design system + 33 components + gallery_kt + e2e android emulator + scaffolder fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+211
@@ -0,0 +1,211 @@
|
||||
#!/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/<name>,
|
||||
# y ejecuta fn index. La plantilla cumple cpp/PATTERNS.md y .claude/rules/cpp_apps.md.
|
||||
#
|
||||
# Uso:
|
||||
# init_cpp_app <name> [--project <p>] [--domain <d>] [--desc "..."] [--tags "a,b"]
|
||||
#
|
||||
# Por defecto domain=tools, sin proyecto (cpp/apps/<name>/).
|
||||
|
||||
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 <name>" >&2
|
||||
echo "Uso: init_cpp_app <name> [--project <p>] [--domain <d>] [--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" <<EOF
|
||||
#include <imgui.h>
|
||||
#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" <<EOF
|
||||
add_imgui_app($name
|
||||
main.cpp
|
||||
)
|
||||
target_include_directories($name PRIVATE \${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties($name PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
endif()
|
||||
EOF
|
||||
|
||||
# ---------- app.md ----------
|
||||
local repo_url="https://gitea.organic-machine.com/dataforge/$name"
|
||||
local tags_yaml="[imgui]"
|
||||
if [[ -n "$tags" ]]; then
|
||||
# Convierte "a,b,c" -> "[a, b, c]"
|
||||
tags_yaml="[$(echo "$tags" | sed 's/,/, /g'), imgui]"
|
||||
fi
|
||||
|
||||
cat > "$abs_dir/app.md" <<EOF
|
||||
---
|
||||
name: $name
|
||||
lang: cpp
|
||||
domain: $domain
|
||||
description: "$desc"
|
||||
tags: $tags_yaml
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
framework: "imgui"
|
||||
entry_point: "main.cpp"
|
||||
dir_path: "$rel_dir"
|
||||
repo_url: "$repo_url"
|
||||
---
|
||||
|
||||
# $name
|
||||
|
||||
$desc
|
||||
|
||||
## Build
|
||||
|
||||
\`\`\`bash
|
||||
cd cpp && cmake --build build --target $name -j
|
||||
\`\`\`
|
||||
|
||||
## Run
|
||||
|
||||
\`\`\`bash
|
||||
./cpp/build/$name
|
||||
\`\`\`
|
||||
EOF
|
||||
|
||||
# ---------- Registrar en cpp/CMakeLists.txt ----------
|
||||
local cpp_cmake="$FN_ROOT/cpp/CMakeLists.txt"
|
||||
if ! grep -q "# --- $name ---" "$cpp_cmake"; then
|
||||
if [[ -n "$project" ]]; then
|
||||
local upper
|
||||
upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')"
|
||||
cat >> "$cpp_cmake" <<EOF
|
||||
|
||||
# --- $name (lives in projects/$project/apps/) ---
|
||||
set(_${upper}_DIR \${CMAKE_SOURCE_DIR}/../projects/$project/apps/$name)
|
||||
if(EXISTS \${_${upper}_DIR}/CMakeLists.txt)
|
||||
add_subdirectory(\${_${upper}_DIR} \${CMAKE_BINARY_DIR}/apps/$name)
|
||||
endif()
|
||||
EOF
|
||||
else
|
||||
cat >> "$cpp_cmake" <<EOF
|
||||
|
||||
# --- $name ---
|
||||
if(EXISTS \${CMAKE_CURRENT_SOURCE_DIR}/apps/$name/CMakeLists.txt)
|
||||
add_subdirectory(apps/$name)
|
||||
endif()
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------- Git + Gitea ----------
|
||||
if [[ -n "${GITEA_URL:-}" && -n "${GITEA_TOKEN:-}" ]]; then
|
||||
ensure_repo_synced "$abs_dir" "dataforge" "$name" "master" "feat: scaffold $name via init_cpp_app" || \
|
||||
echo "init_cpp_app: warning — ensure_repo_synced fallo, repo no creado" >&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
|
||||
Reference in New Issue
Block a user