1
0
mirror of https://github.com/owncloud/ocis.git synced 2025-04-18 23:44:07 +03:00
ocis/docs/helpers/extendedEnv.go
jkoberg fcea194af0
fix extended env var parsing
Signed-off-by: jkoberg <jkoberg@owncloud.com>

Co-authored-by: dragonchaser <crichter@owncloud.com>
2024-02-08 16:13:04 +01:00

179 lines
4.4 KiB
Go

package main
import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
"text/template"
"gopkg.in/yaml.v2"
)
const yamlSource = "extended_vars.yaml"
// ConfigVars is the main yaml source
type ConfigVars struct {
Variables []Variable `yaml:"variables"`
}
// Variable contains all information about one rogue envvar
type Variable struct {
// These field structs are automatically filled:
// RawName can be the name of the envvar or the name of its var
RawName string `yaml:"rawname"`
// Path to the envvar with linenumber
Path string `yaml:"path"`
// FoundInCode indicates if the variable is still found in the codebase. TODO: delete immediately?
FoundInCode bool `yaml:"foundincode"`
// Name is equal to RawName but will not be overwritten in consecutive runs
Name string `yaml:"name"`
// These field structs need manual filling:
// Type of the envvar
Type string `yaml:"type"`
// DefaultValue of the envvar
DefaultValue string `yaml:"default_value"`
// Description of what this envvar does
Description string `yaml:"description"`
// Ignore this envvar when creating docs?
Ignore bool `yaml:"do_ignore"`
// For simplicity ignored for now:
// DependendServices []Service `yaml:"dependend_services"`
}
// GetRogueEnvs extracts the rogue envs from the code
func GetRogueEnvs() {
curdir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fullYamlPath := filepath.Join(curdir, yamlSource)
re := regexp.MustCompile(`os.Getenv\(([^\)]+)\)`)
vars := &ConfigVars{}
fmt.Printf("Reading existing variable definitions from %s\n", fullYamlPath)
yfile, err := os.ReadFile(fullYamlPath)
if err == nil {
err := yaml.Unmarshal(yfile, &vars)
if err != nil {
log.Fatal(err)
}
}
if err := os.Chdir("../../"); err != nil {
log.Fatal(err)
}
fmt.Println("Gathering variable definitions from source")
out, err := exec.Command("sh", "-c", "grep -RHn os.Getenv --exclude-dir=vendor | grep -v extendedEnv.go |grep \\.go").Output()
if err != nil {
log.Fatal(err)
}
lines := strings.Split(string(out), "\n")
// find current vars
currentVars := make(map[string]Variable)
for _, l := range lines {
fmt.Printf("Parsing %s\n", l)
r := strings.SplitN(l, ":\t", 2)
if len(r) != 2 || r[0] == "" || r[1] == "" {
continue
}
res := re.FindAllSubmatch([]byte(r[1]), -1)
if len(res) < 1 {
fmt.Printf("Error envvar not matching pattern: %s", r[1])
continue
}
for _, m := range res {
path := r[0]
name := strings.Trim(string(m[1]), "\"")
currentVars[path+name] = Variable{
RawName: name,
Path: path,
FoundInCode: true,
Name: name,
}
}
}
// adjust existing vars
for i, v := range vars.Variables {
_, ok := currentVars[v.Path+v.RawName]
if !ok {
vars.Variables[i].FoundInCode = false
continue
}
vars.Variables[i].FoundInCode = true
delete(currentVars, v.Path+v.RawName)
}
// add new envvars
for _, v := range currentVars {
vars.Variables = append(vars.Variables, v)
}
less := func(i, j int) bool {
return vars.Variables[i].Name < vars.Variables[j].Name
}
sort.Slice(vars.Variables, less)
output, err := yaml.Marshal(vars)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Writing new variable definitions to %s\n", fullYamlPath)
err = os.WriteFile(fullYamlPath, output, 0666)
if err != nil {
log.Fatalf("could not write %s", fullYamlPath)
}
if err := os.Chdir(curdir); err != nil {
log.Fatal(err)
}
}
// RenderGlobalVarsTemplate renders the global vars template
func RenderGlobalVarsTemplate() {
curdir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fullYamlPath := filepath.Join(curdir, yamlSource)
content, err := os.ReadFile("../../docs/templates/ADOC_extended.tmpl")
if err != nil {
log.Fatal(err)
}
targetFolder := "../../docs/services/_includes/adoc/"
vars := &ConfigVars{}
fmt.Printf("Reading existing variable definitions from %s\n", fullYamlPath)
yfile, err := os.ReadFile(fullYamlPath)
if err != nil {
log.Fatal(err)
}
err = yaml.Unmarshal(yfile, &vars)
if err != nil {
log.Fatal(err)
}
targetFile, err := os.Create(filepath.Join(targetFolder, "extended_configvars.adoc"))
if err != nil {
log.Fatalf("Failed to create target file: %s", err)
}
defer targetFile.Close()
tpl := template.Must(template.New("").Parse(string(content)))
if err = tpl.Execute(targetFile, *vars); err != nil {
log.Fatalf("Failed to execute template: %s", err)
}
}