예제 #1
0
파일: goal.py 프로젝트: pkwarren/commons
    def console_output(self, targets):
        DONE = "__done_reporting"

        port = ReportingServerManager.get_current_server_port()
        if port:
            return ["Server already running at http://localhost:%d" % port]

        def run_server(reporting_queue):
            def report_launch(actual_port):
                reporting_queue.put("Launching server with pid %d at http://localhost:%d" % (os.getpid(), actual_port))

            def done_reporting():
                reporting_queue.put(DONE)

            try:
                # We mustn't block in the child, because the multiprocessing module enforces that the
                # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue
                # but is allowed to block indefinitely on the server loop.
                if not os.fork():
                    # Child process.
                    info_dir = self.context.config.getdefault("info_dir")
                    # If these are specified explicitly in the config, use those. Otherwise
                    # they will be None, and we'll use the ones baked into this package.
                    template_dir = self.context.config.get("reporting", "reports_template_dir")
                    assets_dir = self.context.config.get("reporting", "reports_assets_dir")
                    settings = ReportingServer.Settings(
                        info_dir=info_dir,
                        template_dir=template_dir,
                        assets_dir=assets_dir,
                        root=get_buildroot(),
                        allowed_clients=self.context.options.allowed_clients,
                    )
                    server = ReportingServer(self.context.options.port, settings)
                    actual_port = server.server_port()
                    ReportingServerManager.save_current_server_port(actual_port)
                    report_launch(actual_port)
                    done_reporting()
                    # Block forever here.
                    server.start()
            except socket.error:
                done_reporting()
                raise

        # We do reporting on behalf of the child process (necessary, since reporting may be buffered in a
        # background thread). We use multiprocessing.Process() to spawn the child so we can use that
        # module's inter-process Queue implementation.
        reporting_queue = multiprocessing.Queue()
        proc = multiprocessing.Process(target=run_server, args=[reporting_queue])
        proc.daemon = True
        proc.start()
        s = reporting_queue.get()
        ret = []
        while s != DONE:
            ret.append(s)
            s = reporting_queue.get()
        # The child process is done reporting, and is now in the server loop, so we can proceed.
        server_port = ReportingServerManager.get_current_server_port()
        if server_port:
            binary_util.ui_open("http://localhost:%d/run/latest" % server_port)
        return ret
예제 #2
0
  def execute(self, targets):
    pages = []
    for target in targets:
      if isinstance(target, Page):
        wikiconfig = target.wiki_config(self.wiki())
        if wikiconfig:
          pages.append((target, wikiconfig))

    urls = list()

    genmap = self.context.products.get('wiki_html')
    for page, wikiconfig in pages:
      html_info = genmap.get((self.wiki(), page))
      if len(html_info) > 1:
        raise TaskError('Unexpected resources for %s: %s' % (page, html_info))
      basedir, htmls = html_info.items()[0]
      if len(htmls) != 1:
        raise TaskError('Unexpected resources for %s: %s' % (page, htmls))
      with safe_open(os.path.join(basedir, htmls[0])) as contents:
        url = self.publish_page(
          page.address,
          wikiconfig['space'],
          wikiconfig['title'],
          contents.read(),
          parent=wikiconfig.get('parent')
        )
        if url:
          urls.append(url)
          self.context.log.info('Published %s to %s' % (page, url))

    if self.open and urls:
      binary_util.ui_open(*urls)
예제 #3
0
파일: ide_gen.py 프로젝트: ssalevan/commons
  def execute(self, targets):
    """Stages IDE project artifacts to a project directory and generates IDE configuration files."""
    checkstyle_enabled = len(Phase.goals_of_type(Checkstyle)) > 0
    checkstyle_classpath = \
      self._bootstrap_utils.get_jvm_build_tools_classpath(self.checkstyle_bootstrap_key) \
      if checkstyle_enabled else []
    scalac_classpath = \
      self._bootstrap_utils.get_jvm_build_tools_classpath(self.scalac_bootstrap_key) \
      if self.scalac_bootstrap_key else []

    targets, self._project = self.configure_project(
      targets,
      self.checkstyle_suppression_files,
      self.debug_port)

    self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath)

    self.configure_compile_context(targets)

    self.map_internal_jars(targets)
    self.map_external_jars()

    idefile = self.generate_project(self._project)
    if idefile:
      binary_util.ui_open(idefile)
