bootstrap: iniciar bitácora operativa
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
package clusterlog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func (a *App) runProject(root string, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return NewError(ExitUsage, "project_usage", "uso: project create | list", nil)
|
||||
}
|
||||
switch args[0] {
|
||||
case "create":
|
||||
fs := newFlagSet("project create")
|
||||
title := fs.String("title", "", "título")
|
||||
description := fs.String("description", "", "resumen")
|
||||
objective := fs.String("objective", "", "objetivo")
|
||||
owners := fs.String("owners", "", "administradores separados por coma")
|
||||
targetDate := fs.String("target-date", "", "fecha YYYY-MM-DD")
|
||||
status := fs.String("status", "", "planned|active|blocked|done|cancelled")
|
||||
tags := fs.String("tags", "", "tags separados por coma")
|
||||
systems := fs.String("systems", "", "sistemas separados por coma")
|
||||
scope := fs.String("scope", "", "elementos de alcance separados por coma")
|
||||
outOfScope := fs.String("out-of-scope", "", "elementos fuera de alcance separados por coma")
|
||||
milestones := fs.String("milestones", "", "hitos separados por coma")
|
||||
success := fs.String("success", "", "criterios de éxito separados por coma")
|
||||
bodyFile := fs.String("body-file", "", "Markdown o -")
|
||||
fromJSON := fs.String("from-json", "", "JSON o -")
|
||||
if err := fs.Parse(args[1:]); err != nil {
|
||||
return NewError(ExitUsage, "invalid_flags", err.Error(), nil)
|
||||
}
|
||||
var input ProjectInput
|
||||
if *fromJSON != "" {
|
||||
if err := decodeJSONInput(*fromJSON, a.Options.Stdin, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if wasSet(fs, "title") {
|
||||
input.Title = *title
|
||||
}
|
||||
if wasSet(fs, "description") {
|
||||
input.Description = *description
|
||||
}
|
||||
if wasSet(fs, "objective") {
|
||||
input.Objective = *objective
|
||||
}
|
||||
if wasSet(fs, "owners") {
|
||||
input.Owners = splitCSV(*owners)
|
||||
}
|
||||
if wasSet(fs, "target-date") {
|
||||
input.TargetDate = *targetDate
|
||||
}
|
||||
if wasSet(fs, "status") {
|
||||
input.Status = *status
|
||||
}
|
||||
if wasSet(fs, "tags") {
|
||||
input.Tags = splitCSV(*tags)
|
||||
}
|
||||
if wasSet(fs, "systems") {
|
||||
input.Systems = splitCSV(*systems)
|
||||
}
|
||||
if wasSet(fs, "scope") {
|
||||
input.Scope = splitCSV(*scope)
|
||||
}
|
||||
if wasSet(fs, "out-of-scope") {
|
||||
input.OutOfScope = splitCSV(*outOfScope)
|
||||
}
|
||||
if wasSet(fs, "milestones") {
|
||||
input.Milestones = splitCSV(*milestones)
|
||||
}
|
||||
if wasSet(fs, "success") {
|
||||
input.Success = splitCSV(*success)
|
||||
}
|
||||
if *bodyFile != "" {
|
||||
data, err := readAll(*bodyFile, a.Options.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
input.BodyMarkdown = string(data)
|
||||
}
|
||||
identity, err := a.ResolveIdentity(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, warnings, err := a.createProject(root, identity, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.Options.DryRun {
|
||||
return a.printResult("project.create", result, warnings...)
|
||||
}
|
||||
state, changed, statePath, err := a.Sync(root, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paths := []string{filepath.FromSlash(result["path"].(string))}
|
||||
if changed {
|
||||
paths = append(paths, statePath)
|
||||
}
|
||||
sha, err := a.commitPaths(root, identity, fmt.Sprintf("project(%s): %s", result["project_id"], input.Title), paths)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result["commit"] = sha
|
||||
result["active_projects"] = state.Stats.ActiveProjects
|
||||
return a.printResult("project.create", result, warnings...)
|
||||
case "list":
|
||||
fs := newFlagSet("project list")
|
||||
status := fs.String("status", "", "filtrar por estado")
|
||||
if err := fs.Parse(args[1:]); err != nil {
|
||||
return NewError(ExitUsage, "invalid_flags", err.Error(), nil)
|
||||
}
|
||||
state, err := a.BuildState(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items := []ProjectState{}
|
||||
for _, item := range state.Projects {
|
||||
if *status == "" || item.Status == *status {
|
||||
items = append(items, item)
|
||||
}
|
||||
}
|
||||
return a.printResult("project.list", map[string]any{"count": len(items), "items": items})
|
||||
default:
|
||||
return NewError(ExitUsage, "project_usage", "uso: project create | list", args[0])
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) runContent(root string, args []string) error {
|
||||
if len(args) == 0 || args[0] != "create" {
|
||||
return NewError(ExitUsage, "content_usage", "uso: content create --section documentacion|manuales --title ... --body-file ...", nil)
|
||||
}
|
||||
fs := newFlagSet("content create")
|
||||
section := fs.String("section", "", "documentacion|manuales")
|
||||
title := fs.String("title", "", "título")
|
||||
description := fs.String("description", "", "resumen")
|
||||
tags := fs.String("tags", "", "tags separados por coma")
|
||||
systems := fs.String("systems", "", "sistemas separados por coma")
|
||||
bodyFile := fs.String("body-file", "", "Markdown o -")
|
||||
weight := fs.Int("weight", 0, "orden opcional")
|
||||
fromJSON := fs.String("from-json", "", "JSON o -")
|
||||
if err := fs.Parse(args[1:]); err != nil {
|
||||
return NewError(ExitUsage, "invalid_flags", err.Error(), nil)
|
||||
}
|
||||
var input ContentInput
|
||||
if *fromJSON != "" {
|
||||
if err := decodeJSONInput(*fromJSON, a.Options.Stdin, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if wasSet(fs, "section") {
|
||||
input.Section = *section
|
||||
}
|
||||
if wasSet(fs, "title") {
|
||||
input.Title = *title
|
||||
}
|
||||
if wasSet(fs, "description") {
|
||||
input.Description = *description
|
||||
}
|
||||
if wasSet(fs, "tags") {
|
||||
input.Tags = splitCSV(*tags)
|
||||
}
|
||||
if wasSet(fs, "systems") {
|
||||
input.Systems = splitCSV(*systems)
|
||||
}
|
||||
if wasSet(fs, "weight") {
|
||||
input.Weight = *weight
|
||||
}
|
||||
if *bodyFile != "" {
|
||||
data, err := readAll(*bodyFile, a.Options.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
input.BodyMarkdown = string(data)
|
||||
}
|
||||
identity, err := a.ResolveIdentity(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, warnings, err := a.createContent(root, identity, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.Options.DryRun {
|
||||
return a.printResult("content.create", result, warnings...)
|
||||
}
|
||||
createdPath := filepath.FromSlash(result["path"].(string))
|
||||
sha, err := a.commitPaths(root, identity, fmt.Sprintf("%s(%s): %s", input.Section, result["content_id"], input.Title), []string{createdPath})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result["commit"] = sha
|
||||
return a.printResult("content.create", result, warnings...)
|
||||
}
|
||||
|
||||
func (a *App) runSync(root string, args []string) error {
|
||||
fs := newFlagSet("sync")
|
||||
check := fs.Bool("check", false, "no escribe; falla si el estado generado está desactualizado")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return NewError(ExitUsage, "invalid_flags", err.Error(), nil)
|
||||
}
|
||||
state, changed, path, err := a.Sync(root, *check)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.printResult("sync", map[string]any{
|
||||
"path": filepath.ToSlash(path), "changed": changed, "check": *check,
|
||||
"source_sha256": state.SourceSHA256, "stats": state.Stats,
|
||||
})
|
||||
}
|
||||
|
||||
func (a *App) runVerify(root string, args []string) error {
|
||||
if len(args) == 0 || args[0] != "commit" {
|
||||
return NewError(ExitUsage, "verify_usage", "uso: verify commit [SHA]", nil)
|
||||
}
|
||||
sha := "HEAD"
|
||||
if len(args) > 1 {
|
||||
sha = args[1]
|
||||
}
|
||||
if len(args) > 2 {
|
||||
return NewError(ExitUsage, "unexpected_arguments", "uso: verify commit [SHA]", args[2:])
|
||||
}
|
||||
if err := verifyCommit(root, sha); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.printResult("verify.commit", map[string]any{"commit": sha, "valid": true})
|
||||
}
|
||||
Reference in New Issue
Block a user