package main import ( "bufio" "fmt" "log" "sort" "strings" "forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/richardrobertreitz/docudile/lib" ) type field struct { name string kind string description []string } type spec struct { uuid string group string kind string version string field []string description []string fields []field } type index struct { name string version string key string uuid string } func getFields(state *int, line string) { *state++ } func getSpec(specs map[string]spec, specName string) { spec := spec{} spec.uuid = specName out, err := lib.ExecNotFatal(`#!/bin/bash kubectl explain "${SPEC}" `, []string{"SPEC=" + specName}) if err != nil { if specName == "events.events.k8s.io" { fmt.Println("warning: skipped " + specName + " intentionally, seems substituted by events") return } else { log.Fatal("warning, cant lookup "+specName+": ", err) } } currentField := field{} fieldsState := 0 scanner := bufio.NewScanner(strings.NewReader(out)) step := 0 for scanner.Scan() { line := scanner.Text() if step == 0 { if strings.HasPrefix(line, "GROUP:") { word := line[6:] spec.group = strings.Join(strings.Fields(word), " ") } else if strings.HasPrefix(line, "KIND:") { word := line[5:] spec.kind = strings.Join(strings.Fields(word), " ") step++ } step++ } else if step == 1 { if strings.HasPrefix(line, "KIND:") { word := line[5:] spec.kind = strings.Join(strings.Fields(word), " ") step++ } else { log.Fatal("cant find kind type") } } else if step == 2 { if strings.HasPrefix(line, "VERSION:") { word := line[8:] spec.version = strings.Join(strings.Fields(word), " ") step++ } else { log.Fatal("cant find kind type") } } else if step == 3 { if len(strings.TrimSpace(line)) == 0 { step++ } else { log.Fatal("cant find new line") } } else if step == 5 { if len(strings.TrimSpace(line)) == 0 { step = 3 } else { log.Fatal("cant find new line") } } else if step == 4 { if strings.HasPrefix(line, "FIELD:") { word := line[6:] spec.field = strings.Fields(word) step = 5 } else if strings.HasPrefix(line, "DESCRIPTION:") { step = 6 } else { log.Fatal("cant find field or description type") } } else if step == 6 { if !strings.HasPrefix(line, "FIELDS:") { if len(line) != 0 { spec.description = append(spec.description, strings.TrimSpace(line)) } } else { step++ } } else if step == 7 { currentField = field{} field.name = strings.TrimSpace(line) spec.fields = append(spec.fields, field) getFields(&fieldsState, &spec.fieldsstrings.TrimSpace(line)) } } fmt.Println("fs " + fmt.Sprint(fieldsState)) if err := scanner.Err(); err != nil { log.Fatal("error: ", err) } if len(spec.field) != 2 && len(spec.field) != 0 { log.Fatal("type field should contain 2 or 0 elements, found " + fmt.Sprint(len(spec.field))) } if len(spec.description) > 0 { if len(strings.TrimSpace(spec.description[len(spec.description)-1])) == 0 { spec.description = spec.description[:len(spec.description)-1] } } specs[specName] = spec } func main() { out, err := lib.ExecNotFatal(`#!/bin/bash kubectl api-resources --verbs=list -o name | sort `, []string{}) if err != nil { log.Fatal("error: ", err) } specs := make(map[string]spec) scanner := bufio.NewScanner(strings.NewReader(out)) for scanner.Scan() { getSpec(specs, scanner.Text()) } getSpec(specs, "edfbuilders.edfbuilder.crossplane.io") if err := scanner.Err(); err != nil { log.Fatal("error: ", err) } for name, spec := range specs { fmt.Println("### uuid = " + name) fmt.Println("group = '" + spec.group + "'") fmt.Println("kind = '" + spec.kind + "'") fmt.Println("version = '" + spec.version + "'") fmt.Println("field[" + fmt.Sprint(len(spec.field)) + "]:") for i := 0; i < len(spec.field); i++ { fmt.Println(" " + spec.field[i]) } fmt.Println("description[" + fmt.Sprint(len(spec.description)) + "]:") for i := 0; i < len(spec.description); i++ { fmt.Println(" " + spec.description[i]) } fmt.Println("fields[" + fmt.Sprint(len(spec.fields)) + "]:") for i := 0; i < len(spec.fields); i++ { fmt.Println(" " + spec.fields[i].name) } } objects := []index{} for name, spec := range specs { objects = append(objects, index{spec.kind, spec.version, name, spec.uuid}) } sort.SliceStable(objects, func(i, j int) bool { if objects[i].name == objects[j].name && objects[i].key == objects[j].key { return objects[i].version < objects[j].version } else if objects[i].name == objects[j].name { return objects[i].key < objects[j].key } else { return objects[i].name < objects[j].name } }) /*for _, object := range objects { fmt.Println(object.name + " " + object.version + "." + object.key + " " + object.uuid) }*/ }