コード例 #1
0
ファイル: console.py プロジェクト: alvabai/trac-multiproject
    def globally_execute_command(self, *args):
        offset = 0
        max_index = -1
        if args and args[0].isdigit():
            offset = int(args[0])
            if len(args) > 1 and args[1].isdigit():
                limit = int(args[1])
                max_index = limit + offset
                args = args[2:]
            else:
                args = args[1:]
        upgrade_check = False
        env_list = False
        if args and args[0] == 'upgrade-check':
            upgrade_check = True
        elif args and args[0] == 'list-env':
            env_list = True

        sys_home_project_name = self.config.get('multiproject', 'sys_home_project_name')
        for index, row in enumerate(self.projects_iterator(['env_name'], batch_size=10)):
            env_name, = row
            if index < offset:
                continue
            if max_index != -1 and index >= max_index:
                break
            if env_name == sys_home_project_name:
                continue
            if env_list:
                printout("{0:4} env:'{1}'".format(index, env_name))
                continue
            env = None
            try:
                env_path = safe_path(self.config.get('multiproject', 'sys_projects_root'),
                    env_name)
                env = Environment(env_path)
            except TracError as e:
                printout(_('ERROR: Opening environment %(env_name)s failed', env_name=env_name))
                continue

            if upgrade_check:
                if env.needs_upgrade():
                    printout("[+] {0:4} env:'{1}'".format(index, env_name))
                else:
                    printout("[ ] {0:4} env:'{1}'".format(index, env_name))
                continue
            # To setup MultiProject specific things like 'project_identifier'
            MultiProjectEnvironmentInit(env).environment_needs_upgrade(None)

            try:
                command_manager = AdminCommandManager(env)
                printout(_("{0:4} Run in env:'{1}'".format(index, env_name)))
                command_manager.execute_command(*args)
            except AdminCommandError as e:
                printout(_('ERROR: Executing command in environment %(env_name)s failed: ',
                    env_name=env_name) + str(e))
コード例 #2
0
ファイル: agilo_sqlite2pg.py プロジェクト: djangsters/agilo
def getPostgreSQLEnvironment(opts):
    """ Create an Environment connected to the PostgreSQL database """

    dburi = opts.pg_uri
    env = Environment(opts.tracenv)
    env.config.set('trac', 'database', dburi)
    try:
        cnx = env.get_db_cnx()
        cur = cnx.cursor()
        cur.execute("select value from system where name = 'database_version'");
    except ProgrammingError:
        cnx.rollback()
        DatabaseManager(env).init_db()
        DatabaseManager(env).shutdown()
        for x in filter(None, [env.compmgr[cls] for cls in 
                        ComponentMeta._registry.get(
                        IEnvironmentSetupParticipant, [])]):
            if isinstance(x, EnvironmentSetup):
                x.environment_created()        
    if env.needs_upgrade():
        env.upgrade()
    return env
コード例 #3
0
def getPostgreSQLEnvironment(opts):
    """ Create an Environment connected to the PostgreSQL database """

    dburi = opts.pg_uri
    env = Environment(opts.tracenv)
    env.config.set('trac', 'database', dburi)
    try:
        cnx = env.get_db_cnx()
        cur = cnx.cursor()
        cur.execute("select value from system where name = 'database_version'")
    except ProgrammingError:
        cnx.rollback()
        DatabaseManager(env).init_db()
        DatabaseManager(env).shutdown()
        for x in filter(None, [
                env.compmgr[cls] for cls in ComponentMeta._registry.get(
                    IEnvironmentSetupParticipant, [])
        ]):
            if isinstance(x, EnvironmentSetup):
                x.environment_created()
    if env.needs_upgrade():
        env.upgrade()
    return env
