trac-bootstrap-script /

Full commit
# The code to bootstrap Trac with environment created in .trac
# subdir in current directory.
# Placed into public domain by anatoly techtonik

import os
import shutil
import sys
import subprocess

DEVPATH = os.path.dirname(os.path.abspath(__file__))
ENVPATH = os.path.join(DEVPATH, '.trac')
# path to download dependency modules
LIBPATH = os.path.join(DEVPATH, '.pylibs')

# module checkout URLs
PATCH = ''

# setuptools curse lifting patch
TRACPATCH = DEVPATH + '/trac-0.12.2.patch'

print("Executing Trac from source checkout (using .trac/ environment)")

sys.path.insert(0, LIBPATH)
print("01. Patched sys.path with %s" % LIBPATH)
sys.path.insert(0, DEVPATH)
print("01. Patched sys.path with %s" % DEVPATH)

def get_module(url, path):
  print("... checking out module from SVN")
  if not os.path.exists(path):
    print "... creating %s" % path
  cmd = "svn co %s %s" % (url, path)
  print("... executing: %s" % cmd)
  retcode =, shell=True)
  if retcode != 0:
    sys.exit("Error while executing SVN. Aborting")

print("02. Check Genshi")

  import imp
except ImportError:
  get_module(GENSHI, os.path.join(LIBPATH, 'genshi'))
import genshi
print("... imported Genshi %s" % genshi.__version__)

print("0x. Patching Trac to get rid of setuptools dependency")
  import imp
except ImportError:
  PATCHPATH = os.path.join(LIBPATH, 'patch')
  if not os.path.exists(PATCHPATH + '.py'):
    print('... fetching python-patch')
    get_module(PATCH, PATCHPATH)
    shutil.move(os.path.join(PATCHPATH, ''), LIBPATH)
    sys.exit('FAIL: can\'t get python-patch')
cmd = "python %s/ %s" % (LIBPATH, TRACPATCH)
retcode =, shell=True)
# [ ] TODO return status code if file is already patched
print('... patch returned %s (which doesn\'t mean anything on second run)' % retcode)

print("03. Importing Core Trac Modules")
# even core Trac modules are imported through setuptools, and
# here is a workaround to get rid of the dependency
imports = open(os.path.join(DEVPATH, '')).readlines()
key = [x for x,y in enumerate(imports) if '[trac.plugins]' in y][0]
imports = imports[key+1:]
key = [x for x,y in enumerate(imports) if '"""' in y][0]
imports = imports[:key]
for line in imports:
  # line format is "trac.db.sqlite = trac.db.sqlite_backend"
  # or trac.mimeview.rst = trac.mimeview.rst[reST]
  name = line.split('=',1)[1].strip()
  if '[' in name:
    name = name[:name.index('[')]
  except ImportError, err:
    print '... %s failed to load: %s' % (name, err)

if not os.path.exists(ENVPATH):
  print("04. Creating .trac/ environment in %s" % ENVPATH)
  import trac.admin.console[ENVPATH, 'initenv',
    'Default "Trac Environment" for Development',
  print("04. .trac/ environment already exists - exiting")