timoideas
Version:
CLI oficial de Timoideas para automatizar tareas de desarrollo
166 lines (149 loc) • 4.54 kB
JavaScript
// 📦 Flujo interactivo para crear commits estandarizados
const { execSync } = require("child_process");
const prompts = require("prompts");
// ✅ Cancelación global consistente
const onCancel = () => {
console.log("\n❌ Operación cancelada por el usuario.\n");
process.exit(0);
};
module.exports = async function commitFlow() {
console.log("\n🚀 Iniciando creación de commit...\n");
// 🎯 Tipos válidos con emojis y descripciones
const validTypes = [
{
title: "refactor",
value: "refactor",
emoji: "♻️ ",
description: "cambio interno sin alterar el comportamiento",
example: "reestructura lógica de checkout",
},
{
title: "feat",
value: "feat",
emoji: "✨",
description: "nueva funcionalidad para el usuario final",
example: "añade login con Google",
},
{
title: "fix",
value: "fix",
emoji: "🐞",
description: "corrección de errores de lógica o visuales",
example: "corrige error de navegación en mobile",
},
{
title: "perf",
value: "perf",
emoji: "⚡",
description: "mejoras de rendimiento",
example: "optimiza carga de imágenes",
},
{
title: "style",
value: "style",
emoji: "🎨",
description: "formato, estilos, sin cambiar lógica",
example: "ajusta padding en header",
},
{
title: "docs",
value: "docs",
emoji: "📝",
description: "cambios en documentación (README, etc.)",
example: "documenta uso del endpoint /users",
},
{
title: "chore",
value: "chore",
emoji: "🔧",
description: "tareas de mantenimiento",
example: "actualiza dependencias",
},
{
title: "test",
value: "test",
emoji: "🧪",
description: "todo lo relacionado a testing",
example: "agrega pruebas a componente Modal",
},
];
// 🧠 Preguntar tipo de commit
const maxLength = Math.max(...validTypes.map(({ title }) => title.length));
const { type } = await prompts(
{
type: "select",
name: "type",
message: "📂 Selecciona el tipo de commit",
choices: validTypes.map(({ title, value, emoji, description }) => ({
// Alineamos títulos con padEnd para que los emojis queden en columna
title: `${title.padEnd(maxLength)} ${emoji} ${description}`,
value,
})),
},
{ onCancel }
);
const selected = validTypes.find((t) => t.value === type);
const example = selected?.example || "";
// 🧩 Preguntar scope
const { scope } = await prompts(
{
type: "text",
name: "scope",
message: "🧩 Scope (<módulo | sección | componente>)",
},
{ onCancel }
);
// 📝 Preguntar mensaje de commit
let message = "";
while (true) {
const res = await prompts(
{
type: "text",
name: "msg",
message: `📝 Mensaje (<${example}>)`,
},
{ onCancel }
);
message = res.msg?.trim().toLowerCase();
if (!message || message.length < 5) {
console.log("❌ El mensaje debe tener al menos 5 caracteres.");
} else if (message.length > 72) {
console.log("❌ El mensaje no puede superar 72 caracteres.");
} else {
break;
}
}
// 🧾 Formato final del commit
const commitMessage = scope
? `${type}(${scope.trim().toLowerCase().replace(/ /g, "-")}): ${message}`
: `${type}: ${message}`;
console.log(`\n✅ Commit preparado: ${commitMessage}\n`);
// ✅ Ejecutar commit
try {
execSync("git add -A", { stdio: "inherit" });
execSync(`git commit -m "${commitMessage}"`, { stdio: "inherit" });
} catch (error) {
console.error("❌ Error al hacer commit. ¿Tienes cambios para commitear?");
process.exit(1);
}
// ☁️ Preguntar push
const { confirmPush } = await prompts(
{
type: "confirm",
name: "confirmPush",
message: "¿Deseas hacer push ahora?",
initial: false,
},
{ onCancel }
);
if (confirmPush) {
try {
execSync("git push", { stdio: "inherit" });
console.log("\n🚀 Push completado.");
} catch {
console.error("❌ Error durante el push. Verifica tu conexión o rama.");
}
} else {
console.log("\n⏭️ Push omitido por el usuario.");
}
};