コード例 #4
0
ファイル: admin.py プロジェクト: jun66j5/tracmigrateplugin
class MigrationTestCase(unittest.TestCase):

    def setUp(self):
        self.stdout = sys.stdout
        self.stderr = sys.stderr
        sys.stdout = sys.stderr = DummyOut()
        self.path = tempfile.mkdtemp(prefix='trac-migrate-')
        self.src_path = os.path.join(self.path, 'src')
        self.dst_path = os.path.join(self.path, 'dst')
        self.src_env = None
        self.dst_env = None
        self._destroy_db()

    def tearDown(self):
        sys.stdout = self.stdout
        sys.stderr = self.stderr
        if self.src_env:
            self.src_env.shutdown()
        if self.dst_env:
            self.dst_env.shutdown()
        shutil.rmtree(self.path)

    def _create_env(self, path, dburi):
        env = Environment(path, True,
                          [('trac', 'database', dburi),
                           ('trac', 'base_url', 'http://localhost/'),
                           ('project', 'name', u'Pŕójéćŧ Ńáḿé')])
        @env.with_transaction()
        def fn(db):
            cursor = db.cursor()
            cursor.execute("UPDATE system SET value='21' "
                           "WHERE name='initial_database_version'")
        pages_dir = resource_filename('trac.wiki', 'default-pages')
        WikiAdmin(env).load_pages(pages_dir)
        att = Attachment(env, 'wiki', 'WikiStart')
        att.insert('filename.txt', StringIO('test'), 4)
        env.shutdown()

    if 'destroying' in inspect.getargspec(EnvironmentStub.__init__)[0]:
        def _destroy_db(self):
            EnvironmentStub(destroying=True).destroy_db()
    else:
        def _destroy_db(self):
            EnvironmentStub().destroy_db()

    def _get_all_records(self, env):
        def primary(row, columns):
            if len(columns) == 1:
                return row[columns[0]]
            else:
                return tuple(row[col] for col in columns)

        db = env.get_read_db()
        cursor = db.cursor()
        records = {}
        for table in db_default.schema:
            primary_cols = ','.join(db.quote(col) for col in table.key)
            query = "SELECT * FROM %s ORDER BY %s" % (db.quote(table.name),
                                                      primary_cols)
            cursor.execute(query)
            columns = get_column_names(cursor)
            rows = {}
            for row in cursor:
                row = dict(zip(columns, row))
                rows[primary(row, table.key)] = row
            records[table.name] = rows
        return records

    def _generate_module_name(self):
        return 'tracmigratetest_' + hex_entropy(16)

    def _build_egg_file(self):
        module_name = self._generate_module_name()
        plugin_src = os.path.join(self.path, 'plugin_src')
        os.mkdir(plugin_src)
        os.mkdir(os.path.join(plugin_src, module_name))
        create_file(os.path.join(plugin_src, 'setup.py'),
                    _setup_py % {'name': module_name})
        create_file(os.path.join(plugin_src, module_name, '__init__.py'),
                    _plugin_py)
        proc = Popen((sys.executable, 'setup.py', 'bdist_egg'), cwd=plugin_src,
                     stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds)
        stdout, stderr = proc.communicate(input='')
        for f in (proc.stdin, proc.stdout, proc.stderr):
            f.close()
        for filename in glob(os.path.join(plugin_src, 'dist', '*-*.egg')):
            return filename

    def _migrate(self, env, path, dburi):
        TracMigrationCommand(env)._do_migrate(path, dburi)

    def _migrate_inplace(self, env, dburi):
        self._migrate(env, '--in-place', dburi)

    def _compare_records(self, expected, actual):
        self.assertEqual(expected.keys(), actual.keys())
        for table in db_default.schema:
            name = table.name
            if name == 'report':
                self.assertEqual(expected[name].keys(), actual[name].keys())
            else:
                self.assertEqual(expected[name], actual[name])

    def _get_options(self, env):
        config = env.config
        return [(section, name, self._option_dumps(section, name, value))
                for section in sorted(config.sections())
                for name, value in sorted(config.options(section))
                if not (section == 'trac' and name == 'database')]

    if hasattr(Option, 'dumps'):
        def _option_dumps(self, section, name, value):
            try:
                option = Option.registry[(section, name)]
                value = option.dumps(value)
            except KeyError:
                pass
            return value
    else:
        def _option_dumps(self, section, name, value):
            def dumps(value, option=None):
                if value is None:
                    return ''
                if value is True:
                    return 'enabled'
                if value is False:
                    return 'disabled'
                if isinstance(value, unicode):
                    return value
                if isinstance(value, (list, tuple)) and hasattr(option, 'sep'):
                    return option.sep.join(dumps(v) for v in value)
                return to_unicode(value)
            try:
                option = Option.registry[(section, name)]
                value = dumps(value, option=option)
            except KeyError:
                pass
            return value

    def test_migrate_from_sqlite_to_env(self):
        self._create_env(self.src_path, 'sqlite:db/trac.db')
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._migrate(self.src_env, self.dst_path, dburi)
        self.dst_env = Environment(self.dst_path)
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
                         dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_migrate_from_sqlite_inplace(self):
        self._create_env(self.src_path, 'sqlite:db/trac.db')
        dburi = get_dburi()
        if dburi in ('sqlite::memory:', 'sqlite:db/trac.db'):
            dburi = 'sqlite:db/trac-migrate.db'

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._migrate_inplace(self.src_env, dburi)
        self.src_env.shutdown()
        self.src_env = Environment(self.src_path)
        dst_options = self._get_options(self.src_env)
        dst_records = self._get_all_records(self.src_env)
        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
                         dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)

    def test_migrate_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._migrate(self.src_env, self.dst_path, 'sqlite:db/trac.db')
        self.dst_env = Environment(self.dst_path)
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
                         dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_migrate_to_sqlite_inplace(self):
        dburi = get_dburi()
        if dburi in ('sqlite::memory:', 'sqlite:db/trac.db'):
            dburi = 'sqlite:db/trac-migrate.db'
        self._create_env(self.src_path, dburi)

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._migrate_inplace(self.src_env, 'sqlite:db/trac.db')
        self.src_env.shutdown()
        self.src_env = Environment(self.src_path)
        dst_options = self._get_options(self.src_env)
        dst_records = self._get_all_records(self.src_env)
        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
                         dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)

    def _test_migrate_with_plugin_to_sqlite_env(self):
        self.src_env = Environment(self.src_path)
        self.assertTrue(self.src_env.needs_upgrade())
        self.src_env.upgrade()
        self.assertFalse(self.src_env.needs_upgrade())
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)

        self._migrate(self.src_env, self.dst_path, 'sqlite:db/trac.db')
        self.dst_env = Environment(self.dst_path)
        self.assertFalse(self.dst_env.needs_upgrade())
        self.assertFalse(os.path.exists(os.path.join(self.dst_path, 'log',
                                                     'created')))
        self.assertTrue(os.path.exists(os.path.join(self.dst_path, 'log',
                                                    'upgraded')))
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
                         dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_migrate_with_plugin_py_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)
        plugin_name = self._generate_module_name() + '.py'
        create_file(os.path.join(self.src_path, 'plugins', plugin_name),
                    _plugin_py)
        self._test_migrate_with_plugin_to_sqlite_env()

    def _extract_zipfile(self, zipfile, destdir):
        z = ZipFile(zipfile)
        try:
            for entry in z.namelist():
                if entry.endswith('/'):  # is a directory
                    continue
                names = entry.split('/')
                content = z.read(entry)
                filename = os.path.join(destdir, *names)
                dirname = os.path.dirname(filename)
                if not os.path.isdir(dirname):
                    os.makedirs(dirname)
                create_file(filename, content, 'wb')
        finally:
            z.close()

    def test_migrate_with_plugin_egg_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)
        self._extract_zipfile(self._build_egg_file(),
                              os.path.join(self.src_path, 'plugins',
                                           'tracmigratetest.egg'))
        self._test_migrate_with_plugin_to_sqlite_env()