예제 #4
0
                    def generate_reports():
                        args = [
                            'report', '-in', self.coverage_metadata_file,
                            '-in', self.coverage_file, '-exit'
                        ]
                        source_bases = set()

                        def collect_source_base(target):
                            if self.is_coverage_target(target):
                                source_bases.add(target.target_base)

                        for target in self.test_target_candidates(targets):
                            target.walk(collect_source_base)
                        for source_base in source_bases:
                            args.extend(['-sp', source_base])

                        sorting = [
                            '-Dreport.sort', '+name,+class,+method,+block'
                        ]
                        if self.coverage_report_console:
                            args.extend([
                                '-r', 'txt',
                                '-Dreport.txt.out.file=%s' %
                                self.coverage_console_file
                            ] + sorting)
                        if self.coverage_report_xml:
                            args.extend([
                                '-r', 'xml',
                                '-Dreport.xml.out.file=%s' %
                                self.coverage_xml_file
                            ])
                        if self.coverage_report_html:
                            args.extend([
                                '-r', 'html',
                                '-Dreport.html.out.file=%s' %
                                self.coverage_html_file,
                                '-Dreport.out.encoding=UTF-8'
                            ] + sorting)

                        main = 'emma'
                        result = execute_java(
                            classpath=emma_classpath,
                            main=main,
                            args=args,
                            workunit_factory=self.context.new_workunit,
                            workunit_name='emma-report')
                        if result != 0:
                            raise TaskError(
                                "java %s ... exited non-zero (%i)"
                                " 'failed to generate code coverage reports'" %
                                (main, result))

                        if self.coverage_report_console:
                            with safe_open(self.coverage_console_file
                                           ) as console_report:
                                sys.stdout.write(console_report.read())
                        if self.coverage_report_html_open:
                            binary_util.ui_open(self.coverage_html_file)
예제 #5
0
파일: ide_gen.py 프로젝트: xianxu/pants
    def execute(self, targets):
        """Stages IDE project artifacts to a project directory and generates IDE configuration files."""

        self.map_internal_jars(targets)
        self.map_external_jars()

        idefile = self.generate_project(self._project)
        if idefile:
            binary_util.ui_open(idefile)
예제 #6
0
    def _generate_ivy_report(self, targets):
        def make_empty_report(report, organisation, module, conf):
            no_deps_xml_template = """
        <?xml version="1.0" encoding="UTF-8"?>
        <?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?>
        <ivy-report version="1.0">
          <info
            organisation="%(organisation)s"
            module="%(module)s"
            revision="latest.integration"
            conf="%(conf)s"
            confs="%(conf)s"
            date="%(timestamp)s"/>
        </ivy-report>
      """
            no_deps_xml = no_deps_xml_template % dict(
                organisation=organisation,
                module=module,
                conf=conf,
                timestamp=time.strftime('%Y%m%d%H%M%S'))
            with open(report, 'w') as report_handle:
                print(no_deps_xml, file=report_handle)

        classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(
            self._ivy_bootstrap_key, self.create_java_executor())

        reports = []
        org, name = self._ivy_utils.identify(targets)
        xsl = os.path.join(self._cachedir, 'ivy-report.xsl')

        # Xalan needs this dir to exist - ensure that, but do no more - we have no clue where this
        # points.
        safe_mkdir(self._outdir, clean=False)

        for conf in self._confs:
            params = dict(org=org, name=name, conf=conf)
            xml = self._ivy_utils.xml_report_path(targets, conf)
            if not os.path.exists(xml):
                make_empty_report(xml, org, name, conf)
            out = os.path.join(self._outdir,
                               '%(org)s-%(name)s-%(conf)s.html' % params)
            args = ['-IN', xml, '-XSL', xsl, '-OUT', out]
            if 0 != self.runjava(classpath=classpath,
                                 main='org.apache.xalan.xslt.Process',
                                 args=args,
                                 workunit_name='report'):
                raise TaskError
            reports.append(out)

        css = os.path.join(self._outdir, 'ivy-report.css')
        if os.path.exists(css):
            os.unlink(css)
        shutil.copy(os.path.join(self._cachedir, 'ivy-report.css'),
                    self._outdir)

        if self._open:
            binary_util.ui_open(*reports)
예제 #7
0
  def execute(self, targets):
    """Stages IDE project artifacts to a project directory and generates IDE configuration files."""

    self.map_internal_jars(targets)
    self.map_external_jars()

    idefile = self.generate_project(self._project)
    if idefile:
      binary_util.ui_open(idefile)
