jimmyfrasche / autoreadme

Automatically create github README.md's from Go source code
BSD 2-Clause "Simplified" License
69 stars 7 forks source link

Documentation of command line flags #1

Closed mewmew closed 8 years ago

mewmew commented 11 years ago

Parse the source code looking for flag.String, flag.VarInt, flag.Usage etc and pull out essential information to generate command line flag documentation.

Example input (github.com/mewmew/playground/wallbase/cmd/walls):

func init() {
    flag.StringVar(&wallPath, "o", "/tmp/wallbase", "Output directory.")
    flag.StringVar(&flagResolution, "res", "", `Screen resolution (ex. "1920x1080").`)
    flag.StringVar(&flagTimeout, "t", "30m", "Timeout interval between updates.")
    flag.BoolVar(&flagVerbose, "v", false, "Verbose.")
    flag.Usage = usage
}

func usage() {
    fmt.Fprintln(os.Stderr, "walls [OPTION]... QUERY")
    fmt.Fprintln(os.Stderr, "Update the desktop wallpaper at specified time intervals.")
    fmt.Fprintln(os.Stderr)
    fmt.Fprintln(os.Stderr, "Flags:")
    flag.PrintDefaults()
    fmt.Fprintln(os.Stderr)
    fmt.Fprintln(os.Stderr, "Examples:")
    fmt.Fprintln(os.Stderr, `  Search for "nature waterfall" and update active wallpaper each 10s.`)
    fmt.Fprintln(os.Stderr, "    walls -t 10s nature waterfall")
    fmt.Fprintln(os.Stderr, `  Search for "nature" and store each wallpaper in "download/".`)
    fmt.Fprintln(os.Stderr, "    walls -t 0s -o download/ nature")
    fmt.Fprintln(os.Stderr, `  Search for "nature" wallpapers with the screen resolution 1920x1080.`)
    fmt.Fprintln(os.Stderr, "    wallbase -res 1920x1080 nature")
}

Output:

Usage:

    walls [OPTION]... QUERY

Flags:

    -o (default="/tmp/wallbase")
        Output directory.
    -res (default="")
        Screen resolution (ex. "1920x1080").
    -t (default="30m")
        Timeout interval between updates.
    -v (default=false)
        Verbose.
jimmyfrasche commented 11 years ago

I did something similar in https://code.google.com/p/mango-doc/

Though it would not have picked any of those flags up because you defined them in an init and it only picks up "var toggle = flag.Bool(yada, false, yada)" style declarations at the top level. I'm not sure how you propose it know how to extract "walls [OPTION]... QUERY" from your usage function without also extracting the examples and without somehow either evaling the code or whitelisting every function in the stdlib that can write to stdout or stderr and hoping no one writes a helper function.

In mango I handled that case by a special comment on the main function, which you can see here https://github.com/JImmyFrasche/autoreadme/blob/master/autoreadme.go#L270

Also the only requests I ever get for mango are to handle third party option parsers, when it can really only handle maybe a tenth of what you can do with the stdlib flag package. I responded by adding another flag to take a text file containing the flag info, which is less than optimal but always works.

I'm starting to think the only solution to both problems is to write a program that reads the output of the program echoing usage, and parse it into the above mentioned format so you can manually fix parsing errors, which is a PITA and less automatic than I would like but it would always work, and at least it's something you could write a script to do it for you.

I'm going to put this on hold until I write such a program an evaluate how well integrated it should be with autoreadme and mango respectively.

mewmew commented 11 years ago

I think the suggestion you have about running the command in a sandbox of some sort and capturing it's output is the most sane thing to do, since there are many 3rd party flag libraries as well (goopt for instance), and that would capture the usage message as well.

Thanks for taking your time and thinking about the issue. And I didn't know you wrote mango-doc, nice :)

jimmyfrasche commented 11 years ago

I'm as big a believer in documentation as I am lazy, if not demonstrably more.

jimmyfrasche commented 11 years ago

In the meantime, you could save -print-template to README.md.template and copy-paste the usage string for your program in wherever you feel like it should fit (indented or wrapped in three backticks so it renders preformatted).

When you run autoreadme in that directory the template file so named will override the built in and include the usage dump. Of course you'd have to repeat that process if the usage changes or flags are added/removed but it shouldn't be too difficult to automate the process with a script and/or build file of some kind if you find yourself doing that frequently (or if you're like me distrust that you'll remember to do so).

mewmew commented 11 years ago

I'm as big a believer in documentation as I am lazy, if not demonstrably more. (or if you're like me distrust that you'll remember to do so).

I know what you mean :) This is why I'm looking for alternatives to automate it, and so far the projects you are working on are looking really promising!

Thanks for what you've written so far and I'll follow your progress closely in the future.

/u

mewmew commented 8 years ago

Mango has solved this issue for me. Thank you Jimmy for being so dedicated to automate the boring documentation tasks! Closing this issue for now, as a solution has been found.