| #!/usr/bin/env python |
| |
| # |
| # Sven's quick hack script to update the documentation |
| # |
| # call with: |
| # ./docs/update.py /usr/bin/docker |
| # |
| |
| import re |
| from sys import argv |
| import subprocess |
| import os |
| import os.path |
| |
| script, docker_cmd = argv |
| |
| def print_usage(outtext, docker_cmd, command): |
| help = "" |
| try: |
| #print "RUN ", "".join((docker_cmd, " ", command, " --help")) |
| help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) |
| except subprocess.CalledProcessError, e: |
| help = e.output |
| for l in str(help).strip().split("\n"): |
| l = l.rstrip() |
| if l == '': |
| outtext.write("\n") |
| else: |
| # `docker --help` tells the user the path they called it with |
| l = re.sub(docker_cmd, "docker", l) |
| outtext.write(" "+l+"\n") |
| outtext.write("\n") |
| |
| # TODO: look for an complain about any missing commands |
| def update_cli_reference(): |
| originalFile = "docs/sources/reference/commandline/cli.md" |
| os.rename(originalFile, originalFile+".bak") |
| |
| intext = open(originalFile+".bak", "r") |
| outtext = open(originalFile, "w") |
| |
| mode = 'p' |
| space = " " |
| command = "" |
| # 2 mode line-by line parser |
| for line in intext: |
| if mode=='p': |
| # Prose |
| match = re.match("( \s*)Usage: docker ([a-z]+)", line) |
| if match: |
| # the begining of a Docker command usage block |
| space = match.group(1) |
| command = match.group(2) |
| mode = 'c' |
| else: |
| match = re.match("( \s*)Usage of .*docker.*:", line) |
| if match: |
| # the begining of the Docker --help usage block |
| space = match.group(1) |
| command = "" |
| mode = 'c' |
| else: |
| outtext.write(line) |
| else: |
| # command usage block |
| match = re.match("("+space+")(.*)|^$", line) |
| #print "CMD ", command |
| if not match: |
| # The end of the current usage block - Shell out to run docker to see the new output |
| print_usage(outtext, docker_cmd, command) |
| outtext.write(line) |
| mode = 'p' |
| if mode == 'c': |
| print_usage(outtext, docker_cmd, command) |
| |
| def update_man_pages(): |
| cmds = [] |
| try: |
| help = subprocess.check_output("".join((docker_cmd)), stderr=subprocess.STDOUT, shell=True) |
| except subprocess.CalledProcessError, e: |
| help = e.output |
| for l in str(help).strip().split("\n"): |
| l = l.rstrip() |
| if l != "": |
| match = re.match(" (.*?) .*", l) |
| if match: |
| cmds.append(match.group(1)) |
| |
| desc_re = re.compile(r".*# DESCRIPTION(.*?)# (OPTIONS|EXAMPLES?).*", re.MULTILINE|re.DOTALL) |
| example_re = re.compile(r".*# EXAMPLES?(.*)# HISTORY.*", re.MULTILINE|re.DOTALL) |
| history_re = re.compile(r".*# HISTORY(.*)", re.MULTILINE|re.DOTALL) |
| |
| for command in cmds: |
| print "COMMAND: "+command |
| history = "" |
| description = "" |
| examples = "" |
| if os.path.isfile("docs/man/docker-"+command+".1.md"): |
| intext = open("docs/man/docker-"+command+".1.md", "r") |
| txt = intext.read() |
| intext.close() |
| match = desc_re.match(txt) |
| if match: |
| description = match.group(1) |
| match = example_re.match(txt) |
| if match: |
| examples = match.group(1) |
| match = history_re.match(txt) |
| if match: |
| history = match.group(1).strip() |
| |
| usage = "" |
| usage_description = "" |
| params = {} |
| key_params = {} |
| |
| help = "" |
| try: |
| help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) |
| except subprocess.CalledProcessError, e: |
| help = e.output |
| last_key = "" |
| for l in str(help).split("\n"): |
| l = l.rstrip() |
| if l != "": |
| match = re.match("Usage: docker "+command+"(.*)", l) |
| if match: |
| usage = match.group(1).strip() |
| else: |
| #print ">>>>"+l |
| match = re.match(" (-+)(.*) \s+(.*)", l) |
| if match: |
| last_key = match.group(2).rstrip() |
| #print " found "+match.group(1) |
| key_params[last_key] = match.group(1)+last_key |
| params[last_key] = match.group(3) |
| else: |
| if last_key != "": |
| params[last_key] = params[last_key] + "\n" + l |
| else: |
| if usage_description != "": |
| usage_description = usage_description + "\n" |
| usage_description = usage_description + l |
| |
| # replace [OPTIONS] with the list of params |
| options = "" |
| match = re.match("\[OPTIONS\](.*)", usage) |
| if match: |
| usage = match.group(1) |
| |
| new_usage = "" |
| # TODO: sort without the `-`'s |
| for key in sorted(params.keys(), key=lambda s: s.lower()): |
| # split on commas, remove --?.*=.*, put in *'s mumble |
| ps = [] |
| opts = [] |
| for k in key_params[key].split(","): |
| #print "......"+k |
| match = re.match("(-+)([A-Za-z-0-9]*)(?:=(.*))?", k.lstrip()) |
| if match: |
| p = "**"+match.group(1)+match.group(2)+"**" |
| o = "**"+match.group(1)+match.group(2)+"**" |
| if match.group(3): |
| # if ="" then use UPPERCASE(group(2))" |
| val = match.group(3) |
| if val == "\"\"": |
| val = match.group(2).upper() |
| p = p+"[=*"+val+"*]" |
| val = match.group(3) |
| if val in ("true", "false"): |
| params[key] = params[key].rstrip() |
| if not params[key].endswith('.'): |
| params[key] = params[key]+ "." |
| params[key] = params[key] + " The default is *"+val+"*." |
| val = "*true*|*false*" |
| o = o+"="+val |
| ps.append(p) |
| opts.append(o) |
| else: |
| print "nomatch:"+k |
| new_usage = new_usage+ "\n["+"|".join(ps)+"]" |
| options = options + ", ".join(opts) + "\n "+ params[key]+"\n\n" |
| if new_usage != "": |
| new_usage = new_usage.strip() + "\n" |
| usage = new_usage + usage |
| |
| |
| outtext = open("docs/man/docker-"+command+".1.md", "w") |
| outtext.write("""% DOCKER(1) Docker User Manuals |
| % Docker Community |
| % JUNE 2014 |
| # NAME |
| """) |
| outtext.write("docker-"+command+" - "+usage_description+"\n\n") |
| outtext.write("# SYNOPSIS\n**docker "+command+"**\n"+usage+"\n\n") |
| if description != "": |
| outtext.write("# DESCRIPTION"+description) |
| if options == "": |
| options = "There are no available options.\n\n" |
| outtext.write("# OPTIONS\n"+options) |
| if examples != "": |
| outtext.write("# EXAMPLES"+examples) |
| outtext.write("# HISTORY\n") |
| if history != "": |
| outtext.write(history+"\n") |
| recent_history_re = re.compile(".*June 2014.*", re.MULTILINE|re.DOTALL) |
| if not recent_history_re.match(history): |
| outtext.write("June 2014, updated by Sven Dowideit <SvenDowideit@home.org.au>\n") |
| outtext.close() |
| |
| # main |
| update_cli_reference() |
| update_man_pages() |