예제 #8
0
  def console_output(self, targets):
    DONE = '__done_reporting'

    port = ReportingServerManager.get_current_server_port()
    if port:
      return ['Server already running at http://localhost:%d' % port]

    def run_server(reporting_queue):
      def report_launch(actual_port):
        reporting_queue.put(
          'Launching server with pid %d at http://localhost:%d' % (os.getpid(), actual_port))

      def done_reporting():
        reporting_queue.put(DONE)

      try:
        # We mustn't block in the child, because the multiprocessing module enforces that the
        # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue
        # but is allowed to block indefinitely on the server loop.
        if not os.fork():
          # Child process.
          info_dir = RunInfo.dir(self.context.config)
          # If these are specified explicitly in the config, use those. Otherwise
          # they will be None, and we'll use the ones baked into this package.
          template_dir = self.context.config.get('reporting', 'reports_template_dir')
          assets_dir = self.context.config.get('reporting', 'reports_assets_dir')
          settings = ReportingServer.Settings(info_dir=info_dir, template_dir=template_dir,
                                              assets_dir=assets_dir, root=get_buildroot(),
                                              allowed_clients=self.context.options.allowed_clients)
          server = ReportingServer(self.context.options.port, settings)
          actual_port = server.server_port()
          ReportingServerManager.save_current_server_port(actual_port)
          report_launch(actual_port)
          done_reporting()
          # Block forever here.
          server.start()
      except socket.error:
        done_reporting()
        raise

    # We do reporting on behalf of the child process (necessary, since reporting may be buffered in a
    # background thread). We use multiprocessing.Process() to spawn the child so we can use that
    # module's inter-process Queue implementation.
    reporting_queue = multiprocessing.Queue()
    proc = multiprocessing.Process(target=run_server, args=[reporting_queue])
    proc.daemon = True
    proc.start()
    s = reporting_queue.get()
    ret = []
    while s != DONE:
      ret.append(s)
      s = reporting_queue.get()
    # The child process is done reporting, and is now in the server loop, so we can proceed.
    server_port = ReportingServerManager.get_current_server_port()
    if server_port:
      binary_util.ui_open('http://localhost:%d/run/latest' % server_port)
    return ret
예제 #9
0
 def _generate_combined(self, classpath, targets, create_jvmdoc_command):
   gendir = os.path.join(self._output_dir, 'combined')
   if targets:
     safe_mkdir(gendir, clean=True)
     command = create_jvmdoc_command(classpath, gendir, *targets)
     if command:
       create_jvmdoc(command, gendir)
   if self.open:
     binary_util.ui_open(os.path.join(gendir, 'index.html'))
예제 #10
0
 def _generate_combined(self, classpath, targets, create_jvmdoc_command):
   gendir = os.path.join(self._output_dir, 'combined')
   if targets:
     safe_mkdir(gendir, clean=True)
     command = create_jvmdoc_command(classpath, gendir, *targets)
     if command:
       create_jvmdoc(command, gendir)
   if self.open:
     binary_util.ui_open(os.path.join(gendir, 'index.html'))
예제 #11
0
                    def generate_reports():
                        opts = [
                            'report', '-in', self.coverage_metadata_file,
                            '-in', self.coverage_file, '-exit'
                        ]
                        source_bases = set()

                        def collect_source_base(target):
                            if self.is_coverage_target(target):
                                source_bases.add(target.target_base)

                        for target in self.test_target_candidates(targets):
                            target.walk(collect_source_base)
                        for source_base in source_bases:
                            opts.extend(['-sp', source_base])

                        sorting = [
                            '-Dreport.sort', '+name,+class,+method,+block'
                        ]
                        if self.coverage_report_console:
                            opts.extend([
                                '-r', 'txt',
                                '-Dreport.txt.out.file=%s' %
                                self.coverage_console_file
                            ] + sorting)
                        if self.coverage_report_xml:
                            opts.extend([
                                '-r', 'xml',
                                '-Dreport.xml.out.file=%s' %
                                self.coverage_xml_file
                            ])
                        if self.coverage_report_html:
                            opts.extend([
                                '-r', 'html',
                                '-Dreport.html.out.file=%s' %
                                self.coverage_html_file,
                                '-Dreport.out.encoding=UTF-8'
                            ] + sorting)

                        result = binary_util.runjava_indivisible(
                            classpath=emma_classpath,
                            main='emma',
                            opts=opts,
                            workunit_name='emma')
                        if result != 0:
                            raise TaskError(
                                'Failed to emma generate code coverage reports: %d'
                                % result)

                        if self.coverage_report_console:
                            with safe_open(self.coverage_console_file
                                           ) as console_report:
                                sys.stdout.write(console_report.read())
                        if self.coverage_report_html_open:
                            binary_util.ui_open(self.coverage_html_file)