コード例 #5
0
class ConvertDatabaseTestCase(unittest.TestCase):

    stdout = None
    stderr = None

    @classmethod
    def setUpClass(cls):
        cls.stdout = sys.stdout
        cls.stderr = sys.stderr
        cls.devnull = io.open(os.devnull, 'wb')
        sys.stdout = sys.stderr = cls.devnull

    @classmethod
    def tearDownClass(cls):
        cls.devnull.close()
        sys.stdout = cls.stdout
        sys.stderr = cls.stderr

    def setUp(self):
        self.path = mkdtemp()
        self.src_path = os.path.join(self.path, 'src')
        self.dst_path = os.path.join(self.path, 'dst')
        self.src_env = None
        self.dst_env = None
        self._destroy_db()

    def tearDown(self):
        if self.src_env:
            self.src_env.shutdown()
        if self.dst_env:
            self.dst_env.shutdown()
        rmtree(self.path)

    def _create_env(self, path, dburi):
        env = Environment(path, True,
                          [('trac', 'database', dburi),
                           ('trac', 'base_url', 'http://localhost/'),
                           ('project', 'name', u'Pŕójéćŧ Ńáḿé')])
        dbm = DatabaseManager(env)
        dbm.set_database_version(21, 'initial_database_version')
        att = Attachment(env, 'wiki', 'WikiStart')
        att.insert('filename.txt', io.BytesIO('test'), 4)
        env.shutdown()

    if 'destroying' in inspect.getargspec(EnvironmentStub.__init__)[0]:

        def _destroy_db(self):
            EnvironmentStub(path=self.path, destroying=True).destroy_db()
    else:

        def _destroy_db(self):
            EnvironmentStub(path=self.path).destroy_db()

    def _get_all_records(self, env):
        def primary(row, columns):
            if len(columns) == 1:
                return row[columns[0]]
            else:
                return tuple(row[col] for col in columns)

        records = {}
        with env.db_query as db:
            cursor = db.cursor()
            for table in db_default.schema:
                primary_cols = ','.join(db.quote(col) for col in table.key)
                query = "SELECT * FROM %s ORDER BY %s" \
                        % (db.quote(table.name), primary_cols)
                cursor.execute(query)
                columns = get_column_names(cursor)
                rows = {}
                for row in cursor:
                    row = dict(zip(columns, row))
                    rows[primary(row, table.key)] = row
                records[table.name] = rows
        return records

    def _generate_module_name(self):
        return 'trac_convert_db_' + hex_entropy(16)

    def _build_egg_file(self):
        module_name = self._generate_module_name()
        plugin_src = os.path.join(self.path, 'plugin_src')
        os.mkdir(plugin_src)
        os.mkdir(os.path.join(plugin_src, module_name))
        create_file(os.path.join(plugin_src, 'setup.py'),
                    _setup_py % {'name': module_name})
        create_file(os.path.join(plugin_src, module_name, '__init__.py'),
                    _plugin_py)
        proc = Popen((sys.executable, 'setup.py', 'bdist_egg'),
                     cwd=plugin_src,
                     stdin=PIPE,
                     stdout=PIPE,
                     stderr=PIPE,
                     close_fds=close_fds)
        proc.communicate(input='')
        for f in (proc.stdin, proc.stdout, proc.stderr):
            f.close()
        for filename in glob(os.path.join(plugin_src, 'dist', '*-*.egg')):
            return filename

    def _convert_db(self, env, dburi, path):
        EnvironmentAdmin(env)._do_convert_db(dburi, path)

    def _convert_db_inplace(self, env, dburi):
        self._convert_db(env, dburi, None)

    def _compare_records(self, expected, actual):
        self.assertEqual(expected.keys(), actual.keys())
        for table in db_default.schema:
            name = table.name
            if name == 'report':
                self.assertEqual(expected[name].keys(), actual[name].keys())
            else:
                self.assertEqual(expected[name], actual[name])

    def _get_options(self, env):
        config = env.config
        return [(section, name, self._option_dumps(section, name, value))
                for section in sorted(config.sections())
                for name, value in sorted(config.options(section))
                if (section, name) != ('trac', 'database')]

    def _option_dumps(self, section, name, value):
        try:
            option = Option.registry[(section, name)]
        except KeyError:
            pass
        else:
            value = option.dumps(value)
        return value

    def test_convert_from_sqlite_to_env(self):
        self._create_env(self.src_path, 'sqlite:db/trac.db')
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._convert_db(self.src_env, dburi, self.dst_path)
        self.dst_env = Environment(self.dst_path)
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({
            'name': 'initial_database_version',
            'value': '21'
        }, dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_convert_from_sqlite_inplace(self):
        self._create_env(self.src_path, 'sqlite:db/trac.db')
        dburi = get_dburi()
        if dburi in ('sqlite::memory:', 'sqlite:db/trac.db'):
            dburi = 'sqlite:db/trac-convert.db'

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._convert_db_inplace(self.src_env, dburi)
        self.src_env.shutdown()
        self.src_env = Environment(self.src_path)
        dst_options = self._get_options(self.src_env)
        dst_records = self._get_all_records(self.src_env)
        self.assertEqual({
            'name': 'initial_database_version',
            'value': '21'
        }, dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)

    def test_convert_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._convert_db(self.src_env, 'sqlite:db/trac.db', self.dst_path)
        self.dst_env = Environment(self.dst_path)
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({
            'name': 'initial_database_version',
            'value': '21'
        }, dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_convert_to_sqlite_inplace(self):
        dburi = get_dburi()
        if dburi in ('sqlite::memory:', 'sqlite:db/trac.db'):
            dburi = 'sqlite:db/trac-convert.db'
        self._create_env(self.src_path, dburi)

        self.src_env = Environment(self.src_path)
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)
        self._convert_db_inplace(self.src_env, 'sqlite:db/trac.db')
        self.src_env.shutdown()
        self.src_env = Environment(self.src_path)
        dst_options = self._get_options(self.src_env)
        dst_records = self._get_all_records(self.src_env)
        self.assertEqual({
            'name': 'initial_database_version',
            'value': '21'
        }, dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)

    def _test_convert_with_plugin_to_sqlite_env(self):
        self.src_env = Environment(self.src_path)
        self.assertTrue(self.src_env.needs_upgrade())
        self.src_env.upgrade()
        self.assertFalse(self.src_env.needs_upgrade())
        src_options = self._get_options(self.src_env)
        src_records = self._get_all_records(self.src_env)

        self._convert_db(self.src_env, 'sqlite:db/trac.db', self.dst_path)
        self.dst_env = Environment(self.dst_path)
        self.assertFalse(self.dst_env.needs_upgrade())
        self.assertFalse(
            os.path.exists(os.path.join(self.dst_env.log_dir, 'created')))
        self.assertTrue(
            os.path.exists(os.path.join(self.dst_env.log_dir, 'upgraded')))
        dst_options = self._get_options(self.dst_env)
        dst_records = self._get_all_records(self.dst_env)
        self.assertEqual({
            'name': 'initial_database_version',
            'value': '21'
        }, dst_records['system']['initial_database_version'])
        self._compare_records(src_records, dst_records)
        self.assertEqual(src_options, dst_options)
        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
        self.assertEqual('test', read_file(att.path))

    def test_convert_with_plugin_py_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)
        plugin_name = self._generate_module_name() + '.py'
        create_file(os.path.join(self.src_path, 'plugins', plugin_name),
                    _plugin_py)
        self._test_convert_with_plugin_to_sqlite_env()

    def test_convert_with_plugin_egg_to_sqlite_env(self):
        dburi = get_dburi()
        if dburi == 'sqlite::memory:':
            dburi = 'sqlite:db/trac.db'
        self._create_env(self.src_path, dburi)
        extract_zipfile(
            self._build_egg_file(),
            os.path.join(self.src_path, 'plugins', 'trac_convert_db_test.egg'))
        self._test_convert_with_plugin_to_sqlite_env()
