first commit.
This commit is contained in:
+237
@@ -0,0 +1,237 @@
|
||||
#+TITLE: Duckbrain toolbox
|
||||
#+AUTHOR: KJ
|
||||
#+OPTIONS: toc:2
|
||||
|
||||
Instalador y catálogo de paquetes de [[https://git.kj2.me/kj/duckbrain][Duckbrain]]. Trae el núcleo a un
|
||||
proyecto y gestiona sus addons con un solo comando, manteniendo la filosofía del
|
||||
núcleo: *sin Composer obligatorio*, código legible y *copias reales
|
||||
desplegables* (hosting compartido, FTP, etc.).
|
||||
|
||||
* Qué resuelve
|
||||
|
||||
El núcleo Duckbrain mantiene su código simple y sin dependencias, y todo lo
|
||||
accesorio vive en addons. Antes, instalar un addon era copiar archivos a mano
|
||||
dentro de =src/=: cada proyecto quedaba con una versión distinta, las
|
||||
correcciones no se propagaban y se acumulaba código muerto.
|
||||
|
||||
El toolbox convierte eso en:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
duckbrain install mi-proyecto
|
||||
duckbrain add crypto
|
||||
duckbrain update
|
||||
#+END_SRC
|
||||
|
||||
* Conceptos
|
||||
|
||||
| Concepto | Qué es |
|
||||
|-------------+----------------------------------------------------------|
|
||||
| Repositorio | Dónde vive el código (canal de distribución) |
|
||||
| Paquete | Una familia de componentes (=http=, =crypto=, =text=…) |
|
||||
| Componente | La unidad instalable (una clase o una familia) |
|
||||
| Manifiesto | =duckbrain.json=: qué archivos aporta cada componente |
|
||||
| Catálogo | Los paquetes disponibles en el toolbox |
|
||||
| Lock | =.duckbrain/lock.json=: qué quedó instalado y con qué hash |
|
||||
|
||||
La unidad que se pide con =duckbrain add= es el *componente*, no el paquete ni el
|
||||
repositorio.
|
||||
|
||||
* Estructura del repositorio
|
||||
|
||||
#+BEGIN_SRC text
|
||||
duckbrain-toolbox/
|
||||
bin/duckbrain instalador global (bootstrap)
|
||||
scripts/release escritor único de versión + tag
|
||||
packages/
|
||||
commands/ cli, migration, toolbox
|
||||
htmx/ htmlComponent, htmx
|
||||
http/ curlRequest, aria2, proxy, compreFace
|
||||
crypto/ crypto, nonce, twoFactor
|
||||
text/ filter, replacement
|
||||
cache/ apcache
|
||||
id/ ulid
|
||||
test/ harness
|
||||
#+END_SRC
|
||||
|
||||
Cada paquete tiene su =duckbrain.json=. Sólo se copian los archivos declarados
|
||||
por el componente que pides; los metadatos del paquete no se instalan.
|
||||
|
||||
* Instalación
|
||||
|
||||
El instalador global arranca un proyecto desde cero y no necesita nada previo:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
git clone git@git.kj2.me:kj/duckbrain-toolbox.git
|
||||
ln -s "$PWD/duckbrain-toolbox/bin/duckbrain" ~/.local/bin/duckbrain
|
||||
|
||||
duckbrain install mi-proyecto # descarga el núcleo Duckbrain
|
||||
cd mi-proyecto
|
||||
duckbrain add crypto htmx # copias reales, listas para commitear
|
||||
#+END_SRC
|
||||
|
||||
*Uso opcional dentro del proyecto*: si quieres que el proyecto gestione sus
|
||||
propios addons sin el instalador global, instala el componente =commands:toolbox=
|
||||
(es un =add= más, no un requisito). A partir de ahí =./duckbrain= funciona solo.
|
||||
|
||||
* Comandos
|
||||
|
||||
** =duckbrain install [dir]=
|
||||
|
||||
Descarga el núcleo Duckbrain en =dir=. Es sólo del instalador global.
|
||||
|
||||
** =duckbrain add <componente|paquete>=
|
||||
|
||||
Instala componentes, resolviendo dependencias y copiando archivos.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
duckbrain add crypto # la familia completa
|
||||
duckbrain add http:aria2 # un solo componente
|
||||
duckbrain add http@^0.1 # fijando restricción de versión
|
||||
duckbrain add htmx --link # enlaza en lugar de copiar (desarrollo)
|
||||
#+END_SRC
|
||||
|
||||
** =duckbrain remove <componente>=
|
||||
|
||||
Borra sólo los archivos de ese componente; si alguno fue editado localmente,
|
||||
se bloquea y pide =--force=, =--backup= o =--keep-local=.
|
||||
|
||||
** =duckbrain update [core|<componente>] [--dry-run]=
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
duckbrain update core # sólo el núcleo
|
||||
duckbrain update http # un paquete
|
||||
duckbrain update # todo: catálogo -> core -> componentes
|
||||
duckbrain update --dry-run # muestra el plan sin escribir
|
||||
#+END_SRC
|
||||
|
||||
** =duckbrain list= / =duckbrain doctor= / =duckbrain catalog= / =duckbrain adopt=
|
||||
|
||||
- =list=: core y componentes instalados con versión y modo.
|
||||
- =doctor=: matriz de compatibilidad, sin efectos secundarios.
|
||||
- =catalog=: paquetes y componentes disponibles.
|
||||
- =adopt=: registra copias hechas a mano en proyectos antiguos.
|
||||
|
||||
* Manifiesto =duckbrain.json=
|
||||
|
||||
#+BEGIN_SRC json
|
||||
{
|
||||
"name": "http",
|
||||
"version": "0.1.0",
|
||||
"description": "Utilidades HTTP",
|
||||
"core": { "requires": ">=0.1", "tested": "0.1" },
|
||||
"php": ">=8.1",
|
||||
"components": {
|
||||
"curlRequest": { "files": ["src/Libs/CurlRequest.php"] },
|
||||
"aria2": { "files": ["src/Libs/Aria2.php"] },
|
||||
"compreFace": {
|
||||
"files": ["src/Libs/CompreFace.php"],
|
||||
"require": { "http:curlRequest": ">=0.1" }
|
||||
}
|
||||
},
|
||||
"default": ["curlRequest", "aria2", "compreFace"]
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
- =files=: archivos (o directorios) que aporta el componente.
|
||||
- =require=: dependencias entre componentes, con rangos semver.
|
||||
- =core.requires= / =core.tested=: compatibilidad con el núcleo.
|
||||
- =post-install=: comandos de configuración (se muestran y confirman).
|
||||
|
||||
* Destino de los archivos
|
||||
|
||||
- un archivo bajo =src/= → =ROOT_CORE/= (quitando el prefijo =src/=);
|
||||
- cualquier otro archivo → =ROOT_DIR/=.
|
||||
|
||||
Así =crypto/src/Libs/Crypto.php= → =src/Libs/Crypto.php= y
|
||||
=commands/duckbrain= → =duckbrain=.
|
||||
|
||||
* Estado del proyecto
|
||||
|
||||
- =.duckbrain/manifest.json=: lo que *quieres* (restricciones de versión).
|
||||
- =.duckbrain/lock.json=: lo que *tienes* (core y componentes, con versión,
|
||||
commit del toolbox y hash por archivo).
|
||||
|
||||
Los hashes permiten detectar ediciones locales. La actualización respeta lo que
|
||||
editaste y te pregunta antes de pisarlo.
|
||||
|
||||
* Migrar un proyecto existente
|
||||
|
||||
Un proyecto que ya tenía Duckbrain y addons copiados a mano entra al toolbox sin
|
||||
perder nada. Clave: =adopt= *no modifica archivos*; sólo registra en
|
||||
=.duckbrain/lock.json= lo que encuentra. Los cambios de contenido los hace
|
||||
=update=, y sólo cuando tú lo pides.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# 0. Red de seguridad
|
||||
git add -A && git commit -m "antes de migrar a duckbrain-toolbox"
|
||||
|
||||
# 1. Registrar el core y las copias existentes (NO toca archivos)
|
||||
duckbrain adopt
|
||||
|
||||
# 2. Traer lo canónico (y respaldar antes de pisar)
|
||||
duckbrain update core --backup
|
||||
duckbrain add http crypto text --backup
|
||||
|
||||
# 3. Estado y compatibilidad
|
||||
duckbrain list
|
||||
duckbrain doctor
|
||||
|
||||
# 4. Commitear la migración
|
||||
git add -A && git commit -m "migrado a duckbrain-toolbox"
|
||||
#+END_SRC
|
||||
|
||||
Cómo trata =adopt= cada archivo:
|
||||
|
||||
| Caso del archivo | Qué hace =adopt= | ¿Actualiza? |
|
||||
|------------------------------+--------------------------------------+-------------|
|
||||
| Coincide con el catálogo | Lo registra como =adopted= | No |
|
||||
| Existe pero difiere | Lo registra con =origin: local= | No |
|
||||
| Del core (existe en el core) | Registra el hash actual en =lock.core= | No |
|
||||
| Ajeno al core/addons | No lo toca | No |
|
||||
|
||||
Las copias divergentes quedan marcadas como *edición local*: un =update=
|
||||
posterior te avisa y no las pisa salvo =--force= o =--backup=. Así puedes revisar
|
||||
el =git diff= con calma (por ejemplo, el arreglo de =Replacement= en
|
||||
=multipaste-vip=) y decidir cuándo reconciliar. Como un proyecto heredado no
|
||||
tiene hashes previos, =--backup= respalda también la primera escritura.
|
||||
|
||||
* Compatibilidad
|
||||
|
||||
Cada componente declara hasta qué versión del núcleo fue probado:
|
||||
|
||||
#+BEGIN_SRC text
|
||||
core < requires avisa "requiere core >=X"
|
||||
requires ≤ core ≤ tested compatible
|
||||
core > tested avisa "no probado"
|
||||
sin datos avisa "sin datos"
|
||||
#+END_SRC
|
||||
|
||||
Nunca bloquea: se confirma con =--yes=. Al core se le sigue la pista por sus
|
||||
tags semver (=vX.Y.Z=, empezando por =v0.1.0=); si no hay tags, la versión es
|
||||
desconocida y se fija por commit.
|
||||
|
||||
* Versionado y releases
|
||||
|
||||
Cada paquete se versiona de forma independiente con tags prefijados
|
||||
(=http-v0.1.0=, =crypto-v0.1.0=…). El tag es el descubrimiento; el *commit* es la
|
||||
identidad, así que el lock pinea commits y no se rompe si un tag se mueve.
|
||||
|
||||
El release lo hace un único script:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
scripts/release <paquete> <patch|minor|major>
|
||||
#+END_SRC
|
||||
|
||||
Bumpea la versión del manifiesto, commitea, crea el tag y publica. Las versiones
|
||||
retiradas se listan en =yanked.json=; las prereleases se omiten salvo =--pre=.
|
||||
|
||||
* Pruebas
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
php tests/run.php
|
||||
#+END_SRC
|
||||
|
||||
* Contacto
|
||||
|
||||
Puedes encontrarme en Telegram como [[https://telegram.me/keyjay][@keyjay]] o por correo:
|
||||
webmaster@outcontrol.net
|
||||
Reference in New Issue
Block a user