예제 #12
0
  def _generate_ivy_report(self, targets):
    def make_empty_report(report, organisation, module, conf):
      no_deps_xml_template = """
        <?xml version="1.0" encoding="UTF-8"?>
        <?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?>
        <ivy-report version="1.0">
          <info
            organisation="%(organisation)s"
            module="%(module)s"
            revision="latest.integration"
            conf="%(conf)s"
            confs="%(conf)s"
            date="%(timestamp)s"/>
        </ivy-report>
      """
      no_deps_xml = no_deps_xml_template % dict(organisation=organisation,
                                                module=module,
                                                conf=conf,
                                                timestamp=time.strftime('%Y%m%d%H%M%S'))
      with open(report, 'w') as report_handle:
        print(no_deps_xml, file=report_handle)

    classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(self._ivy_bootstrap_key,
                                                                   self.create_java_executor())

    reports = []
    org, name = self._ivy_utils.identify(targets)
    xsl = os.path.join(self._cachedir, 'ivy-report.xsl')

    # Xalan needs this dir to exist - ensure that, but do no more - we have no clue where this
    # points.
    safe_mkdir(self._outdir, clean=False)

    for conf in self._confs:
      params = dict(org=org, name=name, conf=conf)
      xml = self._ivy_utils.xml_report_path(targets, conf)
      if not os.path.exists(xml):
        make_empty_report(xml, org, name, conf)
      out = os.path.join(self._outdir, '%(org)s-%(name)s-%(conf)s.html' % params)
      args = ['-IN', xml, '-XSL', xsl, '-OUT', out]
      if 0 != self.runjava(classpath=classpath, main='org.apache.xalan.xslt.Process',
                           args=args, workunit_name='report'):
        raise TaskError
      reports.append(out)

    css = os.path.join(self._outdir, 'ivy-report.css')
    if os.path.exists(css):
      os.unlink(css)
    shutil.copy(os.path.join(self._cachedir, 'ivy-report.css'), self._outdir)

    if self._open:
      binary_util.ui_open(*reports)
예제 #13
0
    def _generate_ivy_report(self):
        def make_empty_report(report, organisation, module, conf):
            no_deps_xml = """<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?>
<ivy-report version="1.0">
	<info
		organisation="%(organisation)s"
		module="%(module)s"
		revision="latest.integration"
		conf="%(conf)s"
		confs="%(conf)s"
		date="%(timestamp)s"/>
</ivy-report>""" % dict(organisation=organisation,
                        module=module,
                        conf=conf,
                        timestamp=time.strftime('%Y%m%d%H%M%S'))
            with open(report, 'w') as report_handle:
                print(no_deps_xml, file=report_handle)

        classpath = self.profile_classpath(self._profile)

        reports = []
        org, name = self._ivy_utils.identify()
        xsl = os.path.join(self._cachedir, 'ivy-report.xsl')
        safe_mkdir(self._outdir, clean=True)
        for conf in self._confs:
            params = dict(org=org, name=name, conf=conf)
            xml = os.path.join(self._cachedir,
                               '%(org)s-%(name)s-%(conf)s.xml' % params)
            if not os.path.exists(xml):
                make_empty_report(xml, org, name, conf)
            #xml = self._ivy_utils.xml_report_path(conf)
            out = os.path.join(self._outdir,
                               '%(org)s-%(name)s-%(conf)s.html' % params)
            opts = ['-IN', xml, '-XSL', xsl, '-OUT', out]
            if 0 != self.runjava_indivisible('org.apache.xalan.xslt.Process',
                                             classpath=classpath,
                                             opts=opts,
                                             workunit_name='report'):
                raise TaskError
            reports.append(out)

        css = os.path.join(self._outdir, 'ivy-report.css')
        if os.path.exists(css):
            os.unlink(css)
        shutil.copy(os.path.join(self._cachedir, 'ivy-report.css'),
                    self._outdir)

        if self._open:
            binary_util.ui_open(*reports)