コード例 #6
0
class EnvironmentTestCase(unittest.TestCase):
    def setUp(self):
        env_path = tempfile.mkdtemp(prefix='trac-tempenv-')
        self.env = Environment(env_path, create=True)
        self.env.config.set('trac', 'base_url',
                            'http://trac.edgewall.org/some/path')
        self.env.config.save()

    def tearDown(self):
        self.env.shutdown()  # really closes the db connections
        shutil.rmtree(self.env.path)

    def test_db_exc(self):
        db_exc = self.env.db_exc
        self.assertTrue(hasattr(db_exc, 'IntegrityError'))
        self.assertIs(db_exc, self.env.db_exc)

    def test_abs_href(self):
        abs_href = self.env.abs_href
        self.assertEqual('http://trac.edgewall.org/some/path', abs_href())
        self.assertIs(abs_href, self.env.abs_href)

    def test_href(self):
        href = self.env.href
        self.assertEqual('/some/path', href())
        self.assertIs(href, self.env.href)

    def test_get_version(self):
        """Testing env.get_version"""
        self.assertEqual(db_default.db_version, self.env.get_version())
        self.assertEqual(db_default.db_version, self.env.database_version)
        self.assertEqual(db_default.db_version,
                         self.env.database_initial_version)

    def test_get_known_users(self):
        """Testing env.get_known_users"""
        with self.env.db_transaction as db:
            db.executemany("INSERT INTO session VALUES (%s,%s,0)",
                           [('123', 0), ('tom', 1), ('joe', 1), ('jane', 1)])
            db.executemany(
                "INSERT INTO session_attribute VALUES (%s,%s,%s,%s)",
                [('123', 0, 'email', '*****@*****.**'),
                 ('tom', 1, 'name', 'Tom'),
                 ('tom', 1, 'email', '*****@*****.**'),
                 ('joe', 1, 'email', '*****@*****.**'),
                 ('jane', 1, 'name', 'Jane')])
        users = {}
        for username, name, email in self.env.get_known_users():
            users[username] = (name, email)

        self.assertTrue('anonymous' not in users)
        self.assertEqual(('Tom', '*****@*****.**'), users['tom'])
        self.assertEqual((None, '*****@*****.**'), users['joe'])
        self.assertEqual(('Jane', None), users['jane'])

    def test_is_component_enabled(self):
        self.assertEqual(True, Environment.required)
        self.assertEqual(True, self.env.is_component_enabled(Environment))
        self.assertEqual(False, EnvironmentStub.required)
        self.assertEqual(None, self.env.is_component_enabled(EnvironmentStub))

    def test_dumped_values_in_tracini(self):
        parser = RawConfigParser()
        filename = self.env.config.filename
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))

    def test_dumped_values_in_tracini_sample(self):
        parser = RawConfigParser()
        filename = self.env.config.filename + '.sample'
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))
        self.assertTrue(parser.has_option('logging', 'log_format'))
        self.assertEqual('', parser.get('logging', 'log_format'))

    def test_needs_upgrade_legacy_participant(self):
        """For backward compatibility with plugin, environment_needs_upgrade
        with a `db` argument is deprecated but still allowed."""
        participants = self.env.setup_participants
        needs_upgrade = self.env.needs_upgrade()

        class LegacyParticipant(Component):
            implements(IEnvironmentSetupParticipant)

            def environment_created(self):
                pass

            def environment_needs_upgrade(self, db):
                return True

            def upgrade_environment(self, db):
                pass

        self.env.enable_component(LegacyParticipant)

        self.assertFalse(needs_upgrade)
        self.assertEqual(
            len(participants) + 1, len(self.env.setup_participants))
        self.assertTrue(self.env.needs_upgrade())

    def test_upgrade_legacy_participant(self):
        """For backward compatibility with plugin, upgrade with a `db`
        argument is deprecated but still allowed."""
        participants = self.env.setup_participants

        class LegacyParticipant(Component):
            implements(IEnvironmentSetupParticipant)

            def environment_created(self):
                pass

            def environment_needs_upgrade(self, db):
                return True

            def upgrade_environment(self, db):
                pass

        self.env.enable_component(LegacyParticipant)

        self.assertEqual(
            len(participants) + 1, len(self.env.setup_participants))
        self.assertTrue(self.env.needs_upgrade())
        self.assertTrue(self.env.upgrade())

    def test_invalid_log_level_raises_exception(self):
        self.env.config.set('logging', 'log_level', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid',
                         self.env.config.get('logging', 'log_level'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)

    def test_invalid_log_type_raises_exception(self):
        self.env.config.set('logging', 'log_type', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid', self.env.config.get('logging', 'log_type'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)
コード例 #7
0
ファイル: env.py プロジェクト: miihael/trac
class EnvironmentTestCase(unittest.TestCase):

    stdout = None
    stderr = None

    @classmethod
    def setUpClass(cls):
        cls.stdout = sys.stdout
        cls.stderr = sys.stderr
        cls.devnull = io.open(os.devnull, 'wb')
        sys.stdout = sys.stderr = cls.devnull

    @classmethod
    def tearDownClass(cls):
        cls.devnull.close()
        sys.stdout = cls.stdout
        sys.stderr = cls.stderr

    def setUp(self):
        self.env_path = mkdtemp()
        self.env = Environment(self.env_path, create=True)

    def tearDown(self):
        self.env.shutdown()  # really closes the db connections
        rmtree(self.env.path)

    def test_missing_config_file_raises_trac_error(self):
        """TracError is raised when config file is missing."""
        os.remove(self.env.config_file_path)
        self.assertRaises(TracError, Environment, self.env.path)

    def test_database_version(self):
        """Testing env.database_version"""
        self.assertEqual(db_default.db_version, self.env.database_version)

    def test_database_initial_version(self):
        """Testing env.database_initial_version"""
        self.assertEqual(db_default.db_version,
                         self.env.database_initial_version)

    def test_is_component_enabled(self):
        self.assertTrue(Environment.required)
        self.assertTrue(self.env.is_component_enabled(Environment))

    def test_log_format(self):
        """Configure the log_format and log to a file at WARNING level."""
        self.env.config.set('logging', 'log_type', 'file')
        self.env.config.set('logging', 'log_level', 'WARNING')
        self.env.config.set('logging', 'log_format',
                            'Trac[$(module)s] $(project)s: $(message)s')
        self.env.config.save()
        self.env.shutdown()
        self.env = Environment(self.env_path)  # Reload environment

        self.env.log.warning("The warning message")

        with open(self.env.log_file_path) as f:
            log = f.readlines()
        self.assertEqual("Trac[env] My Project: The warning message\n",
                         log[-1])

    def test_dumped_values_in_tracini(self):
        parser = RawConfigParser()
        filename = self.env.config.filename
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))

    def test_dumped_values_in_tracini_sample(self):
        parser = RawConfigParser()
        filename = self.env.config.filename + '.sample'
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))
        self.assertTrue(parser.has_option('logging', 'log_format'))
        self.assertEqual('', parser.get('logging', 'log_format'))

    def test_invalid_log_level_raises_exception(self):
        self.env.config.set('logging', 'log_level', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid',
                         self.env.config.get('logging', 'log_level'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)

    def test_invalid_log_type_raises_exception(self):
        self.env.config.set('logging', 'log_type', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid', self.env.config.get('logging', 'log_type'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)

    def test_log_level_not_case_sensitive(self):
        """[logging] log_level is not case-sensitive."""
        self.env.config.set('logging', 'log_level', 'warning')
        self.env.config.save()

        self.assertEqual('warning',
                         self.env.config.get('logging', 'log_level'))
        self.assertEqual('WARNING', self.env.log_level)

    def test_log_type_not_case_sensitive(self):
        """[logging] log_type is not case-sensitive."""
        self.env.config.set('logging', 'log_type', 'File')
        self.env.config.save()

        self.assertEqual('File', self.env.config.get('logging', 'log_type'))
        self.assertEqual('file', self.env.log_type)

    def test_upgrade_environment(self):
        """EnvironmentSetupParticipants are called only if
        environment_needs_upgrade returns True for the participant.
        """
        class SetupParticipantA(Component):
            implements(IEnvironmentSetupParticipant)

            called = False

            def environment_created(self):
                pass

            def environment_needs_upgrade(self):
                return True

            def upgrade_environment(self):
                self.called = True

        class SetupParticipantB(Component):
            implements(IEnvironmentSetupParticipant)

            called = False

            def environment_created(self):
                pass

            def environment_needs_upgrade(self):
                return False

            def upgrade_environment(self):
                self.called = True

        self.env.enable_component(SetupParticipantA)
        self.env.enable_component(SetupParticipantB)
        participant_a = SetupParticipantA(self.env)
        participant_b = SetupParticipantB(self.env)

        self.assertTrue(self.env.needs_upgrade())
        self.env.upgrade()
        self.assertTrue(participant_a.called)
        self.assertFalse(participant_b.called)
コード例 #8
0
    def create_project(self,
                       project,
                       templates,
                       vars=None,
                       database=None,
                       repository=None,
                       return_missing=False):
        """
        * project: path name of project
        * templates: templates to be applied on project creation
        * vars: variables for interpolation
        * database:  type of database to use
        * repository: type of repository to use
        """

        ### set variables

        dirname = os.path.join(self.directory, project)

        if os.path.isdir(dirname) and os.listdir(dirname):
            raise ValueError("Project directory %r already exists, "
                             "cowardly refusing to create anything" % dirname)

        _vars = vars or {}
        vars = self.vars.copy()
        vars.update(_vars)
        vars['project'] = project
        permissions = dict([(key, value[:])
                            for key, value in self.permissions.items()])
        wiki = self.wiki[:]

        ### munge configuration

        # get templates

        # XXX hack to get the specified DB out of pastescript templates
        if not database:
            if isinstance(templates, ProjectTemplates):
                pastescript_templates = templates.pastescript_templates
            else:
                pastescript_templates = ProjectTemplates(
                    *(templates + self.site_templates)).pastescript_templates
            databases = set([
                template.database() for template in pastescript_templates
                if template.db is not None
            ])
            if databases:
                assert len(databases) == 1
                database = databases.pop()
        if not database:
            database = SQLite()

        _templates = []
        _templates.append(database.config())
        if repository:
            _templates.append(repository.config())

        if isinstance(templates, ProjectTemplates):
            if _templates:
                templates.append(*_templates)
        else:
            templates += _templates
            templates = self.project_templates(templates)

        # determine the vars/options
        optdict = templates.vars(self.options)
        repo_fields = {}
        if database:
            vars2dict(optdict, *database.options)
        if repository:
            vars2dict(optdict, *repository.options)
            repo_fields = self.repository_fields(project).get(
                repository.name, {})

        ### interpolate configuration

        command = create_distro_command(interactive=self.interactive)

        # check for missing variables
        missing = templates.missing(vars)
        missing.update(set(optdict.keys()).difference(vars.keys()))
        if return_missing:
            return missing
        if missing:

            # use default repo fields if they are missing
            for field in repo_fields:
                if field in missing:
                    vars[field] = repo_fields[field]
                    missing.remove(field)

            # add missing variables to the optdict
            for missed in missing:
                if missed not in optdict:
                    optdict[missed] = var(missed, '')

            if missing:
                paste_template = Template(project)
                paste_template._read_vars = dict2vars(optdict)  # XXX bad touch
                paste_template.check_vars(vars, command)

        # run the pre method of the pastescript templates
        # XXX should this be done here?
        command.interactive = False
        for paste_template in templates.pastescript_templates:
            paste_template.pre(command, dirname, vars)

        ### create the database
        if database:
            database.setup(**vars)

        ### create the trac environment
        options = templates.options_tuples(vars)
        options.append(('project', 'name', project))  # XXX needed?
        if self.inherit:
            options.append(('inherit', 'file', self.inherit))
        env = Environment(dirname, create=True, options=options)

        ### repository setup
        if repository:
            repository.setup(**vars)
            try:
                repos = env.get_repository()
                repos.sync()
            except TracError:
                pass

        ### read the generated configuration
        _conf_file = os.path.join(dirname, 'conf', 'trac.ini')
        fp = file(_conf_file)
        _conf = fp.read()
        fp.close()

        ### run pastescript templates
        for paste_template in templates.pastescript_templates:
            paste_template.write_files(command, dirname, vars)
            paste_template.post(command, dirname, vars)

            # read permissions
            for agent, perm in paste_template.permissions.items():
                permissions.setdefault(agent, []).extend(perm)

            # read wiki directories
            wiki_dir = paste_template.wiki_dir()
            if wiki_dir is not None:
                wiki.append(wiki_dir)

        # write back munged configuration
        munger = ConfigMunger(_conf, options)
        fp = file(_conf_file, 'w')
        munger.write(fp)
        fp.close()

        # TODO: update the inherited file:
        # * intertrac

        # trac-admin upgrade the project
        env = Environment(dirname)
        if env.needs_upgrade():
            env.upgrade()

        ### trac-admin operations
        admin = TracLegosAdmin(dirname)

        # remove the default items
        admin.delete_all()

        # load wiki pages
        admin.load_pages()  # default wiki pages
        for page_dir in wiki:
            admin.load_pages(page_dir)

        # add permissions
        if permissions:
            admin.add_permissions(permissions)
コード例 #9
0
ファイル: env.py プロジェクト: vidhya-maddisetty/trac
class EnvironmentTestCase(unittest.TestCase):
    def setUp(self):
        env_path = mkdtemp()
        self.env = Environment(env_path, create=True)
        self.env.config.save()

    def tearDown(self):
        self.env.shutdown()  # really closes the db connections
        shutil.rmtree(self.env.path)

    def test_missing_config_file_raises_trac_error(self):
        """TracError is raised when config file is missing."""
        os.remove(self.env.config_file_path)
        self.assertRaises(TracError, Environment, self.env.path)

    def test_database_version(self):
        """Testing env.database_version"""
        self.assertEqual(db_default.db_version, self.env.database_version)

    def test_database_initial_version(self):
        """Testing env.database_initial_version"""
        self.assertEqual(db_default.db_version,
                         self.env.database_initial_version)

    def test_is_component_enabled(self):
        self.assertEqual(True, Environment.required)
        self.assertEqual(True, self.env.is_component_enabled(Environment))

    def test_dumped_values_in_tracini(self):
        parser = RawConfigParser()
        filename = self.env.config.filename
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))

    def test_dumped_values_in_tracini_sample(self):
        parser = RawConfigParser()
        filename = self.env.config.filename + '.sample'
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))
        self.assertTrue(parser.has_option('logging', 'log_format'))
        self.assertEqual('', parser.get('logging', 'log_format'))

    def test_invalid_log_level_raises_exception(self):
        self.env.config.set('logging', 'log_level', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid',
                         self.env.config.get('logging', 'log_level'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)

    def test_invalid_log_type_raises_exception(self):
        self.env.config.set('logging', 'log_type', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid', self.env.config.get('logging', 'log_type'))
        self.assertRaises(ConfigurationError, open_environment, self.env.path,
                          True)

    def test_upgrade_environment(self):
        """EnvironmentSetupParticipants are called only if
        environment_needs_upgrade returns True for the participant.
        """
        class SetupParticipantA(Component):
            implements(IEnvironmentSetupParticipant)

            called = False

            def environment_created(self):
                pass

            def environment_needs_upgrade(self):
                return True

            def upgrade_environment(self):
                self.called = True

        class SetupParticipantB(Component):
            implements(IEnvironmentSetupParticipant)

            called = False

            def environment_created(self):
                pass

            def environment_needs_upgrade(self):
                return False

            def upgrade_environment(self):
                self.called = True

        self.env.enable_component(SetupParticipantA)
        self.env.enable_component(SetupParticipantB)
        participant_a = SetupParticipantA(self.env)
        participant_b = SetupParticipantB(self.env)

        self.assertTrue(self.env.needs_upgrade())
        self.env.upgrade()
        self.assertTrue(participant_a.called)
        self.assertFalse(participant_b.called)
コード例 #10
0

def main(args):
    if len(args) != 3:
        print >>sys.stderr, _usage()
        return 127
    if args[0] in ("-i", "--in-place"):
        dest, source, dburi = args
    else:
        source, dest, dburi = args

    try:
        from trac.env import Environment
        from tracmigrate.admin import TracMigrationCommand
    except ImportError, e:
        print >>sys.stderr, "Requires trac and tracmigrateplugin: %s" % unicode(e)
        return 126

    env = Environment(source)
    if env.needs_upgrade():
        print >>sys.stderr, '''\
The Trac Environment needs to be upgraded.

Run "trac-admin %s upgrade"''' % source
        return 2
    return TracMigrationCommand(env)._do_migrate(dest, dburi)


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]) or 0)
コード例 #11
0
ファイル: env.py プロジェクト: pkdevbox/trac
class EnvironmentTestCase(unittest.TestCase):

    def setUp(self):
        env_path = tempfile.mkdtemp(prefix='trac-tempenv-')
        self.env = Environment(env_path, create=True)
        self.env.config.set('trac', 'base_url',
                            'http://trac.edgewall.org/some/path')
        self.env.config.save()

    def tearDown(self):
        self.env.shutdown() # really closes the db connections
        shutil.rmtree(self.env.path)

    def test_db_exc(self):
        db_exc = self.env.db_exc
        self.assertTrue(hasattr(db_exc, 'IntegrityError'))
        self.assertIs(db_exc, self.env.db_exc)

    def test_abs_href(self):
        abs_href = self.env.abs_href
        self.assertEqual('http://trac.edgewall.org/some/path', abs_href())
        self.assertIs(abs_href, self.env.abs_href)

    def test_href(self):
        href = self.env.href
        self.assertEqual('/some/path', href())
        self.assertIs(href, self.env.href)

    def test_get_version(self):
        """Testing env.get_version"""
        self.assertEqual(db_default.db_version, self.env.get_version())
        self.assertEqual(db_default.db_version, self.env.database_version)
        self.assertEqual(db_default.db_version, self.env.database_initial_version)

    def test_is_component_enabled(self):
        self.assertEqual(True, Environment.required)
        self.assertEqual(True, self.env.is_component_enabled(Environment))
        self.assertEqual(False, EnvironmentStub.required)
        self.assertEqual(None, self.env.is_component_enabled(EnvironmentStub))

    def test_dumped_values_in_tracini(self):
        parser = RawConfigParser()
        filename = self.env.config.filename
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))

    def test_dumped_values_in_tracini_sample(self):
        parser = RawConfigParser()
        filename = self.env.config.filename + '.sample'
        self.assertEqual([filename], parser.read(filename))
        self.assertEqual('#cc0,#0c0,#0cc,#00c,#c0c,#c00',
                         parser.get('revisionlog', 'graph_colors'))
        self.assertEqual('disabled', parser.get('trac', 'secure_cookies'))
        self.assertTrue(parser.has_option('logging', 'log_format'))
        self.assertEqual('', parser.get('logging', 'log_format'))

    def test_needs_upgrade_legacy_participant(self):
        """For backward compatibility with plugin, environment_needs_upgrade
        with a `db` argument is deprecated but still allowed."""
        participants = self.env.setup_participants
        needs_upgrade = self.env.needs_upgrade()

        class LegacyParticipant(Component):
            implements(IEnvironmentSetupParticipant)
            def environment_created(self):
                pass
            def environment_needs_upgrade(self, db):
                return True
            def upgrade_environment(self, db):
                pass

        self.env.enable_component(LegacyParticipant)

        self.assertFalse(needs_upgrade)
        self.assertEqual(len(participants) + 1,
                         len(self.env.setup_participants))
        self.assertTrue(self.env.needs_upgrade())

    def test_upgrade_legacy_participant(self):
        """For backward compatibility with plugin, upgrade with a `db`
        argument is deprecated but still allowed."""
        participants = self.env.setup_participants

        class LegacyParticipant(Component):
            implements(IEnvironmentSetupParticipant)
            def environment_created(self):
                pass
            def environment_needs_upgrade(self, db):
                return True
            def upgrade_environment(self, db):
                pass

        self.env.enable_component(LegacyParticipant)

        self.assertEqual(len(participants) + 1,
                         len(self.env.setup_participants))
        self.assertTrue(self.env.needs_upgrade())
        self.assertTrue(self.env.upgrade())

    def test_invalid_log_level_raises_exception(self):
        self.env.config.set('logging', 'log_level', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid',
                         self.env.config.get('logging', 'log_level'))
        self.assertRaises(ConfigurationError, open_environment,
                          self.env.path, True)

    def test_invalid_log_type_raises_exception(self):
        self.env.config.set('logging', 'log_type', 'invalid')
        self.env.config.save()

        self.assertEqual('invalid',
                         self.env.config.get('logging', 'log_type'))
        self.assertRaises(ConfigurationError, open_environment,
                          self.env.path, True)
