Beispiel #1
0
    def run(self):
        if not self.web_ext_modules:
            return

        ## Make sure that extension sources are complete.
        self.run_command('build_src')
        build = self.get_finalized_command('build')
        environ = self.distribution.environment

        for wext in self.web_ext_modules:
            if self.distribution.verbose:
                print('building web extension "' + \
                    os.path.join(wext.public_subdir, wext.name) + '" sources')

            target = os.path.abspath(os.path.join(options.target_build_dir,
                                                  'http', wext.public_subdir))
            mkdir(target)
            here = os.getcwd()
            src_dir = os.path.abspath(wext.source_directory)
            working_dir = os.path.abspath(os.path.join(build.build_temp,
                                                       'web', wext.name))
            mkdir(working_dir)

            for support in wext.extra_support_files:
                src_file = os.path.join(CLIENT_SUPPORT_DIR, support + '.in')
                if not os.path.exists(src_file):
                    src_file = src_file[:-3]
                dst_file = os.path.join(working_dir, support)
                configure_file(environ, src_file, dst_file)

            reprocess = True
            ref = os.path.join(target, wext.name + '.html')
            if os.path.exists(ref) and not self.force:
                reprocess = False
                for src in wext.sources:
                    if os.path.getmtime(ref) < os.path.getmtime(src):
                        reprocess = True
            if reprocess:
                ## Special handling for 'public' directory
                configure_files(environ, os.path.join(src_dir, 'public'),
                                '*', os.path.join(working_dir, 'public'),
                                excludes=['.svn', 'CVS'])

                if len(wext.sources) > 0:
                    for s in wext.sources:
                        configure_file(environ, s,
                                       os.path.join(working_dir,
                                                    os.path.basename(s)))
                    #import pyjs  # pylint: disable=F0401,W0611,W0612
                    ## TODO: use pyjs module directly (instead of 'pyjsbuild')
                    try:
                        compiler = environ['PYJSBUILD']
                    except KeyError:
                        compiler = self.pyjscompiler
                    if compiler is None:
                        env = configure_package('pyjamas')
                        compiler = env['PYJSBUILD']
                        if compiler is None:
                            raise DistutilsExecError("no pyjsbuild executable found or given")
                    cmd_line = [os.path.abspath(compiler)]
                    for arg in wext.extra_compile_args:
                        if 'debug' in arg.lower():
                            cmd_line.append('--debug')
                            cmd_line.append('--print-statements')
                        else:
                            cmd_line.append(arg)
                    if self.distribution.verbose:
                        cmd_line.append('--log-level=' + str(logging.INFO))
                    else:
                        cmd_line.append('--log-level=' + str(logging.ERROR))
                    cmd_line.append('--output=' + target)
                    cmd_line.append(wext.name)

                    os.chdir(working_dir)
                    status = subprocess.call(cmd_line)
                    if status != 0:
                        raise Exception("Command '" + str(cmd_line) +
                                        "' returned non-zero exit status "
                                        + str(status))
                    os.chdir(here)

            pubdir = os.path.join(working_dir, 'public')
            excludes = ['.svn', 'CVS']
            if len(wext.sources) < 1:  ## PYJS did not run
                copy_tree(pubdir, target, excludes=excludes,
                          verbose=self.distribution.verbose)

            for filename in wext.extra_public_files:
                filepath = os.path.join(CLIENT_SUPPORT_DIR, filename + '.in')
                if not os.path.exists(filepath):
                    filepath = filepath[:-3]
                targetfile = os.path.join(target, filename)
                if '.js' in filename:
                    targetfile = os.path.join(target,
                                              options.javascript_dir, filename)
                if '.css' in filename:
                    targetfile = os.path.join(target,
                                              options.stylesheet_dir, filename)
                if not os.path.exists(targetfile):
                    configure_file(environ, filepath, targetfile)

            ## Copy over downloaded files
            js_dir = os.path.join(options.target_build_dir,
                                  options.javascript_dir)
            if os.path.exists(js_dir):
                copy_tree(js_dir, os.path.join(target, options.javascript_dir))
            css_dir = os.path.join(options.target_build_dir,
                                   options.stylesheet_dir)
            if os.path.exists(css_dir):
                copy_tree(css_dir, os.path.join(target, options.stylesheet_dir))
            php_dir = os.path.join(options.target_build_dir, options.script_dir)
            if os.path.exists(php_dir):
                copy_tree(php_dir, target)

            ## pyjs processing ignores hidden files in public
            hidden = []
            for root, _, filenames in os.walk(pubdir):
                for ex in excludes:
                    if fnmatch.fnmatch(root, ex):
                        continue
                for filename in fnmatch.filter(filenames, ".??*"):
                    hidden.append(os.path.join(root[len(pubdir)+1:], filename))
            for filepath in hidden:
                targetfile = os.path.join(target, filepath)
                if not os.path.exists(targetfile):
                    shutil.copyfile(os.path.join(pubdir, filepath), targetfile)

            stat_info = os.stat(os.path.join(src_dir, 'public'))
            uid = stat_info.st_uid
            gid = stat_info.st_gid
            recursive_chown(target, uid, gid)

            if not os.path.lexists(os.path.join(target, 'index.html')) and \
                    os.path.lexists(os.path.join(target, wext.name + '.html')):
                shutil.copyfile(os.path.join(target, wext.name + '.html'),
                                os.path.join(target, 'index.html'))
            if not os.path.lexists(os.path.join(target, 'index.php')) and \
                    os.path.lexists(os.path.join(target, wext.name + '.php')):
                shutil.copyfile(os.path.join(target, wext.name + '.php'),
                                os.path.join(target, 'index.php'))
    def run(self):
        if not self.distribution.doc_modules:
            return

        ## Make sure that sources are complete in build_lib.
        self.run_command('build_src')
        ## Ditto extensions
        self.run_command('build_ext')

        build = self.get_finalized_command('build')
        buildpy = self.get_finalized_command('build_py')
        ## packages and files are in build.build_lib (see build_py.py)
        target = os.path.join(os.path.abspath(build.build_base), 'http')
        mkdir(target)
        build_verbose = self.distribution.verbose
        environ = self.distribution.environment

        for dext in self.distribution.doc_modules:
            if self.distribution.verbose:
                print('building documentation "' + dext.name + '" sources')

            doc_dir = os.path.abspath(dext.source_directory)
            extra_dirs = dext.extra_directories
            src_dir = os.path.abspath(dext.name)
            here = os.getcwd()

            reprocess = True
            ref = os.path.join(target, dext.name + '.html')
            root_dir = dext.name
            if os.path.exists(ref) and not self.force:
                reprocess = False
                for root, _, filenames in os.walk(src_dir):
                    for fn in fnmatch.filter(filenames, '*.rst'):
                        doc = os.path.join(root, fn)
                        if os.path.getmtime(ref) < os.path.getmtime(doc):
                            reprocess = True
                            break
                        src = os.path.join(root_dir, root[len(doc_dir)+1:],
                                            fn[:-3] + 'py')
                        if os.path.exists(src):
                            if os.path.getmtime(ref) < os.path.getmtime(src):
                                reprocess = True
                                break
            if reprocess:
                working_dir = os.path.abspath(build.build_lib)
                for package in buildpy.packages:
                    pkgdir = buildpy.get_package_dir(package)
                    pkgsrcdir = os.path.join(os.path.dirname(src_dir), pkgdir)
                    configure_files(environ, pkgsrcdir,
                                    '*.rst', os.path.join(working_dir, pkgdir))

                cfg_dir = os.path.join(working_dir, dext.source_directory)
                environ['BUILD_DIR'] = working_dir

                copy_tree(doc_dir, working_dir, True,
                          excludes=[dext.name, '.svn', 'CVS', '.git', '.hg*'])
                copy_tree(os.path.join(doc_dir, dext.name),
                          os.path.join(cfg_dir, dext.name), True,
                          excludes=['.svn', 'CVS', '.git', '.hg*'])
                for d in extra_dirs:
                    subdir = os.path.basename(os.path.normpath(d))
                    copy_tree(d, os.path.join(target, subdir), True,
                              excludes=['.svn', 'CVS', '.git', '.hg*'])

                if os.path.exists(os.path.join(doc_dir, dext.doxygen_cfg)):
                    ## Doxygen + breathe
                    print('Config ' + os.path.join(doc_dir, dext.doxygen_cfg))
                    configure_file(environ,
                                   os.path.join(doc_dir, dext.doxygen_cfg),
                                   os.path.join(working_dir, dext.doxygen_cfg),
                                   style=dext.style)
                    for s in dext.doxygen_srcs:
                        configure_file(environ,
                                       os.path.join(doc_dir, s),
                                       os.path.join(working_dir, s),
                                       style=dext.style)
                    try:
                        doxygen_exe = find_program('doxygen')
                    except Exception:  # pylint: disable=W0703
                        sys.stderr.write('ERROR: Doxygen not installed ' +
                                         '(required for documentation).\n')
                        return

                    reprocess = True
                    ref = os.path.join(working_dir, 'html', 'index.html')
                    if os.path.exists(ref) and not self.force:
                        reprocess = False
                        for d in environ['C_SOURCE_DIRS'].split(' '):
                            for orig in glob.glob(os.path.join(d, '*.h*')):
                                if os.path.getmtime(ref) < \
                                   os.path.getmtime(orig):
                                    reprocess = True
                                    break
                    if reprocess:
                        if self.distribution.verbose:
                            out = sys.stdout
                            err = sys.stderr
                        else:
                            out = err = open('doxygen.log', 'w')
                        os.chdir(working_dir)
                        cmd_line = [doxygen_exe, dext.doxygen_cfg]
                        status = subprocess.call(cmd_line,
                                                 stdout=out, stderr=err)
                        if status != 0:
                            raise Exception("Command '" + str(cmd_line) +
                                            "' returned non-zero exit status "
                                            + str(status))

                        if not self.distribution.verbose:
                            out.close()
                        copy_tree('html', os.path.join(target, 'html'), True,
                                  excludes=['.svn', 'CVS', '.git', '.hg*'])
                        copy_tree('xml', os.path.join(cfg_dir, 'xml'), True)
                        os.chdir(here)
                        create_breathe_stylesheet(target)

                for f in dext.extra_docs:
                    shutil.copy(os.path.join(doc_dir, f), target)

                ## Sphinx
                if dext.without_sphinx:
                    return
                if dext.sphinx_config is None:
                    level_up = os.path.dirname(os.path.dirname(__file__))
                    dext.sphinx_config = os.path.join(level_up,
                                                      'sphinx_conf.py.in')
                elif os.path.dirname(dext.sphinx_config) == '':
                    dext.sphinx_config =  os.path.join(doc_dir,
                                                       dext.sphinx_config)
                configure_file(environ, dext.sphinx_config,
                               os.path.join(cfg_dir, 'conf.py'))
                import warnings
                try:
                    import sphinx  # pylint: disable=W0612
                except ImportError:
                    configure_package('breathe')  ## requires sphinx
                    sys.path.insert(0, os.path.join(options.target_build_dir,
                                                    options.local_lib_dir))

                from sphinx.application import Sphinx
                if 'windows' in platform.system().lower() or \
                   not build_verbose:
                    from sphinx.util.console import nocolor
                warnings.filterwarnings("ignore",
                                        category=PendingDeprecationWarning)
                warnings.filterwarnings("ignore", category=UserWarning)

                status = sys.stdout
                if not build_verbose:
                    status = open('sphinx.log', 'w')
                if 'windows' in platform.system().lower() or not build_verbose:
                    nocolor()
                try:
                    ## args: srcdir, confdir, outdir, doctreedir, buildername
                    sphinx_app = Sphinx(os.path.join(working_dir, dext.name),
                                        cfg_dir, target,
                                        os.path.join(target, '.doctrees'),
                                        'html', status=status)
                    sphinx_app.build(force_all=True, filenames=None)
                except Exception:  # pylint: disable=W0703
                    if build_verbose:
                        print('ERROR: ' + str(sys.exc_info()[1]))
                    else:
                        pass
                if not build_verbose:
                    status.close()
                warnings.resetwarnings()