228 lines
6.9 KiB
Go
228 lines
6.9 KiB
Go
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})
|
|
}
|