コード例 #12
0
ファイル: legos.py プロジェクト: nyuhuhuu/trachacks
    def create_project(self, project, templates, vars=None,
                       database=None, repository=None,
                       return_missing=False):
        """
        * project: path name of project
        * templates: templates to be applied on project creation
        * vars: variables for interpolation
        * database:  type of database to use
        * repository: type of repository to use
        """
        
        ### set variables

        dirname = os.path.join(self.directory, project)
        
        if os.path.isdir(dirname) and os.listdir(dirname):
            raise ValueError("Project directory %r already exists, "
                             "cowardly refusing to create anything" % dirname)

        _vars = vars or {}
        vars = self.vars.copy()
        vars.update(_vars)
        vars['project'] = project        
        permissions = dict([(key, value[:]) 
                            for key, value in self.permissions.items()])
        wiki = self.wiki[:]

        ### munge configuration

        # get templates

        # XXX hack to get the specified DB out of pastescript templates
        if not database:
            if isinstance(templates, ProjectTemplates):
                pastescript_templates = templates.pastescript_templates
            else:
                pastescript_templates = ProjectTemplates(*(templates + self.site_templates)).pastescript_templates
            databases = set([ template.database() for template in pastescript_templates
                              if template.db is not None])
            if databases:
                assert len(databases) == 1
                database = databases.pop()
        if not database:
            database = SQLite()

        _templates = []
        _templates.append(database.config())
        if repository:
            _templates.append(repository.config())

        if isinstance(templates, ProjectTemplates):
            if _templates:
                templates.append(*_templates)
        else:
            templates += _templates
            templates = self.project_templates(templates)

        # determine the vars/options
        optdict = templates.vars(self.options)
        repo_fields = {}
        if database:
            vars2dict(optdict, *database.options)
        if repository:
            vars2dict(optdict, *repository.options)
            repo_fields = self.repository_fields(project).get(repository.name, {})

        ### interpolate configuration

        command = create_distro_command(interactive=self.interactive)
        
        # check for missing variables
        missing = templates.missing(vars)
        missing.update(set(optdict.keys()).difference(vars.keys()))
        if return_missing:
            return missing
        if missing:

            # use default repo fields if they are missing
            for field in repo_fields:
                if field in missing:
                    vars[field] = repo_fields[field]
                    missing.remove(field)

            # add missing variables to the optdict
            for missed in missing:
                if missed not in optdict:
                    optdict[missed] = var(missed, '')

            if missing:
                paste_template = Template(project)
                paste_template._read_vars = dict2vars(optdict) # XXX bad touch
                paste_template.check_vars(vars, command)

        # run the pre method of the pastescript templates
        # XXX should this be done here?
        command.interactive = False
        for paste_template in templates.pastescript_templates:
            paste_template.pre(command, dirname, vars)

        ### create the database
        if database:
            database.setup(**vars)
        
        ### create the trac environment
        options = templates.options_tuples(vars)
        options.append(('project', 'name', project)) # XXX needed?
        if self.inherit:
            options.append(('inherit', 'file', self.inherit))
        env = Environment(dirname, create=True, options=options)

        ### repository setup
        if repository:
            repository.setup(**vars)
            try:
                repos = env.get_repository()
                repos.sync()
            except TracError:
                pass

        ### read the generated configuration 
        _conf_file = os.path.join(dirname, 'conf', 'trac.ini')
        fp = file(_conf_file)
        _conf = fp.read()
        fp.close()

        ### run pastescript templates
        for paste_template in templates.pastescript_templates:
            paste_template.write_files(command, dirname, vars)
            paste_template.post(command, dirname, vars)

            # read permissions
            for agent, perm in paste_template.permissions.items():
                permissions.setdefault(agent, []).extend(perm)

            # read wiki directories
            wiki_dir = paste_template.wiki_dir()
            if wiki_dir is not None:
                wiki.append(wiki_dir)

        # write back munged configuration 
        munger = ConfigMunger(_conf, options)
        fp = file(_conf_file, 'w')
        munger.write(fp)
        fp.close()

        # TODO: update the inherited file:
        # * intertrac

        # trac-admin upgrade the project
        env = Environment(dirname)
        if env.needs_upgrade():
            env.upgrade()

        ### trac-admin operations
        admin = TracLegosAdmin(dirname)

        # remove the default items
        admin.delete_all()

        # load wiki pages
        admin.load_pages() # default wiki pages
        for page_dir in wiki:
            admin.load_pages(page_dir)

        # add permissions
        if permissions:
            admin.add_permissions(permissions)