root/trunk/make-doc.py

Revision 1628, 8.4 kB (checked in by rob, 2 months ago)

Refs #537: patchlevel version now determined from git log
* changed peppy/init.py to import _peppy_version to get its version info
* _peppy_version not version controlled
* updated places that depended on version
* removed cruft from setup.py.in

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to "Url Rev Author Date Id"
Line 
1#!/usr/bin/env python
2
3import os,sys,re,os.path,time
4from cStringIO import StringIO
5from datetime import date
6from optparse import OptionParser
7from string import Template
8
9module=None
10
11namespace={
12    'prog':None,
13    'author':None,
14    'author_email':None,
15    'url':None,
16    'description':None,
17    'long_description': None,
18    'packages': None,
19    'cvs_version':None,
20    'release_version':None,
21    'version':None,
22    'codename': None,
23    'release_date':None, # should stat the file instead
24    'release_file':None,
25    'today':date.today().strftime("%d %B %Y"),
26    'year':date.today().strftime("%Y"),
27    'yearstart':'2006',
28    'htmlBody':'',
29    'preBody':'',
30    }
31
32def findLongDescription():
33    # skip the opening one-line description and grab the first paragraph
34    # out of the module's docstring to use as the long description.
35    long_description = ''
36    lines = module.__doc__.splitlines()
37    for firstline in range(len(lines)):
38        # skip until we reach a blank line
39        if len(lines[firstline])==0 or lines[firstline].isspace():
40            break
41    if firstline<len(lines):
42        firstline+=1
43    for lastline in range(firstline,len(lines)):
44        # stop when we reach a blank line
45        if len(lines[lastline])==0 or lines[lastline].isspace():
46            break
47    long_description = " ".join(lines[firstline:lastline])
48    namespace['long_description'] = long_description
49
50def findPackages(mil=False):
51    packages = []
52
53    # find packages to be installed
54    path = os.path.dirname(module.__file__)
55    def addmodules(arg, dirname, names):
56        if '__init__.py' in names:
57            prefix = os.path.commonprefix((path, dirname))
58            mod = "%s%s" % (module.__name__, dirname[len(prefix):].replace(os.sep,'.'))
59            if mod not in packages:
60                packages.append(mod)
61    os.path.walk(path, addmodules, None)
62    print "packages = %s" % packages
63    if mil == False and 'peppy.hsi.mil' in packages:
64        packages.remove('peppy.hsi.mil')
65    namespace['packages'] = str(packages)
66
67def setnamespace(mil=False):
68    if module:
69        defaults={
70            'prog':'__name__',
71            'version': '__version__',
72            'codename': '__codename__',
73            'author':'__author__',
74            'author_email':'__author_email__',
75            'url':'__url__',
76            'download_url':'__download_url__',
77            'description':'__description__',
78            'license': '__license__',
79            'keywords': '__keywords__',
80            'coconuts': '__sir_not_appearing_in_this_film__',
81            }
82       
83        for key,val in defaults.iteritems():
84            if hasattr(module, val):
85                namespace[key]=getattr(module, val)
86            # print "%s=%s" % (key,val)
87   
88    findLongDescription()
89    findPackages(mil)
90   
91    if int(namespace['yearstart'])<int(namespace['year']):
92        namespace['yearrange']=namespace['yearstart']+'-'+namespace['year']
93    else:
94        namespace['yearrange']=namespace['year']
95
96
97
98def store(keyword,infile):
99    if isinstance(infile,str):
100        fh=open(infile)
101    else:
102        fh=infile
103    txt=fh.read()
104    t=Template(txt)
105    out=t.safe_substitute(namespace)
106    namespace[keyword]=out
107
108def remap(keyword,value):
109    if value.startswith('$'):
110        value=namespace[value[1:]]
111    namespace[keyword]=value
112
113def parse(infile):
114    if isinstance(infile,str):
115        fh=open(infile)
116    else:
117        fh=infile
118    txt=fh.read()
119    t=Template(txt)
120    out=t.safe_substitute(namespace)
121    return out
122
123def parsedocstring(infile):
124    if isinstance(infile,str):
125        fh=open(infile)
126    else:
127        fh=infile
128    doc=StringIO()
129    count=0
130    while count<2:
131        line=fh.readline()
132        if line.find('"""')>=0: count+=1
133        doc.write(line)
134    unparsed=fh.read()
135    t=Template(doc.getvalue())
136    out=t.safe_substitute(namespace)
137    return out+unparsed
138
139def parsechangelog(infile):
140    if isinstance(infile, str):
141        fh = open(infile)
142    else:
143        fh = infile
144    doc=StringIO()
145    doc.write("<h2>ChangeLog</h2>")
146    release_date = ''
147    version = ''
148    show_items = False
149    for line in fh:
150        match=re.match('(\d+-\d+-\d+).*',line)
151        if match:
152            if show_items:
153                doc.write("</ul>\n")
154                show_items = False
155            print 'found date %s' % match.group(1)
156            release_date=date.fromtimestamp(time.mktime(time.strptime(match.group(1),'%Y-%m-%d'))).strftime('%d %B %Y')
157        else:
158            match=re.match('\s+\*\s*[Rr]eleased peppy-([\d\.]+)',line)
159            if match:
160                print 'found version %s' % match.group(1)
161                version=match.group(1)
162                doc.write("<h3>%s, released %s</h3>\n<ul>\n" % (version, release_date))
163                show_items = True
164            else:
165                line = line.lstrip()
166                if line.startswith('*'):
167                    doc.write("<li>%s " % line[1:])
168                else:
169                    doc.write(line)
170    return doc.getvalue()
171
172
173if __name__=='__main__':
174    usage="usage: %prog [-m module] [-o file] [-n variablename file] [-t template] [files...]"
175    parser=OptionParser(usage=usage)
176    parser.add_option("-m", action="store", dest="module",
177                      help="module to import")
178   
179    parser.add_option("-o", action="store", dest="outputfile",
180                      help="output filename")
181    parser.add_option("-n", "--name", action="append", nargs=2,
182                      dest="namespace", metavar="KEY FILENAME",
183                      help="expand the named variable KEY with the contents of FILENAME")
184    parser.add_option("-r", "--remapkey", action="append", nargs=2,
185                      dest="remapkey", metavar="KEY1 KEY2",
186                      help="remap the named variable KEY1 with the value of the named variable KEY2")
187    parser.add_option("-k", "--keyvalue", action="append", nargs=2,
188                      dest="keyvalue", metavar="KEY VALUE",
189                      help="remap the named variable KEY with the supplied constant VALUE, or if VALUE begins with a $, with the value of that named variable.  Note that you probably have to escape the $ from the shell with \\$")
190    parser.add_option("-t", "--template", action="store", dest="template",
191                      help="filename of template file")
192    parser.add_option("-p", "--print-namespace", action="store_true",
193                      dest="printnamespace", help="print namespace and exit without processing")
194    parser.add_option("--mil", action="store_true", default=False,
195                      dest="mil", help="use mil modules")
196    parser.add_option("-d", "--docstring-only", action="store_true",
197                      dest="docstringonly", help="only variable-expand the named file's docstring only; leave the remaining contents unchanged.")
198    parser.add_option("-c", "--changelog", action="store_true",
199                      dest="changelog", help="create a changelog input file.")
200    (options, args) = parser.parse_args()
201
202    all=''
203
204    if options.module:
205        module=__import__(options.module)
206
207    setnamespace(options.mil)
208
209    # Static value setting should happen before anything
210    if options.keyvalue:
211        for keyword,value in options.keyvalue:
212            print "keyword=%s value=%s" % (keyword,value)
213            remap(keyword,value)
214
215    if options.namespace:
216        for keyword,filename in options.namespace:
217            # print "keyword=%s filename=%s" % (keyword,filename)
218            store(keyword,filename)
219
220    if options.remapkey:
221        for key1,key2 in options.remapkey:
222            value=namespace[key2]
223            print "keyword=%s value=%s" % (key1,value)
224            remap(key1,value)
225
226    if options.template:
227        all=parse(options.template)
228
229    if options.printnamespace:
230        print namespace
231        sys.exit()
232
233    for filename in args:
234        if options.docstringonly:
235            txt = parsedocstring(filename)
236        elif options.changelog:
237            txt = parsechangelog(filename)
238        else:
239            txt = parse(filename)
240        if options.outputfile:
241            print 'saving to %s' % options.outputfile
242            all += txt
243        else:
244            if filename.endswith('.in'):
245                outfile = filename[:-3]
246            else:
247                outfile = filename+".out"
248            fh = open(outfile,"w")
249            fh.write(txt)
250            fh.close()
251
252    if options.outputfile:
253        fh = open(options.outputfile,"w")
254        fh.write(all)
255        fh.close()
256    else:
257        print all
258       
Note: See TracBrowser for help on using the browser.