File: makeweb.py

package info (click to toggle)
llvm-py 0.5%2Bsvn85-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 996 kB
  • ctags: 1,768
  • sloc: python: 3,655; ansic: 1,893; cpp: 495; pascal: 91; makefile: 8; sh: 1
file content (190 lines) | stat: -rwxr-xr-x 6,103 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env python

# Usage: run "python makeweb.py src web" to update files
# under 'web'. See "python makeweb.py --help" for more options.

import os, sys, shutil
from stat import *
from optparse import OptionParser


# how to process files that match various filename patterns
FILE_ACTION_TBL = [

    # selector_func(infilepath) -> True|False
    # output_filepath_func(outfilepath) -> outfilepath
    # cmd_line_func(opts, infilepath, outfilepath) -> cmdline|None

    ( lambda f: f.endswith('.py'),
      lambda o: o.replace('.py', '.html'),
      lambda opts, i, o: "source-highlight --input='%s' --output='%s'" \
        % (i, o) ),

    ( lambda f: f.endswith('userguide.txt'),
      lambda o: o.replace('.txt', '.html'),
      lambda opts, i, o: "asciidoc --unsafe --conf-file='%s/layout.conf' -a icons -a toc -o '%s' '%s'" \
        % (opts.srcdir, o, i) ),

    ( lambda f: f.endswith('.txt'),
      lambda o: o.replace('.txt', '.html'),
      lambda opts, i, o: "asciidoc --unsafe --conf-file='%s/layout.conf' -a icons -o '%s' '%s'" \
        % (opts.srcdir, o, i) ),

    ( lambda f: f.endswith('layout.conf') or f.endswith('.svn') or f.endswith('.inc'),
      lambda o: o,
      lambda opts, i, o: None )
]


# list of directories to skip
DIR_SKIP_TBL = [
    '.svn'
]


def _is_older(inp, outp):
    older = True
    if os.path.exists(outp):
        modin  = os.stat(inp)[ST_MTIME]
        modout = os.stat(outp)[ST_MTIME]
        older = (modin > modout)
    return older


def _rmtree_warn(fn, path, excinfo):
    print "** WARNING **: error while doing %s on %s" % (fn, path)


def _can_skip(opts, infile, outfile):
    return not _is_older(infile, outfile) and not opts.force


def process_file(opts, infile, outfile):

    for matchfn, outfilefn, cmdfn in FILE_ACTION_TBL:
        if matchfn(infile):
            outfile_actual = outfilefn(outfile)
            cmd = cmdfn(opts, infile, outfile_actual)
            if _can_skip(opts, infile, outfile_actual):
                if opts.verbose >= 2:
                    print "up to date %s -> %s" % (infile, outfile_actual)
                return
            if cmd:
                # do cmd
                if opts.verbose:
                    print "process %s -> %s" % (infile, outfile_actual)
                if opts.verbose >= 3:
                    print "command is [%s]" % cmd
                if not opts.dryrun:
                    os.system(cmd)
            # else if cmd is None, do nothing
            return

    # nothing matched, default action is to copy
    if not _can_skip(opts, infile, outfile):
        if opts.verbose:
            print "copying %s -> %s" % (infile, outfile)
        if not opts.dryrun:
            shutil.copy(infile, outfile)


def make(opts, indir, outdir):

    # does outdir exists?
    odexists = os.path.exists(outdir)

    # if it exists, it must be a dir!
    if odexists and not os.path.isdir(outdir):
        print "** WARNING **: output dir '%s' exists but is " \
            "not a dir, skipping" % outdir
        return

    # make outdir if not existing
    if not odexists:
        if opts.verbose:
            print "creating %s" % outdir
        if not opts.dryrun:
            os.mkdir(outdir)

    # process indir/* -> outdir/*
    for elem in os.listdir(indir):
        inp = os.path.join(indir, elem)
        outp = os.path.join(outdir, elem)

        # process files
        if os.path.isfile(inp):
            if os.path.exists(outp) and not os.path.isfile(outp):
                print "** WARNING **: output '%s' corresponding to " \
                    "input '%s' is not a file, skipping" % (outp, inp)
            else:
                process_file(opts, inp, outp)

        # process directories
        elif os.path.isdir(inp):
            # if dir is in skip list, silently ignore
            if elem in DIR_SKIP_TBL:
                if opts.verbose >= 3:
                    print "skipping %s" % inp
                continue
            # just recurse
            make(opts, inp, outp)

        # neither a file nor a dir
        else:
            print "** WARNING **: input '%s' is neither file nor " \
                "dir, skipping" % inp


def get_opts():
    usage = "usage: %prog [options] srcdir destdir"

    p = OptionParser(usage=usage)
    p.add_option("-f", "--force", action="store_true", dest="force", default=False, 
        help="ignore timestamps and force build of all files")
    p.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
        help="be chatty (use more v's to be more friendly)")
    p.add_option("-c", "--clean-first", action="store_true", dest="clean", default=False,
        help="remove outdir and everything under it before building")
    p.add_option("-n", "--dry-run", action="store_true", dest="dryrun", default=False,
        help="just print what will happen rather than doing it")

    (opts, args) = p.parse_args()
    if len(args) != 2:
        p.error("incorrect number of arguments")
    srcdir, destdir = args

    if not os.path.exists(srcdir):
        p.error("srcdir (%s) does not exist" % srcdir)
    if not os.path.isdir(args[0]):
        p.error("srcdir (%s) is not a directory" % srcdir)
    if os.path.exists(destdir) and not os.path.isdir(destdir):
        p.error("destdir (%s) is not a directory" % destdir)

    if opts.verbose == None:
        opts.verbose = 0

    # add srcdir and destdir also to opts
    opts.srcdir = srcdir
    opts.destdir = destdir

    return (opts, srcdir, destdir)


def main():
    opts, src, dest = get_opts()
    if opts.verbose >= 3:
        print ("running with options:\nsrc = [%s]\ndest = [%s]\nverbose = [%d]\n" +\
            "dry-run = [%d]\nclean-first = [%d]\nforce = [%d]") %\
            (src, dest, opts.verbose, opts.dryrun, opts.clean, opts.force)
    if opts.dryrun and opts.verbose == 0:
        opts.verbose = 1
    if opts.clean:
        if opts.dryrun or opts.verbose:
            print "removing tree %s" % dest
        if not opts.dryrun:
            os.rmtree(dest, True, _rmtree_warn)
    make(opts, src, dest)


main()