Example #1
0
def builddb(treecfg, dbdir):
  """ Post-process the build and make the SQL directory """
  global big_blob

  # We use this all over the place, cache it here.
  plugins = dxr.get_active_plugins(treecfg)

  # Building the database--this happens as multiple phases. In the first phase,
  # we basically collect all of the information and organizes it. In the second
  # phase, we link the data across multiple languages.
  print "Post-processing the source files..."
  big_blob = {}
  srcdir = treecfg.sourcedir
  objdir = treecfg.objdir
  # srcdir=objdir is not a good idea
  if os.path.normpath(srcdir) == objdir:
    print('objdir must not be the same as srcdir')
    sys.exit(1)
  for plugin in plugins:
    if 'post_process' in plugin.__all__:
      big_blob[plugin.__name__] = plugin.post_process(srcdir, objdir)

  # Save off the raw data blob
  print "Storing data..."
  dxr.store_big_blob(treecfg, big_blob)

  # Build the sql for later queries. This is a combination of the main language
  # schema as well as plugin-specific information. The pragmas that are
  # executed should make the sql stage go faster.
  print "Building SQL..."
  dbname = dxr.get_database_filename(treecfg)
  conn = dxr.open_database(dbname,
      'PRAGMA synchronous=off; PRAGMA page_size=65536;')

  # Import the schemata
  schemata = [dxr.languages.get_standard_schema()]
  for plugin in plugins:
    schemata.append(plugin.get_schema())
  conn.executescript('\n'.join(schemata))
  conn.commit()

  # Load and run the SQL
  def sql_generator():
    for statement in dxr.languages.get_sql_statements():
      yield statement
    for plugin in plugins:
      if plugin.__name__ in big_blob:
        plugblob = big_blob[plugin.__name__]
        for statement in plugin.sqlify(plugblob):
          yield statement

  for stmt in sql_generator():
    if isinstance(stmt, tuple):
      conn.execute(stmt[0], stmt[1])
    else:
      conn.execute(stmt)
  conn.commit()
  conn.close()
Example #2
0
def indextree(treecfg, doxref, dohtml, debugfile):
  global big_blob

  # If we're live, we'll need to move -current to -old; we'll move it back
  # after we're done.
  if treecfg.isdblive:
    currentroot = os.path.join(treecfg.wwwdir, treecfg.tree + '-current')
    oldroot = os.path.join(treecfg.wwwdir, treecfg.tree + '-old')
    linkroot = os.path.join(treecfg.wwwdir, treecfg.tree)
    if os.path.isdir(currentroot):
      if os.path.exists(os.path.join(currentroot, '.dxr_xref', '.success')):
        # Move current -> old, change link to old
        try:
          shutil.rmtree(oldroot)
        except OSError:
          assert_permission_denied()
          pass
        try:
          shutil.move(currentroot, oldroot)
          os.unlink(linkroot)
          os.symlink(oldroot, linkroot)
        except OSError:
          assert_permission_denied()
          pass
      else:
        # This current directory is bad, move it away
        shutil.rmtree(currentroot)

  # dxr xref files (index + sqlitedb) go in wwwdir/treename-current/.dxr_xref
  # and we'll symlink it to wwwdir/treename later
  htmlroot = os.path.join(treecfg.wwwdir, treecfg.tree + '-current')
  dbdir = os.path.join(htmlroot, '.dxr_xref')
  os.makedirs(dbdir, 0755)
  dbname = dxr.get_database_filename(treecfg)

  retcode = 0
  if doxref:
    builddb(treecfg, dbdir)
    if treecfg.isdblive:
      f = open(os.path.join(dbdir, '.success'), 'w')
      f.close()
  elif treecfg.isdblive:
    # If the database is live, we need to copy database info from the old
    # version of the code
    oldhtml = os.path.join(treecfg.wwwdir, treecfg.tree + '-old')
    olddbdir = os.path.join(oldhtml, '.dxr_xref')
    shutil.rmtree(dbdir)
    shutil.copytree(olddbdir, dbdir)

  # Build static html
  if dohtml:
    if not doxref:
      big_blob = dxr.load_big_blob(treecfg)
    # Do we need to do file pivoting?
    for plugin in dxr.get_active_plugins(treecfg):
      if plugin.__name__ in big_blob:
        plugin.pre_html_process(treecfg, big_blob[plugin.__name__])
    dxr.htmlbuilders.build_htmlifier_map(dxr.get_active_plugins(treecfg))
    treecfg.database = dbname

    n = cpu_count()
    p = Pool(processes=n)

    print 'Building HTML files for %s...' % treecfg.tree, ; sys.stdout.flush ()

    index_list = open(os.path.join(dbdir, "file_list.txt"), 'w')
    file_list = []

    def getOutputFiles():
      for regular in treecfg.getFileList():
        yield regular
      filelist = set()
      for plug in big_blob:
        try:
          filelist.update(big_blob[plug]["byfile"].keys())
        except KeyError:
          pass
      for filename in filelist:
        if filename.startswith("--GENERATED--/"):
          relpath = filename[len("--GENERATED--/"):]
          yield filename, os.path.join(treecfg.objdir, relpath)

    if debugfile:
      output_files = glob.glob (treecfg.sourcedir + '/' + debugfile)
      if output_files == []:
        print 'Error: Glob %s doesn\'t match any files' % debugfile
        sys.exit (1)
    last_dir = None

    for f in getOutputFiles():
      # In debug mode, we only care about some files
      if debugfile and not treecfg.sourcedir + '/' + f[0] in output_files: continue
      if os.path.dirname (treecfg.sourcedir + '/' + f[0]) != last_dir:
        last_dir = os.path.dirname (treecfg.sourcedir + '/' + f[0])
        print os.path.basename (last_dir), ; sys.stdout.flush ()

      index_list.write(f[0] + '\n')
      cpypath = os.path.join(htmlroot, f[0])
      srcpath = f[1]
      file_list.append(f)

      # Make output directory
      cpydir = os.path.dirname(cpypath)
      if not os.path.exists(cpydir):
        os.makedirs(cpydir)

      def is_text(srcpath):
        # xdg.Mime considers .lo as text, which is technically true but useless
        if srcpath[-3:] == '.lo': return False
        import xdg.Mime
        mimetype = str(xdg.Mime.get_type (srcpath))
        for valid in ['text', 'xml', 'shellscript', 'perl', 'm4', 'xbel']:
          if valid in mimetype:
            return True
        return False
      if not is_text(srcpath):
        continue
      p.apply_async(async_toHTML, [treecfg, srcpath, cpypath + ".html"])

    if file_list == []:
        print 'Error: No files found to index'
        sys.exit (0)
    print '...Done', '%d files indexed' % len (file_list)

    p.apply_async(make_index, [file_list, dbdir])

    index_list.close()
    p.close()
    p.join()

    # Generate index.html files
    # XXX: This wants to be parallelized. However, I seem to run into problems
    # if it isn't.
    def genhtml(treecfg, dirname, fnames):
      make_index_html(treecfg, dirname, fnames, htmlroot)
    os.path.walk(htmlroot, genhtml, treecfg)

  # If the database is live, we need to switch the live to the new version
  if treecfg.isdblive:
    try:
      try:
        shutil.rmtree(oldroot)
      except:
        pass
      try:
        os.remove(linkroot + '.tmp')
      except:
        pass
      os.symlink(currentroot, linkroot + '.tmp')
      os.rename(linkroot + '.tmp', linkroot)
    except OSError:
      msg = sys.exc_info()[1] # Python 2/3 compatibility
      print ('Replacing database failed: %s' % str(msg))