svgui/pyjs/build.py
changeset 3359 2c924cf26161
parent 3358 7478d0c0dc1c
child 3360 746e3e3f6537
--- a/svgui/pyjs/build.py	Fri Oct 01 15:36:09 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,774 +0,0 @@
-#!/usr/bin/env python
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-import sys
-import shutil
-import re
-import os
-from os.path import join, basename, abspath, split, isfile, isdir
-from hashlib import md5
-from optparse import OptionParser
-from six.moves import cStringIO
-
-from svgui.pyjs import pyjs
-
-
-usage = """
-  usage: %prog [options] <application module name or path>
-
-This is the command line builder for the pyjamas project, which can
-be used to build Ajax applications from Python.
-For more information, see the website at http://pyjs.org/
-"""
-
-# GWT1.2 Impl  | GWT1.2 Output         | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
-# -------------+-----------------------+----------------------+----------------------
-# IE6          | ie6                   | IE6                  | ie6
-# Opera        | opera                 | Opera                | opera
-# Safari       | safari                | Safari               | safari
-# --           | gecko1_8              | Mozilla              | mozilla
-# --           | gecko                 | OldMoz               | oldmoz
-# Standard     | all                   | (default code)       | all
-# Mozilla      | gecko1_8, gecko       | --                   | --
-# Old          | safari, gecko, opera  | --                   | --
-
-version = "%prog pyjamas version 2006-08-19"
-
-# these names in lowercase need match the strings
-# returned by "provider$user.agent" in order to be selected corretly
-app_platforms = ['IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla']
-
-# usually defaults to e.g. /usr/share/pyjamas
-_data_dir = os.path.join(pyjs.prefix, "share/pyjamas")
-
-
-# .cache.html files produces look like this
-CACHE_HTML_PAT = re.compile(r'^[a-z]*.[0-9a-f]{32}\.cache\.html$')
-
-# ok these are the three "default" library directories, containing
-# the builtins (str, List, Dict, ord, round, len, range etc.)
-# the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.)
-# and the contributed addons
-
-for p in ["library/builtins",
-          "library",
-          "addons"]:
-    p = os.path.join(_data_dir, p)
-    if os.path.isdir(p):
-        pyjs.path.append(p)
-
-
-def read_boilerplate(data_dir, filename):
-    return open(join(data_dir, "builder/boilerplate", filename)).read()
-
-
-def copy_boilerplate(data_dir, filename, output_dir):
-    filename = join(data_dir, "builder/boilerplate", filename)
-    shutil.copy(filename, output_dir)
-
-
-# taken and modified from python2.4
-def copytree_exists(src, dst, symlinks=False):
-    if not os.path.exists(src):
-        return
-
-    names = os.listdir(src)
-    try:
-        os.mkdir(dst)
-    except Exception:
-        pass
-
-    errors = []
-    for name in names:
-        if name.startswith('CVS'):
-            continue
-        if name.startswith('.git'):
-            continue
-        if name.startswith('.svn'):
-            continue
-
-        srcname = os.path.join(src, name)
-        dstname = os.path.join(dst, name)
-        try:
-            if symlinks and os.path.islink(srcname):
-                linkto = os.readlink(srcname)
-                os.symlink(linkto, dstname)
-            elif isdir(srcname):
-                copytree_exists(srcname, dstname, symlinks)
-            else:
-                shutil.copy2(srcname, dstname)
-        except (IOError, os.error) as why:
-            errors.append((srcname, dstname, why))
-    if errors:
-        print(errors)
-
-
-def check_html_file(source_file, dest_path):
-    """ Checks if a base HTML-file is available in the PyJamas
-        output directory.
-        If the HTML-file isn't available, it will be created.
-
-        If a CSS-file with the same name is available
-        in the output directory, a reference to this CSS-file
-        is included.
-
-        If no CSS-file is found, this function will look for a special
-        CSS-file in the output directory, with the name
-        "pyjamas_default.css", and if found it will be referenced
-        in the generated HTML-file.
-
-        [thank you to stef mientki for contributing this function]
-    """
-
-    base_html = """\
-<html>
-    <!-- auto-generated html - you should consider editing and
-         adapting this to suit your requirements
-     -->
-    <head>
-      <meta name="pygwt:module" content="%(modulename)s">
-      %(css)s
-      <title>%(title)s</title>
-    </head>
-    <body bgcolor="white">
-      <script language="javascript" src="pygwt.js"></script>
-    </body>
-</html>
-"""
-
-    filename = os.path.split(source_file)[1]
-    mod_name = os.path.splitext(filename)[0]
-    file_name = os.path.join(dest_path, mod_name + '.html')
-
-    # if html file in output directory exists, leave it alone.
-    if os.path.exists(file_name):
-        return 0
-
-    if os.path.exists(os.path.join(dest_path, mod_name + '.css')):
-        css = "<link rel='stylesheet' href='" + mod_name + ".css'>"
-    elif os.path.exists(os.path.join(dest_path, 'pyjamas_default.css')):
-        css = "<link rel='stylesheet' href='pyjamas_default.css'>"
-
-    else:
-        css = ''
-
-    title = 'PyJamas Auto-Generated HTML file ' + mod_name
-
-    base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
-
-    fh = open(file_name, 'w')
-    fh.write(base_html)
-    fh.close()
-
-    return 1
-
-
-def build(app_name, output, js_includes=(), debug=False, dynamic=0,
-          data_dir=None, cache_buster=False, optimize=False):
-
-    # make sure the output directory is always created in the current working
-    # directory or at the place given if it is an absolute path.
-    output = os.path.abspath(output)
-    msg = "Building '%(app_name)s' to output directory '%(output)s'" % locals()
-    if debug:
-        msg += " with debugging statements"
-    print(msg)
-
-    # check the output directory
-    if os.path.exists(output) and not os.path.isdir(output):
-        print("Output destination %s exists and is not a directory" % output, file=sys.stderr)
-        return
-    if not os.path.isdir(output):
-        try:
-            print("Creating output directory")
-            os.mkdir(output)
-        except OSError as e:
-            print("Exception creating output directory %s: %s" % (output, e), file=sys.stderr)
-
-    # public dir
-    for p in pyjs.path:
-        pub_dir = join(p, 'public')
-        if isdir(pub_dir):
-            print("Copying: public directory of library %r" % p)
-            copytree_exists(pub_dir, output)
-
-    # AppName.html - can be in current or public directory
-    html_input_filename = app_name + ".html"
-    html_output_filename = join(output, basename(html_input_filename))
-    if os.path.isfile(html_input_filename):
-        if not os.path.isfile(html_output_filename) or \
-               os.path.getmtime(html_input_filename) > \
-               os.path.getmtime(html_output_filename):
-            try:
-                shutil.copy(html_input_filename, html_output_filename)
-            except Exception:
-                print("Warning: Missing module HTML file %s" % html_input_filename, file=sys.stderr)
-
-            print("Copying: %(html_input_filename)s" % locals())
-
-    if check_html_file(html_input_filename, output):
-        print("Warning: Module HTML file %s has been auto-generated" % html_input_filename, file=sys.stderr)
-
-    # pygwt.js
-
-    print("Copying: pygwt.js")
-
-    pygwt_js_template = read_boilerplate(data_dir, "pygwt.js")
-    pygwt_js_output = open(join(output, "pygwt.js"), "w")
-
-    print(pygwt_js_template, file=pygwt_js_output)
-
-    pygwt_js_output.close()
-
-    # Images
-
-    print("Copying: Images and History")
-    copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_bottomleft_black.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_edge_black.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_topleft.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_topright.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_bottomright.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_bottomleft.png", output)
-    copy_boilerplate(data_dir, "corner_dialog_edge.png", output)
-    copy_boilerplate(data_dir, "tree_closed.gif", output)
-    copy_boilerplate(data_dir, "tree_open.gif", output)
-    copy_boilerplate(data_dir, "tree_white.gif", output)
-    copy_boilerplate(data_dir, "history.html", output)
-
-    # all.cache.html
-    app_files = generateAppFiles(data_dir, js_includes, app_name, debug,
-                                 output, dynamic, cache_buster, optimize)
-
-    # AppName.nocache.html
-
-    print("Creating: %(app_name)s.nocache.html" % locals())
-
-    home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html")
-    home_nocache_html_output = open(join(output, app_name + ".nocache.html"),
-                                    "w")
-
-    # the selector templ is added to the selectScript function
-    select_tmpl = """O(["true","%s"],"%s");"""
-    script_selectors = cStringIO()
-
-    for platform, file_prefix in app_files:
-        print(select_tmpl % (platform, file_prefix), file=script_selectors)
-
-    print(
-        home_nocache_html_template % dict(
-            app_name=app_name,
-            script_selectors=script_selectors.getvalue(),
-        ), file=home_nocache_html_output)
-
-    home_nocache_html_output.close()
-
-    print("Done. You can run your app by opening '%(html_output_filename)s' in a browser" % locals())
-
-
-def generateAppFiles(data_dir, js_includes, app_name, debug, output, dynamic,
-                     cache_buster, optimize):
-
-    all_cache_html_template = read_boilerplate(data_dir, "all.cache.html")
-    mod_cache_html_template = read_boilerplate(data_dir, "mod.cache.html")
-
-    # clean out the old ones first
-    for name in os.listdir(output):
-        if CACHE_HTML_PAT.match(name):
-            p = join(output, name)
-            print("Deleting existing app file %s" % p)
-            os.unlink(p)
-
-    app_files = []
-    parser = pyjs.PlatformParser("platform")
-    app_headers = ''
-    scripts = ['<script type="text/javascript" src="%s"></script>' %
-               script for script in js_includes]
-    app_body = '\n'.join(scripts)
-
-    mod_code = {}
-    mod_libs = {}
-    modules = {}
-    app_libs = {}
-    early_app_libs = {}
-    app_code = {}
-    overrides = {}
-    pover = {}
-    app_modnames = {}
-    mod_levels = {}
-
-    # First, generate all the code.
-    # Second, (dynamic only), post-analyse the places where modules
-    # haven't changed
-    # Third, write everything out.
-
-    for platform in app_platforms:
-
-        mod_code[platform] = {}
-        mod_libs[platform] = {}
-        modules[platform] = []
-        pover[platform] = {}
-        app_libs[platform] = ''
-        early_app_libs[platform] = ''
-        app_code[platform] = {}
-        app_modnames[platform] = {}
-
-        # Application.Platform.cache.html
-
-        parser.setPlatform(platform)
-        app_translator = pyjs.AppTranslator(
-            parser=parser, dynamic=dynamic, optimize=optimize)
-        early_app_libs[platform], appcode = \
-            app_translator.translate(None, is_app=False,
-                                     debug=debug,
-                                     library_modules=['dynamicajax.js',
-                                                      '_pyjs.js', 'sys',
-                                                      'pyjslib'])
-        pover[platform].update(app_translator.overrides.items())
-        for mname, name in app_translator.overrides.items():
-            pd = overrides.setdefault(mname, {})
-            pd[platform] = name
-
-        print(appcode)
-        # mod_code[platform][app_name] = appcode
-
-        # platform.Module.cache.js
-
-        modules_done = ['pyjslib', 'sys', '_pyjs.js']
-        # modules_to_do = [app_name] + app_translator.library_modules
-        modules_to_do = [app_name] + app_translator.library_modules
-
-        dependencies = {}
-
-        deps = map(pyjs.strip_py, modules_to_do)
-        for d in deps:
-            sublist = add_subdeps(dependencies, d)
-            modules_to_do += sublist
-        deps = uniquify(deps)
-        # dependencies[app_name] = deps
-
-        modules[platform] = modules_done + modules_to_do
-
-        while modules_to_do:
-
-            # print "modules to do", modules_to_do
-
-            mn = modules_to_do.pop()
-            mod_name = pyjs.strip_py(mn)
-
-            if mod_name in modules_done:
-                continue
-
-            modules_done.append(mod_name)
-
-            mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name)
-
-            parser.setPlatform(platform)
-            mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize)
-            mod_libs[platform][mod_name], mod_code[platform][mod_name] = \
-                mod_translator.translate(mod_name,
-                                         is_app=False,
-                                         debug=debug)
-            pover[platform].update(mod_translator.overrides.items())
-            for mname, name in mod_translator.overrides.items():
-                pd = overrides.setdefault(mname, {})
-                pd[platform] = name
-
-            mods = mod_translator.library_modules
-            modules_to_do += mods
-            modules[platform] += mods
-
-            deps = map(pyjs.strip_py, mods)
-            sd = subdeps(mod_name)
-            if len(sd) > 1:
-                deps += sd[:-1]
-            while mod_name in deps:
-                deps.remove(mod_name)
-
-            # print
-            # print
-            # print "modname preadd:", mod_name, deps
-            # print
-            # print
-            for d in deps:
-                sublist = add_subdeps(dependencies, d)
-                modules_to_do += sublist
-            modules_to_do += add_subdeps(dependencies, mod_name)
-            # print "modname:", mod_name, deps
-            deps = uniquify(deps)
-            # print "modname:", mod_name, deps
-            dependencies[mod_name] = deps
-
-        # work out the dependency ordering of the modules
-
-        mod_levels[platform] = make_deps(None, dependencies, modules_done)
-
-    # now write everything out
-
-    for platform in app_platforms:
-
-        early_app_libs_ = early_app_libs[platform]
-        app_libs_ = app_libs[platform]
-        app_code_ = app_code[platform]
-        # modules_ = filter_mods(app_name, modules[platform])
-        mods = flattenlist(mod_levels[platform])
-        mods.reverse()
-        modules_ = filter_mods(None, mods)
-
-        for mod_name in modules_:
-
-            mod_code_ = mod_code[platform][mod_name]
-
-            mod_name = pyjs.strip_py(mod_name)
-
-            override_name = "%s.%s" % (platform.lower(), mod_name)
-            if override_name in pover[platform]:
-                mod_cache_name = "%s.cache.js" % (override_name)
-            else:
-                mod_cache_name = "%s.cache.js" % (mod_name)
-
-            print("Creating: " + mod_cache_name)
-
-            modlevels = make_deps(None, dependencies, dependencies[mod_name])
-
-            modnames = []
-
-            for md in modlevels:
-                mnames = map(lambda x: "'%s'" % x, md)
-                mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
-                modnames.append(mnames)
-
-            modnames.reverse()
-            modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(modnames)
-
-            # convert the overrides
-
-            overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
-            overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
-
-            if dynamic:
-                mod_cache_html_output = open(join(output, mod_cache_name), "w")
-            else:
-                mod_cache_html_output = cStringIO()
-
-            print(mod_cache_html_template % dict(
-                mod_name=mod_name,
-                app_name=app_name,
-                modnames=modnames,
-                overrides=overnames,
-                mod_libs=mod_libs[platform][mod_name],
-                dynamic=dynamic,
-                mod_code=mod_code_,
-            ), file=mod_cache_html_output)
-
-            if dynamic:
-                mod_cache_html_output.close()
-            else:
-                mod_cache_html_output.seek(0)
-                app_libs_ += mod_cache_html_output.read()
-
-        # write out the dependency ordering of the modules
-
-        app_modnames = []
-
-        for md in mod_levels[platform]:
-            mnames = map(lambda x: "'%s'" % x, md)
-            mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
-            app_modnames.append(mnames)
-
-        app_modnames.reverse()
-        app_modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(app_modnames)
-
-        # convert the overrides
-
-        overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
-        overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
-
-        # print "platform names", platform, overnames
-        # print pover
-
-        # now write app.allcache including dependency-ordered list of
-        # library modules
-
-        file_contents = all_cache_html_template % dict(
-            app_name=app_name,
-            early_app_libs=early_app_libs_,
-            app_libs=app_libs_,
-            app_code=app_code_,
-            app_body=app_body,
-            overrides=overnames,
-            platform=platform.lower(),
-            dynamic=dynamic,
-            app_modnames=app_modnames,
-            app_headers=app_headers
-        )
-        if cache_buster:
-            digest = md5.new(file_contents).hexdigest()
-            file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
-        else:
-            file_name = "%s.%s" % (platform.lower(), app_name)
-        file_name += ".cache.html"
-        out_path = join(output, file_name)
-        out_file = open(out_path, 'w')
-        out_file.write(file_contents)
-        out_file.close()
-        app_files.append((platform.lower(), file_name))
-        print("Created app file %s:%s: %s" % (
-            app_name, platform, out_path))
-
-    return app_files
-
-
-def flattenlist(ll):
-    res = []
-    for l in ll:
-        res += l
-    return res
-
-
-def subdeps(m):
-    """
-    creates sub-dependencies e.g. pyjamas.ui.Widget
-    creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
-    """
-    d = []
-    m = m.split(".")
-    for i in range(0, len(m)):
-        d.append('.'.join(m[:i+1]))
-    return d
-
-
-def add_subdeps(deps, mod_name):
-    sd = subdeps(mod_name)
-    if len(sd) == 1:
-        return []
-    # print "subdeps", mod_name, sd
-    # print "deps", deps
-    res = []
-    for i in range(0, len(sd)-1):
-        parent = sd[i]
-        child = sd[i+1]
-        k = deps.get(child, [])
-        k.append(parent)
-        deps[child] = k
-        if parent not in res:
-            res.append(parent)
-    # print deps
-    return res
-
-
-def uniquify(md):
-    """
-    makes unique and preserves list order
-    """
-    res = []
-    for m in md:
-        if m not in res:
-            res.append(m)
-    return res
-
-
-def filter_mods(app_name, md):
-    while 'sys' in md:
-        md.remove('sys')
-    while 'pyjslib' in md:
-        md.remove('pyjslib')
-    while app_name in md:
-        md.remove(app_name)
-    md = filter(lambda x: not x.endswith('.js'), md)
-    md = map(pyjs.strip_py, md)
-
-    return uniquify(md)
-
-
-def filter_deps(app_name, deps):
-
-    res = {}
-    for (k, l) in deps.items():
-        mods = filter_mods(k, l)
-        while k in mods:
-            mods.remove(k)
-        res[k] = mods
-    return res
-
-
-def has_nodeps(mod, deps):
-    if mod not in deps or not deps[mod]:
-        return True
-    return False
-
-
-def nodeps_list(mod_list, deps):
-    res = []
-    for mod in mod_list:
-        if has_nodeps(mod, deps):
-            res.append(mod)
-    return res
-
-# this function takes a dictionary of dependent modules and
-# creates a list of lists.  the first list will be modules
-# that have no dependencies; the second list will be those
-# modules that have the first list as dependencies; the
-# third will be those modules that have the first and second...
-# etc.
-
-
-def make_deps(app_name, deps, mod_list):
-    print("Calculating Dependencies ...")
-    mod_list = filter_mods(app_name, mod_list)
-    deps = filter_deps(app_name, deps)
-
-    if not mod_list:
-        return []
-
-    # print mod_list
-    # print deps
-
-    ordered_deps = []
-    last_len = -1
-    while deps:
-        l_deps = len(deps)
-        # print l_deps
-        if l_deps == last_len:
-            for m, dl in deps.items():
-                for d in dl:
-                    if m in deps.get(d, []):
-                        raise Exception('Circular Imports found: \n%s %s -> %s %s'
-                                        % (m, dl, d, deps[d]))
-            # raise Exception('Could not calculate dependencies: \n%s' % deps)
-            break
-        last_len = l_deps
-        # print "modlist", mod_list
-        nodeps = nodeps_list(mod_list, deps)
-        # print "nodeps", nodeps
-        mod_list = filter(lambda x: x not in nodeps, mod_list)
-        newdeps = {}
-        for k in deps.keys():
-            depslist = deps[k]
-            depslist = filter(lambda x: x not in nodeps, depslist)
-            if depslist:
-                newdeps[k] = depslist
-        # print "newdeps", newdeps
-        deps = newdeps
-        ordered_deps.append(nodeps)
-        # time.sleep(0)
-
-    if mod_list:
-        ordered_deps.append(mod_list)  # last dependencies - usually the app(s)
-
-    ordered_deps.reverse()
-
-    return ordered_deps
-
-
-def main():
-    global app_platforms
-
-    parser = OptionParser(usage=usage, version=version)
-    parser.add_option(
-        "-o",
-        "--output",
-        dest="output",
-        help="directory to which the webapp should be written"
-    )
-    parser.add_option(
-        "-j",
-        "--include-js",
-        dest="js_includes",
-        action="append",
-        help="javascripts to load into the same frame as the rest of the script"
-    )
-    parser.add_option(
-        "-I",
-        "--library_dir",
-        dest="library_dirs",
-        action="append",
-        help="additional paths appended to PYJSPATH"
-    )
-    parser.add_option(
-        "-D",
-        "--data_dir",
-        dest="data_dir",
-        help="path for data directory"
-    )
-    parser.add_option(
-        "-m",
-        "--dynamic-modules",
-        action="store_true",
-        dest="dynamic",
-        default=False,
-        help="Split output into separate dynamically-loaded modules (experimental)"
-    )
-    parser.add_option(
-        "-P",
-        "--platforms",
-        dest="platforms",
-        help="platforms to build for, comma-separated"
-    )
-    parser.add_option(
-        "-d",
-        "--debug",
-        action="store_true",
-        dest="debug"
-    )
-    parser.add_option(
-        "-O",
-        "--optimize",
-        action="store_true",
-        dest="optimize",
-        default=False,
-        help="Optimize generated code (removes all print statements)",
-    )
-    parser.add_option(
-        "-c",
-        "--cache_buster",
-        action="store_true",
-        dest="cache_buster",
-        help="Enable browser cache-busting (MD5 hash added to output filenames)"
-    )
-
-    parser.set_defaults(output="output", js_includes=[], library_dirs=[],
-                        platforms=(','.join(app_platforms)),
-                        data_dir=os.path.join(sys.prefix, "share/pyjamas"),
-                        dynamic=False,
-                        cache_buster=False,
-                        debug=False)
-    (options, args) = parser.parse_args()
-    if len(args) != 1:
-        parser.error("incorrect number of arguments")
-
-    data_dir = abspath(options.data_dir)
-
-    app_path = args[0]
-    if app_path.endswith('.py'):
-        app_path = abspath(app_path)
-        if not isfile(app_path):
-            parser.error("Application file not found %r" % app_path)
-        app_path, app_name = split(app_path)
-        app_name = app_name[:-3]
-        pyjs.path.append(app_path)
-    elif os.path.sep in app_path:
-        parser.error("Not a valid module declaration %r" % app_path)
-    else:
-        app_name = app_path
-
-    for d in options.library_dirs:
-        pyjs.path.append(abspath(d))
-
-    if options.platforms:
-        app_platforms = options.platforms.split(',')
-
-    # this is mostly for getting boilerplate stuff
-    data_dir = os.path.abspath(options.data_dir)
-
-    build(app_name, options.output, options.js_includes,
-          options.debug, options.dynamic and 1 or 0, data_dir,
-          options.cache_buster, options.optimize)
-
-
-if __name__ == "__main__":
-    main()