@icarusmx/creta 1.4.5 → 1.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ejemplo.sh
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Bash Scripts - Automatización con scripts de shell
|
|
2
|
+
export const BASH_SCRIPTS = {
|
|
3
|
+
id: 'bash-scripts',
|
|
4
|
+
|
|
5
|
+
intro: {
|
|
6
|
+
definition: 'Un script es una secuencia de comandos guardados en un archivo que se pueden ejecutar como un programa.',
|
|
7
|
+
explanation: 'Los bash scripts te permiten automatizar tareas repetitivas y crear herramientas personalizadas.',
|
|
8
|
+
detail: 'Comenzaremos con "Salgamos de este laberinto." y terminaremos construyendo un script de deployment automático.'
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
steps: [
|
|
12
|
+
{
|
|
13
|
+
type: 'command-intro',
|
|
14
|
+
command: 'echo',
|
|
15
|
+
description: 'Primer concepto: echo',
|
|
16
|
+
explanation: 'echo imprime texto en la terminal.',
|
|
17
|
+
example: 'echo "Salgamos de este laberinto."',
|
|
18
|
+
instruction: 'Este es el comando más simple. Pruébalo en tu terminal.'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
type: 'command-intro',
|
|
22
|
+
command: '#!/bin/bash',
|
|
23
|
+
description: 'El shebang',
|
|
24
|
+
explanation: 'La primera línea de un script debe indicar qué intérprete usar.',
|
|
25
|
+
example: '#!/bin/bash\necho "Salgamos de este laberinto."',
|
|
26
|
+
instruction: 'Siempre comienza tus scripts con #!/bin/bash en la primera línea.'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'command-intro',
|
|
30
|
+
command: 'nano script.sh',
|
|
31
|
+
description: 'Crear un archivo de script',
|
|
32
|
+
explanation: 'Usa cualquier editor de texto para crear archivos .sh',
|
|
33
|
+
example: 'nano deploy.sh\n# O usa: code deploy.sh',
|
|
34
|
+
instruction: 'Los scripts son archivos de texto. La extensión .sh es convencional para bash scripts.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'command-intro',
|
|
38
|
+
command: 'chmod +x',
|
|
39
|
+
description: 'Hacer ejecutable un script',
|
|
40
|
+
explanation: 'chmod +x le da permisos de ejecución a un archivo.',
|
|
41
|
+
example: 'chmod +x deploy.sh\n./deploy.sh',
|
|
42
|
+
instruction: 'Después de chmod +x puedes ejecutar el script con ./nombre-script.sh'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'command-intro',
|
|
46
|
+
command: 'VARIABLE="valor"',
|
|
47
|
+
description: 'Variables en bash',
|
|
48
|
+
explanation: 'Puedes guardar valores en variables para reutilizarlos.',
|
|
49
|
+
example: 'MENSAJE="Salgamos de este laberinto."\necho $MENSAJE',
|
|
50
|
+
instruction: 'Define con NOMBRE="valor" y usa con $NOMBRE. Sin espacios alrededor del ='
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'command-intro',
|
|
54
|
+
command: '$(comando)',
|
|
55
|
+
description: 'Sustitución de comandos',
|
|
56
|
+
explanation: 'Puedes guardar la salida de un comando en una variable.',
|
|
57
|
+
example: 'VERSION=$(node -p "require(\'./package.json\').version")\necho "Versión actual: $VERSION"',
|
|
58
|
+
instruction: 'Todo lo que esté dentro de $() se ejecuta y su resultado se guarda.'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'command-intro',
|
|
62
|
+
command: 'IFS',
|
|
63
|
+
description: 'Dividir strings (Internal Field Separator)',
|
|
64
|
+
explanation: 'IFS te permite dividir un string en partes usando un delimitador.',
|
|
65
|
+
example: 'VERSION="1.2.3"\nIFS=\'.\' read -r -a PARTS <<< "$VERSION"\necho ${PARTS[2]} # imprime: 3',
|
|
66
|
+
instruction: 'Muy útil para manipular versiones semánticas (major.minor.patch).'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'command-intro',
|
|
70
|
+
command: '$((expresión))',
|
|
71
|
+
description: 'Aritmética en bash',
|
|
72
|
+
explanation: 'Usa $(( )) para hacer operaciones matemáticas.',
|
|
73
|
+
example: 'PATCH=3\nNEW_PATCH=$((PATCH + 1))\necho $NEW_PATCH # imprime: 4',
|
|
74
|
+
instruction: 'Funciona para sumar, restar, multiplicar y dividir números enteros.'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'command-intro',
|
|
78
|
+
command: 'sed',
|
|
79
|
+
description: 'Reemplazar texto en archivos',
|
|
80
|
+
explanation: 'sed permite buscar y reemplazar texto dentro de archivos.',
|
|
81
|
+
example: 'sed -i \'\' "s/viejo/nuevo/" archivo.txt',
|
|
82
|
+
instruction: 'En macOS usa -i \'\'. En Linux solo -i. Formato: s/buscar/reemplazar/'
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: 'command-intro',
|
|
86
|
+
command: 'if [ $? -eq 0 ]',
|
|
87
|
+
description: 'Condicionales y códigos de salida',
|
|
88
|
+
explanation: '$? contiene el código de salida del último comando. 0 significa éxito.',
|
|
89
|
+
example: 'npm publish\nif [ $? -eq 0 ]; then\n echo "✅ Éxito"\nelse\n echo "❌ Error"\nfi',
|
|
90
|
+
instruction: 'Usa if/then/else/fi para tomar decisiones basadas en resultados.'
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
type: 'code',
|
|
94
|
+
title: 'Script completo: deploy-patch.sh',
|
|
95
|
+
code: `#!/bin/bash
|
|
96
|
+
|
|
97
|
+
# Obtener versión actual del package.json
|
|
98
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
99
|
+
|
|
100
|
+
# Dividir la versión en partes (major.minor.patch)
|
|
101
|
+
IFS='.' read -r -a VERSION_PARTS <<< "$CURRENT_VERSION"
|
|
102
|
+
MAJOR="\${VERSION_PARTS[0]}"
|
|
103
|
+
MINOR="\${VERSION_PARTS[1]}"
|
|
104
|
+
PATCH="\${VERSION_PARTS[2]}"
|
|
105
|
+
|
|
106
|
+
# Incrementar el número de patch
|
|
107
|
+
NEW_PATCH=$((PATCH + 1))
|
|
108
|
+
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
|
|
109
|
+
|
|
110
|
+
echo "📦 Bumping version: $CURRENT_VERSION → $NEW_VERSION"
|
|
111
|
+
|
|
112
|
+
# Actualizar package.json con la nueva versión
|
|
113
|
+
sed -i '' "s/\\"version\\": \\"$CURRENT_VERSION\\"/\\"version\\": \\"$NEW_NEW\\"/" package.json
|
|
114
|
+
|
|
115
|
+
echo "🚀 Publishing to npm..."
|
|
116
|
+
npm publish
|
|
117
|
+
|
|
118
|
+
# Verificar si el publish fue exitoso
|
|
119
|
+
if [ $? -eq 0 ]; then
|
|
120
|
+
echo "✅ Successfully published @icarusmx/creta@$NEW_VERSION"
|
|
121
|
+
else
|
|
122
|
+
echo "❌ Publish failed, reverting version..."
|
|
123
|
+
sed -i '' "s/\\"version\\": \\"$NEW_VERSION\\"/\\"version\\": \\"$CURRENT_VERSION\\"/" package.json
|
|
124
|
+
exit 1
|
|
125
|
+
fi`,
|
|
126
|
+
after: [
|
|
127
|
+
'',
|
|
128
|
+
'Este script automatiza:',
|
|
129
|
+
'1. Leer la versión actual',
|
|
130
|
+
'2. Incrementar el patch',
|
|
131
|
+
'3. Actualizar package.json',
|
|
132
|
+
'4. Publicar a npm',
|
|
133
|
+
'5. Revertir si falla'
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'maze-completion',
|
|
138
|
+
message: 'Bash Scripts completado! Ya puedes automatizar tareas.',
|
|
139
|
+
unlocked: 'Ahora puedes crear tus propias herramientas de automatización.'
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Piping y Redirección - Conectando comandos y manejando flujos de datos
|
|
2
|
+
export const PIPING_REDIRECCION = {
|
|
3
|
+
id: 'piping-redireccion',
|
|
4
|
+
|
|
5
|
+
intro: {
|
|
6
|
+
definition: 'Piping y redirección son mecanismos para conectar comandos y controlar hacia dónde va la información.',
|
|
7
|
+
explanation: 'En lugar de ver resultados en pantalla, puedes enviarlos a archivos, otros comandos, o usarlos como entrada.',
|
|
8
|
+
detail: 'Esto es lo que hace a bash tan poderoso: puedes combinar comandos simples para crear flujos de trabajo complejos.'
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
steps: [
|
|
12
|
+
{
|
|
13
|
+
type: 'command-intro',
|
|
14
|
+
command: '|',
|
|
15
|
+
description: 'El pipe (tubería)',
|
|
16
|
+
explanation: 'El símbolo | toma la salida de un comando y la envía como entrada a otro.',
|
|
17
|
+
example: 'ls | grep ".js"\ncat archivo.txt | wc -l',
|
|
18
|
+
instruction: 'Úsalo para encadenar comandos. La salida del izquierdo entra al derecho.'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
type: 'command-intro',
|
|
22
|
+
command: '>',
|
|
23
|
+
description: 'Redirección de salida (sobrescribir)',
|
|
24
|
+
explanation: '> toma la salida de un comando y la guarda en un archivo, sobrescribiendo contenido previo.',
|
|
25
|
+
example: 'echo "Hola mundo" > saludo.txt\nls > archivos.txt',
|
|
26
|
+
instruction: 'Si el archivo existe, se borra y se reemplaza con el nuevo contenido.'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'command-intro',
|
|
30
|
+
command: '>>',
|
|
31
|
+
description: 'Redirección de salida (agregar)',
|
|
32
|
+
explanation: '>> agrega contenido al final de un archivo sin borrar lo que ya existe.',
|
|
33
|
+
example: 'echo "Primera línea" > log.txt\necho "Segunda línea" >> log.txt',
|
|
34
|
+
instruction: 'Útil para logs y archivos donde quieres preservar el contenido anterior.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'command-intro',
|
|
38
|
+
command: '<',
|
|
39
|
+
description: 'Redirección de entrada',
|
|
40
|
+
explanation: '< toma el contenido de un archivo y lo usa como entrada para un comando.',
|
|
41
|
+
example: 'wc -l < archivo.txt\nsort < nombres.txt',
|
|
42
|
+
instruction: 'En lugar de leer desde teclado, el comando lee desde el archivo.'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'command-intro',
|
|
46
|
+
command: '<<<',
|
|
47
|
+
description: 'Here-string (cadena directa)',
|
|
48
|
+
explanation: '<<< pasa un string directamente como entrada a un comando.',
|
|
49
|
+
example: 'wc -w <<< "Salgamos de este laberinto"\ngrep "mundo" <<< "Hola mundo"',
|
|
50
|
+
instruction: 'Muy útil para pasar variables como entrada: grep "patrón" <<< "$VARIABLE"'
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'command-intro',
|
|
54
|
+
command: 'read <<< "$VAR"',
|
|
55
|
+
description: 'Usando read con here-string',
|
|
56
|
+
explanation: 'read puede tomar una string y dividirla en partes.',
|
|
57
|
+
example: 'VERSION="1.2.3"\nIFS=\'.\' read -r MAJOR MINOR PATCH <<< "$VERSION"\necho $PATCH # imprime: 3',
|
|
58
|
+
instruction: 'IFS define el delimitador. read separa la string y asigna a cada variable.'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'command-intro',
|
|
62
|
+
command: 'read -r -a',
|
|
63
|
+
description: 'Read en un array',
|
|
64
|
+
explanation: 'Con -a, read guarda las partes en un array en lugar de variables separadas.',
|
|
65
|
+
example: 'VERSION="1.2.3"\nIFS=\'.\' read -r -a PARTS <<< "$VERSION"\necho ${PARTS[0]} # 1\necho ${PARTS[1]} # 2\necho ${PARTS[2]} # 3',
|
|
66
|
+
instruction: 'Accede a cada parte con ${ARRAY[índice]}. Los índices empiezan en 0.'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'command-intro',
|
|
70
|
+
command: '2>',
|
|
71
|
+
description: 'Redirección de errores',
|
|
72
|
+
explanation: '2> redirige los mensajes de error (stderr) a un archivo.',
|
|
73
|
+
example: 'npm install 2> errores.log\nls archivo-que-no-existe 2> /dev/null',
|
|
74
|
+
instruction: '/dev/null es como un "agujero negro" - descarta todo lo que le envíes.'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'command-intro',
|
|
78
|
+
command: '&>',
|
|
79
|
+
description: 'Redirección de salida Y errores',
|
|
80
|
+
explanation: '&> redirige tanto la salida normal como los errores al mismo destino.',
|
|
81
|
+
example: 'npm install &> install-log.txt\ngit pull &> pull.log',
|
|
82
|
+
instruction: 'Útil cuando quieres capturar todo lo que un comando produce.'
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: 'code',
|
|
86
|
+
title: 'Ejemplo real: Procesando una versión',
|
|
87
|
+
code: `#!/bin/bash
|
|
88
|
+
|
|
89
|
+
# Obtener versión del package.json
|
|
90
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
91
|
+
|
|
92
|
+
# Aquí está la magia del here-string:
|
|
93
|
+
# 1. Tomamos $VERSION (ej: "1.2.3")
|
|
94
|
+
# 2. Se lo pasamos como entrada a read usando <<<
|
|
95
|
+
# 3. IFS='.' le dice a read que separe por puntos
|
|
96
|
+
# 4. -r significa "raw" (no interpretar backslashes)
|
|
97
|
+
# 5. -a PARTS dice "guarda las partes en el array PARTS"
|
|
98
|
+
|
|
99
|
+
IFS='.' read -r -a PARTS <<< "$VERSION"
|
|
100
|
+
|
|
101
|
+
# Ahora podemos acceder a cada parte
|
|
102
|
+
echo "Major: \${PARTS[0]}" # 1
|
|
103
|
+
echo "Minor: \${PARTS[1]}" # 2
|
|
104
|
+
echo "Patch: \${PARTS[2]}" # 3
|
|
105
|
+
|
|
106
|
+
# Incrementar el patch
|
|
107
|
+
NEW_PATCH=$((PARTS[2] + 1))
|
|
108
|
+
echo "Nueva versión: \${PARTS[0]}.\${PARTS[1]}.$NEW_PATCH"`,
|
|
109
|
+
after: [
|
|
110
|
+
'',
|
|
111
|
+
'El operador <<< es una forma elegante de pasar datos.',
|
|
112
|
+
'Sin él, tendrías que crear un archivo temporal o usar echo | read.',
|
|
113
|
+
'Es especialmente útil para procesar variables.'
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'code',
|
|
118
|
+
title: 'Combinando pipes y redirección',
|
|
119
|
+
code: `# Ver solo archivos .js, contar líneas, guardar resultado
|
|
120
|
+
ls | grep ".js" | wc -l > total-archivos.txt
|
|
121
|
+
|
|
122
|
+
# Buscar en múltiples archivos y guardar matches
|
|
123
|
+
cat *.js | grep "function" > funciones.txt
|
|
124
|
+
|
|
125
|
+
# Procesar git log y extraer solo los commits
|
|
126
|
+
git log --oneline | head -5 > ultimos-commits.txt
|
|
127
|
+
|
|
128
|
+
# Buscar errores en logs, ignorar otros mensajes
|
|
129
|
+
cat app.log | grep "ERROR" 2> /dev/null > errores-importantes.txt`,
|
|
130
|
+
after: [
|
|
131
|
+
'',
|
|
132
|
+
'Puedes encadenar cuantos pipes necesites.',
|
|
133
|
+
'Cada comando procesa la salida del anterior.'
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'maze-completion',
|
|
138
|
+
message: 'Piping y Redirección completado!',
|
|
139
|
+
unlocked: 'Ahora entiendes cómo fluye la información entre comandos.'
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
package/lib/data/menus.js
CHANGED
|
@@ -7,7 +7,9 @@ export const SINTAXIS_MENU_CONFIG = {
|
|
|
7
7
|
description: 'Aprende los comandos fundamentales de terminal y git.',
|
|
8
8
|
options: [
|
|
9
9
|
{ id: 'terminal-basico', title: '1. Terminal básico', description: 'ls, cd, mkdir' },
|
|
10
|
-
{ id: 'git-basico', title: '2. Git básico', description: 'init, status, add, commit' }
|
|
10
|
+
{ id: 'git-basico', title: '2. Git básico', description: 'init, status, add, commit' },
|
|
11
|
+
{ id: 'bash-scripts', title: '3. Bash Scripts', description: 'variables, sed, condicionales' },
|
|
12
|
+
{ id: 'piping-redireccion', title: '4. Piping y Redirección', description: '|, >, <, <<<' }
|
|
11
13
|
]
|
|
12
14
|
}
|
|
13
15
|
|
|
@@ -3,6 +3,8 @@ import { SINTAXIS_MENU_CONFIG } from '../data/menus.js'
|
|
|
3
3
|
import { LessonBuilder } from '../builders/LessonBuilder.js'
|
|
4
4
|
import { TERMINAL_BASICO } from '../data/lessons/sintaxis/terminal-basico.js'
|
|
5
5
|
import { GIT_BASICO } from '../data/lessons/sintaxis/git-basico.js'
|
|
6
|
+
import { BASH_SCRIPTS } from '../data/lessons/sintaxis/bash-scripts.js'
|
|
7
|
+
import { PIPING_REDIRECCION } from '../data/lessons/sintaxis/piping-redireccion.js'
|
|
6
8
|
import { clearConsole } from '../utils/output.js'
|
|
7
9
|
import { createPromptInterface } from '../utils/input.js'
|
|
8
10
|
import { UserState } from '../utils/user-state.js'
|
|
@@ -10,7 +12,9 @@ import { UNLOCK_CONFIG } from '../data/progression.js'
|
|
|
10
12
|
|
|
11
13
|
const LESSONS_BY_ID = new Map([
|
|
12
14
|
['terminal-basico', TERMINAL_BASICO],
|
|
13
|
-
['git-basico', GIT_BASICO]
|
|
15
|
+
['git-basico', GIT_BASICO],
|
|
16
|
+
['bash-scripts', BASH_SCRIPTS],
|
|
17
|
+
['piping-redireccion', PIPING_REDIRECCION]
|
|
14
18
|
])
|
|
15
19
|
|
|
16
20
|
function waitForEnter(message = '\nPresiona Enter para continuar...') {
|