예제 #14
0
  def _generate_ivy_report(self):
    def make_empty_report(report, organisation, module, conf):
      no_deps_xml = """<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ivy-report.xsl"?>
<ivy-report version="1.0">
	<info
		organisation="%(organisation)s"
		module="%(module)s"
		revision="latest.integration"
		conf="%(conf)s"
		confs="%(conf)s"
		date="%(timestamp)s"/>
</ivy-report>""" % dict(organisation=organisation,
                        module=module,
                        conf=conf,
                        timestamp=time.strftime('%Y%m%d%H%M%S'))
      with open(report, 'w') as report_handle:
        print(no_deps_xml, file=report_handle)

    classpath = self.profile_classpath(self._profile)

    reports = []
    org, name = self._ivy_utils.identify()
    xsl = os.path.join(self._cachedir, 'ivy-report.xsl')
    safe_mkdir(self._outdir, clean=True)
    for conf in self._confs:
      params = dict(
        org=org,
        name=name,
        conf=conf
      )
      xml = os.path.join(self._cachedir, '%(org)s-%(name)s-%(conf)s.xml' % params)
      if not os.path.exists(xml):
        make_empty_report(xml, org, name, conf)
      #xml = self._ivy_utils.xml_report_path(conf)
      out = os.path.join(self._outdir, '%(org)s-%(name)s-%(conf)s.html' % params)
      opts = ['-IN', xml, '-XSL', xsl, '-OUT', out]
      if 0 != self.runjava_indivisible('org.apache.xalan.xslt.Process', classpath=classpath,
                                       opts=opts, workunit_name='report'):
        raise TaskError
      reports.append(out)

    css = os.path.join(self._outdir, 'ivy-report.css')
    if os.path.exists(css):
      os.unlink(css)
    shutil.copy(os.path.join(self._cachedir, 'ivy-report.css'), self._outdir)

    if self._open:
      binary_util.ui_open(*reports)
예제 #15
0
          def generate_reports():
            opts = [
              'report',
              '-in', self.coverage_metadata_file,
              '-in', self.coverage_file,
              '-exit'
            ]
            source_bases = set()
            def collect_source_base(target):
              if self.is_coverage_target(target):
                source_bases.add(target.target_base)
            for target in self.test_target_candidates(targets):
              target.walk(collect_source_base)
            for source_base in source_bases:
              opts.extend(['-sp', source_base])

            sorting = ['-Dreport.sort', '+name,+class,+method,+block']
            if self.coverage_report_console:
              opts.extend(['-r', 'txt',
                           '-Dreport.txt.out.file=%s' % self.coverage_console_file] + sorting)
            if self.coverage_report_xml:
              opts.extend(['-r', 'xml','-Dreport.xml.out.file=%s' % self.coverage_xml_file])
            if self.coverage_report_html:
              opts.extend(['-r', 'html',
                           '-Dreport.html.out.file=%s' % self.coverage_html_file,
                           '-Dreport.out.encoding=UTF-8'] + sorting)

            result = binary_util.runjava_indivisible(
              classpath=emma_classpath,
              main='emma',
              opts=opts,
              workunit_name='emma'
            )
            if result != 0:
              raise TaskError('Failed to emma generate code coverage reports: %d' % result)

            if self.coverage_report_console:
              with safe_open(self.coverage_console_file) as console_report:
                sys.stdout.write(console_report.read())
            if self.coverage_report_html_open:
              binary_util.ui_open(self.coverage_html_file)
예제 #16
0
          def generate_reports():
            args = [
              'report',
              '-in', self.coverage_metadata_file,
              '-in', self.coverage_file,
              '-exit'
            ]
            source_bases = set()
            def collect_source_base(target):
              if self.is_coverage_target(target):
                source_bases.add(target.target_base)
            for target in self.test_target_candidates(targets):
              target.walk(collect_source_base)
            for source_base in source_bases:
              args.extend(['-sp', source_base])

            sorting = ['-Dreport.sort', '+name,+class,+method,+block']
            if self.coverage_report_console:
              args.extend(['-r', 'txt',
                           '-Dreport.txt.out.file=%s' % self.coverage_console_file] + sorting)
            if self.coverage_report_xml:
              args.extend(['-r', 'xml','-Dreport.xml.out.file=%s' % self.coverage_xml_file])
            if self.coverage_report_html:
              args.extend(['-r', 'html',
                           '-Dreport.html.out.file=%s' % self.coverage_html_file,
                           '-Dreport.out.encoding=UTF-8'] + sorting)

            main = 'emma'
            result = execute_java(classpath=emma_classpath, main=main, args=args,
                                  workunit_factory=self.context.new_workunit,
                                  workunit_name='emma-report')
            if result != 0:
              raise TaskError("java %s ... exited non-zero (%i)"
                              " 'failed to generate code coverage reports'" % (main, result))

            if self.coverage_report_console:
              with safe_open(self.coverage_console_file) as console_report:
                sys.stdout.write(console_report.read())
            if self.coverage_report_html_open:
              binary_util.ui_open(self.coverage_html_file)
