DEV Community

gsweene2
gsweene2

Posted on

Find & Document a Go Project's Flags as Markdown

Goal: Given a Go project, I want to find all of the flags available and document the flag name, flag type, description, and default value as a Markdown table.

The _process_line can probably be cleaned up a bit, but this worked enough for my use case. Optimizations welcome as comments!

Note:

  • Only works if flag is on 1 line (likely missing description if line is too long)
import subprocess

def _find_flag_initializations():
    """Grep for a lines that initalize a flag"""
    cmd = "grep -nr '= flag.' . --include=*.go"
    return subprocess.check_output(cmd, shell=True).splitlines()


def _write_flags_to_md(lines):
    """Write the flag name, type, desc, & default value to stdout as md"""
    print(f"Name | Type | Description | Default")
    print("|-|-|-|-|")
    for line in lines:
        flag_name, flag_type, flag_desc, flag_default  = _process_line(line)
        print(f"`{flag_name}` | {flag_type} | {flag_desc} | {flag_default}")

def _process_line(line):
    """Given a line of Go code that initalizes a flag, derive the
    flag's name, type, desc, & default value"""
    prepped = str(line.decode().split("= flag.")[1])
    flag_name = prepped.split(',')[0].split('(')[1].replace('"','')
    flag_type = prepped.split('(')[0]
    flag_desc = prepped.split(',',2)[2].replace('`','').replace(')','').replace('"','').strip()
    flag_default = prepped.split(',')[1].strip()
    return flag_name, flag_type, flag_desc, flag_default

lines = _find_flag_initializations()
_write_flags_to_md(lines)

# Tests
happy_path = b'./logic/recommender.go:28:\tpodMinMemoryMb       = flag.Float64("pod-recommendation-min-memory-mb", 250, `Minimum memory recommendation for a pod`)'
f_name, f_type, f_desc, f_default = _process_line(happy_path)
assert f_name == 'pod-recommendation-min-memory-mb'
assert f_type == 'Float64'
assert f_desc == 'Minimum memory recommendation for a pod'
assert f_default == '250'

description_with_comma = b'./routines/recommender.go:52:\tmemorySaver             = flag.Bool("memory-saver", false, `If true, only track pods which have an associated VPA`)'
f_name, f_type, f_desc, f_default = _process_line(description_with_comma)
assert f_name == 'memory-saver'
assert f_type == 'Bool'
assert f_desc == 'If true, only track pods which have an associated VPA'
assert f_default == 'false'

default_with_string = b'./main.go:56:\tpodNameLabel        = flag.String("pod-name-label", "kubernetes_pod_name", `Label name to look for pod names`)'
f_name, f_type, f_desc, f_default = _process_line(default_with_string)
assert f_name == 'pod-name-label'
assert f_type == 'String'
assert f_desc == 'Label name to look for pod names'
assert f_default == '"kubernetes_pod_name"'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)