예제 #17
0
  def execute(self, targets):
    """Stages IDE project artifacts to a project directory and generates IDE configuration files."""
    checkstyle_enabled = len(Phase.goals_of_type(Checkstyle)) > 0
    if checkstyle_enabled:
      checkstyle_classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(
          self.checkstyle_bootstrap_key)
    else:
      checkstyle_classpath = []

    if self.scalac_bootstrap_key:
      scalac_classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(
          self.scalac_bootstrap_key)
    else:
      scalac_classpath = []

    self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath)

    self.map_internal_jars(targets)
    self.map_external_jars()

    idefile = self.generate_project(self._project)
    if idefile:
      binary_util.ui_open(idefile)
예제 #18
0
    def execute(self, targets):
        """Stages IDE project artifacts to a project directory and generates IDE configuration files."""
        checkstyle_enabled = len(Phase.goals_of_type(Checkstyle)) > 0
        if checkstyle_enabled:
            checkstyle_classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(
                self.checkstyle_bootstrap_key)
        else:
            checkstyle_classpath = []

        if self.scalac_bootstrap_key:
            scalac_classpath = self._jvm_tool_bootstrapper.get_jvm_tool_classpath(
                self.scalac_bootstrap_key)
        else:
            scalac_classpath = []

        self._project.set_tool_classpaths(checkstyle_classpath,
                                          scalac_classpath)

        self.map_internal_jars(targets)
        self.map_external_jars()

        idefile = self.generate_project(self._project)
        if idefile:
            binary_util.ui_open(idefile)
예제 #19
0
  def execute(self, targets):
    if not MarkdownToHtml.AVAILABLE:
      raise TaskError('Cannot process markdown - no markdown lib on the sys.path')

    # TODO(John Sirois): consider adding change detection

    css_relpath = os.path.join('css', 'codehighlight.css')
    css = emit_codehighlight_css(os.path.join(self.outdir, css_relpath), self.code_style)
    if css:
      self.context.log.info('Emitted %s' % css)

    def is_page(target):
      return isinstance(target, Page)

    roots = set()
    interior_nodes = set()
    if self.open:
      dependencies_by_page = self.context.dependents(on_predicate=is_page, from_predicate=is_page)
      roots.update(dependencies_by_page.keys())
      for dependencies in dependencies_by_page.values():
        interior_nodes.update(dependencies)
        roots.difference_update(dependencies)
      for page in self.context.targets(is_page):
        # There are no in or out edges so we need to show show this isolated page.
        if not page.dependencies and page not in interior_nodes:
          roots.add(page)

    plaingenmap = self.context.products.get('markdown_html')
    wikigenmap = self.context.products.get('wiki_html')
    show = []
    for page in filter(is_page, targets):
      _, ext = os.path.splitext(page.source)
      if ext in self.extensions:
        def process_page(key, outdir, url_builder, config, genmap, fragment=False):
          html_path = self.process(
            outdir,
            page.target_base,
            page.source,
            self.fragment or fragment,
            url_builder,
            config,
            css=css
          )
          self.context.log.info('Processed %s to %s' % (page.source, html_path))
          relpath = os.path.relpath(html_path, outdir)
          genmap.add(key, outdir, [relpath])
          return html_path

        def url_builder(linked_page, config=None):
          path, ext = os.path.splitext(linked_page.source)
          return linked_page.name, os.path.relpath(path + '.html', os.path.dirname(page.source))

        page_path = os.path.join(self.outdir, 'html')
        html = process_page(page, page_path, url_builder, lambda p: None, plaingenmap)
        if css and not self.fragment:
          plaingenmap.add(page, self.outdir, list(css_relpath))
        if self.open and page in roots:
          show.append(html)

        for wiki in page.wikis():
          def get_config(page):
            return page.wiki_config(wiki)
          basedir = os.path.join(self.outdir, wiki.id)
          process_page((wiki, page), basedir, wiki.url_builder, get_config,
                       wikigenmap, fragment=True)

    if show:
      binary_util.ui_open(*show)