Changeset - ff287676b206
[Not reviewed]
default
0 3 0
Anton Schur - 9 years ago 2017-04-26 10:21:56
tonich.sh@gmail.com
tests: initial_repo_scan = false in test.ini, explicitly do repo scan in the pytest configure phase.
3 files changed with 12 insertions and 13 deletions:
0 comments (0 inline, 0 general)
kallithea/tests/conftest.py
Show inline comments
 
import os
 
import sys
 
import logging
 
import pkg_resources
 

	
 
from paste.deploy import loadwsgi
 
from routes.util import URLGenerator
 

	
 
import pytest
 
from kallithea.controllers.root import RootController
 
from kallithea.lib.utils import repo2db_mapper
 
from kallithea.model.user import UserModel
 
from kallithea.model.meta import Session
 
from kallithea.model.db import Setting, User, UserIpMap
 
from kallithea.tests.base import invalidate_all_caches, TEST_USER_REGULAR_LOGIN
 
from kallithea.model.scm import ScmModel
 
from kallithea.tests.base import invalidate_all_caches, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH
 
import kallithea.tests.base # FIXME: needed for setting testapp instance!!!
 

	
 
from tg.util.webtest import test_context
 

	
 
def pytest_configure():
 
    path = os.getcwd()
 
    sys.path.insert(0, path)
 
    pkg_resources.working_set.add_entry(path)
 

	
 
    # Disable INFO logging of test database creation, restore with NOTSET
 
    logging.disable(logging.INFO)
 

	
 
    context = loadwsgi.loadcontext(loadwsgi.APP, 'config:kallithea/tests/test.ini', relative_to=path)
 

	
 
    test_env = not int(os.environ.get('KALLITHEA_NO_TMP_PATH', 0))
 
    test_index = not int(os.environ.get('KALLITHEA_WHOOSH_TEST_DISABLE', 0))
 
    if os.environ.get('TEST_DB'):
 
        # swap config if we pass environment variable
 
        context.local_conf['sqlalchemy.url'] = os.environ.get('TEST_DB')
 

	
 
    from kallithea.tests.fixture import create_test_env, create_test_index
 
    from kallithea.tests.base import TESTS_TMP_PATH
 
    # set KALLITHEA_NO_TMP_PATH=1 to disable re-creating the database and
 
    # test repos
 
    if test_env:
 

	
 
    # set KALLITHEA_NO_TMP_PATH=1 to disable re-creating the database and test repos
 
    if not int(os.environ.get('KALLITHEA_NO_TMP_PATH', 0)):
 
        create_test_env(TESTS_TMP_PATH, context.config())
 

	
 
    # set KALLITHEA_WHOOSH_TEST_DISABLE=1 to disable whoosh index during tests
 
    if test_index:
 
    if not int(os.environ.get('KALLITHEA_WHOOSH_TEST_DISABLE', 0)):
 
        create_test_index(TESTS_TMP_PATH, context.config(), True)
 

	
 
    kallithea.tests.base.testapp = context.create()
 
    # do initial repo scan
 
    repo2db_mapper(ScmModel().repo_scan(TESTS_TMP_PATH))
 

	
 
    logging.disable(logging.NOTSET)
 

	
 
    kallithea.tests.base.url = URLGenerator(RootController().mapper, kallithea.tests.base.environ)
 

	
 

	
 
@pytest.fixture
 
def create_test_user():
 
    """Provide users that automatically disappear after test is over."""
 
    test_user_ids = []
 
    def _create_test_user(user_form):
 
        user = UserModel().create(user_form)
 
        test_user_ids.append(user.user_id)
 
        return user
 
    yield _create_test_user
 
    for user_id in test_user_ids:
 
        UserModel().delete(user_id)
 
    Session().commit()
 

	
 

	
 
def _set_settings(*kvtseq):
 
    session = Session()
 
    for kvt in kvtseq:
 
        assert len(kvt) in (2, 3)
 
        k = kvt[0]
 
        v = kvt[1]
 
        t = kvt[2] if len(kvt) == 3 else 'unicode'
 
        Setting.create_or_update(k, v, t)
 
    session.commit()
 

	
 

	
 
@pytest.fixture
 
def set_test_settings():
 
    """Restore settings after test is over."""
 
    # Save settings.
 
    settings_snapshot = [
 
        (s.app_settings_name, s.app_settings_value, s.app_settings_type)
 
        for s in Setting.query().all()]
 
    yield _set_settings
 
    # Restore settings.
 
    session = Session()
 
    keys = frozenset(k for (k, v, t) in settings_snapshot)
 
    for s in Setting.query().all():
 
        if s.app_settings_name not in keys:
 
            session.delete(s)
 
    for k, v, t in settings_snapshot:
 
        if t == 'list' and hasattr(v, '__iter__'):
 
            v = ','.join(v) # Quirk: must format list value manually.
 
        Setting.create_or_update(k, v, t)
 
    session.commit()
 

	
 
@pytest.fixture
 
def auto_clear_ip_permissions():
 
    """Fixture that provides nothing but clearing IP permissions upon test
 
    exit. This clearing is needed to avoid other test failing to make fake http
 
    accesses."""
 
    yield
 
    # cleanup
 
    user_model = UserModel()
 

	
 
    user_ids = []
 
    user_ids.append(User.get_default_user().user_id)
 
    user_ids.append(User.get_by_username(TEST_USER_REGULAR_LOGIN).user_id)
 

	
 
    for user_id in user_ids:
 
        for ip in UserIpMap.query().filter(UserIpMap.user_id == user_id):
 
            user_model.delete_extra_ip(user_id, ip.ip_id)
 

	
 
    # IP permissions are cached, need to invalidate this cache explicitly
 
    invalidate_all_caches()
 

	
 
@pytest.fixture
 
def test_context_fixture(app_fixture):
 
    """
 
    Encompass the entire test using this fixture in a test_context,
 
    making sure that certain functionality still works even if no call to
 
    self.app.get/post has been made.
 
    The typical error message indicating you need a test_context is:
 
        TypeError: No object (name: context) has been registered for this thread
 

	
 
    The standard way to fix this is simply using the test_context context
 
    manager directly inside your test:
 
        with test_context(self.app):
 
            <actions>
 
    but if test setup code (xUnit-style or pytest fixtures) also needs to be
 
    executed inside the test context, that method is not possible.
 
    Even if there is no such setup code, the fixture may reduce code complexity
 
    if the entire test needs to run inside a test context.
 

	
 
    To apply this fixture (like any other fixture) to all test methods of a
 
    class, use the following class decorator:
 
        @pytest.mark.usefixtures("test_context_fixture")
 
        class TestFoo(TestController):
 
            ...
 
    """
 
    with test_context(app_fixture):
 
        yield
kallithea/tests/test.ini
Show inline comments
 
################################################################################
 
################################################################################
 
# Kallithea - config for tests:                                                #
 
# initial_repo_scan = true                                                     #
 
# sqlalchemy and kallithea_test.sqlite                                         #
 
# custom logging                                                               #
 
#                                                                              #
 
# The %(here)s variable will be replaced with the parent directory of this file#
 
################################################################################
 
################################################################################
 

	
 
[DEFAULT]
 

	
 
################################################################################
 
## Email settings                                                             ##
 
##                                                                            ##
 
## Refer to the documentation ("Email settings") for more details.            ##
 
##                                                                            ##
 
## It is recommended to use a valid sender address that passes access         ##
 
## validation and spam filtering in mail servers.                             ##
 
################################################################################
 

	
 
## 'From' header for application emails. You can optionally add a name.
 
## Default:
 
#app_email_from = Kallithea
 
## Examples:
 
#app_email_from = Kallithea <kallithea-noreply@example.com>
 
#app_email_from = kallithea-noreply@example.com
 

	
 
## Subject prefix for application emails.
 
## A space between this prefix and the real subject is automatically added.
 
## Default:
 
#email_prefix =
 
## Example:
 
#email_prefix = [Kallithea]
 

	
 
## Recipients for error emails and fallback recipients of application mails.
 
## Multiple addresses can be specified, space-separated.
 
## Only addresses are allowed, do not add any name part.
 
## Default:
 
#email_to =
 
## Examples:
 
#email_to = admin@example.com
 
#email_to = admin@example.com another_admin@example.com
 
email_to =
 

	
 
## 'From' header for error emails. You can optionally add a name.
 
## Default: (none)
 
## Examples:
 
#error_email_from = Kallithea Errors <kallithea-noreply@example.com>
 
#error_email_from = kallithea_errors@example.com
 
error_email_from =
 

	
 
## SMTP server settings
 
## If specifying credentials, make sure to use secure connections.
 
## Default: Send unencrypted unauthenticated mails to the specified smtp_server.
 
## For "SSL", use smtp_use_ssl = true and smtp_port = 465.
 
## For "STARTTLS", use smtp_use_tls = true and smtp_port = 587.
 
smtp_server =
 
#smtp_username =
 
#smtp_password =
 
smtp_port =
 
#smtp_use_ssl = false
 
#smtp_use_tls = false
 

	
 
[server:main]
 
## Gearbox default web server ##
 
#use = egg:gearbox#wsgiref
 
## nr of worker threads to spawn
 
#threadpool_workers = 1
 
## max request before thread respawn
 
#threadpool_max_requests = 100
 
## option to use threads of process
 
#use_threadpool = true
 

	
 
## Gearbox gevent web server ##
 
#use = egg:gearbox#gevent
 

	
 
## WAITRESS ##
 
use = egg:waitress#main
 
## number of worker threads
 
threads = 1
 
## MAX BODY SIZE 100GB
 
max_request_body_size = 107374182400
 
## use poll instead of select, fixes fd limits, may not work on old
 
## windows systems.
 
#asyncore_use_poll = True
 

	
 
## GUNICORN ##
 
#use = egg:gunicorn#main
 
## number of process workers. You must set `instance_id = *` when this option
 
## is set to more than one worker
 
#workers = 1
 
## process name
 
#proc_name = kallithea
 
## type of worker class, one of sync, eventlet, gevent, tornado
 
## recommended for bigger setup is using of of other than sync one
 
#worker_class = sync
 
#max_requests = 1000
 
## amount of time a worker can handle request before it gets killed and
 
## restarted
 
#timeout = 3600
 

	
 
## UWSGI ##
 
## run with uwsgi --ini-paste-logged <inifile.ini>
 
#[uwsgi]
 
#socket = /tmp/uwsgi.sock
 
#master = true
 
#http = 127.0.0.1:5000
 

	
 
## set as deamon and redirect all output to file
 
#daemonize = ./uwsgi_kallithea.log
 

	
 
## master process PID
 
#pidfile = ./uwsgi_kallithea.pid
 

	
 
## stats server with workers statistics, use uwsgitop
 
## for monitoring, `uwsgitop 127.0.0.1:1717`
 
#stats = 127.0.0.1:1717
 
#memory-report = true
 

	
 
## log 5XX errors
 
#log-5xx = true
 

	
 
## Set the socket listen queue size.
 
#listen = 256
 

	
 
## Gracefully Reload workers after the specified amount of managed requests
 
## (avoid memory leaks).
 
#max-requests = 1000
 

	
 
## enable large buffers
 
#buffer-size = 65535
 

	
 
## socket and http timeouts ##
 
#http-timeout = 3600
 
#socket-timeout = 3600
 

	
 
## Log requests slower than the specified number of milliseconds.
 
#log-slow = 10
 

	
 
## Exit if no app can be loaded.
 
#need-app = true
 

	
 
## Set lazy mode (load apps in workers instead of master).
 
#lazy = true
 

	
 
## scaling ##
 
## set cheaper algorithm to use, if not set default will be used
 
#cheaper-algo = spare
 

	
 
## minimum number of workers to keep at all times
 
#cheaper = 1
 

	
 
## number of workers to spawn at startup
 
#cheaper-initial = 1
 

	
 
## maximum number of workers that can be spawned
 
#workers = 4
 

	
 
## how many workers should be spawned at a time
 
#cheaper-step = 1
 

	
 
## COMMON ##
 
host = 127.0.0.1
 
#port = 5000
 
port = 4999
 

	
 
## middleware for hosting the WSGI application under a URL prefix
 
#[filter:proxy-prefix]
 
#use = egg:PasteDeploy#prefix
 
#prefix = /<your-prefix>
 

	
 
[app:main]
 
use = egg:kallithea
 
## enable proxy prefix middleware
 
#filter-with = proxy-prefix
 

	
 
full_stack = true
 
static_files = true
 
## Available Languages:
 
## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
 
lang =
 
#cache_dir = %(here)s/data
 
cache_dir = %(here)s/../../data/test/cache
 
#index_dir = %(here)s/data/index
 
index_dir = %(here)s/../../data/test/index
 

	
 
## perform a full repository scan on each server start, this should be
 
## set to false after first startup, to allow faster server restarts.
 
#initial_repo_scan = false
 
initial_repo_scan = true
 
initial_repo_scan = false
 

	
 
## uncomment and set this path to use archive download cache
 
#archive_cache_dir = %(here)s/tarballcache
 
archive_cache_dir = %(here)s/../../data/test/tarballcache
 

	
 
## change this to unique ID for security
 
app_instance_uuid = test
 

	
 
## cut off limit for large diffs (size in bytes)
 
cut_off_limit = 256000
 

	
 
## force https in Kallithea, fixes https redirects, assumes it's always https
 
force_https = false
 

	
 
## use Strict-Transport-Security headers
 
use_htsts = false
 

	
 
## number of commits stats will parse on each iteration
 
commit_parse_limit = 25
 

	
 
## path to git executable
 
git_path = git
 

	
 
## git rev filter option, --all is the default filter, if you need to
 
## hide all refs in changelog switch this to --branches --tags
 
#git_rev_filter = --branches --tags
 

	
 
## RSS feed options
 
rss_cut_off_limit = 256000
 
rss_items_per_page = 10
 
rss_include_diff = false
 

	
 
## options for showing and identifying changesets
 
show_sha_length = 12
 
#show_revision_number = false
 
show_revision_number = true
 

	
 
## Canonical URL to use when creating full URLs in UI and texts.
 
## Useful when the site is available under different names or protocols.
 
## Defaults to what is provided in the WSGI environment.
 
#canonical_url = https://kallithea.example.com/repos
 

	
 
## gist URL alias, used to create nicer urls for gist. This should be an
 
## url that does rewrites to _admin/gists/<gistid>.
 
## example: http://gist.example.com/{gistid}. Empty means use the internal
 
## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/<gistid>
 
gist_alias_url =
 

	
 
## white list of API enabled controllers. This allows to add list of
 
## controllers to which access will be enabled by api_key. eg: to enable
 
## api access to raw_files put `FilesController:raw`, to enable access to patches
 
## add `ChangesetController:changeset_patch`. This list should be "," separated
 
## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
 
## Recommended settings below are commented out:
 
api_access_controllers_whitelist =
 
#    ChangesetController:changeset_patch,
 
#    ChangesetController:changeset_raw,
 
#    FilesController:raw,
 
#    FilesController:archivefile
 

	
 
## default encoding used to convert from and to unicode
 
## can be also a comma separated list of encoding in case of mixed encodings
 
default_encoding = utf8
 

	
 
## issue tracker for Kallithea (leave blank to disable, absent for default)
 
#bugtracker = https://bitbucket.org/conservancy/kallithea/issues
 

	
 
## issue tracking mapping for commits messages
 
## comment out issue_pat, issue_server, issue_prefix to enable
 

	
 
## pattern to get the issues from commit messages
 
## default one used here is #<numbers> with a regex passive group for `#`
 
## {id} will be all groups matched from this pattern
 

	
 
issue_pat = (?:\s*#)(\d+)
 

	
 
## server url to the issue, each {id} will be replaced with match
 
## fetched from the regex and {repo} is replaced with full repository name
 
## including groups {repo_name} is replaced with just name of repo
 

	
 
issue_server_link = https://issues.example.com/{repo}/issue/{id}
 

	
 
## prefix to add to link to indicate it's an url
 
## #314 will be replaced by <issue_prefix><id>
 

	
 
issue_prefix = #
 

	
 
## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
 
## multiple patterns, to other issues server, wiki or others
 
## below an example how to create a wiki pattern
 
# wiki-some-id -> https://wiki.example.com/some-id
 

	
 
#issue_pat_wiki = (?:wiki-)(.+)
 
#issue_server_link_wiki = https://wiki.example.com/{id}
 
#issue_prefix_wiki = WIKI-
 

	
 
## alternative return HTTP header for failed authentication. Default HTTP
 
## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
 
## handling that. Set this variable to 403 to return HTTPForbidden
 
auth_ret_code =
 

	
 
## locking return code. When repository is locked return this HTTP code. 2XX
 
## codes don't break the transactions while 4XX codes do
 
lock_ret_code = 423
 

	
 
## allows to change the repository location in settings page
 
allow_repo_location_change = True
 

	
 
## allows to setup custom hooks in settings page
 
allow_custom_hooks_settings = True
 

	
 
## extra extensions for indexing, space separated and without the leading '.'.
 
# index.extensions =
 
#    gemfile
 
#    lock
 

	
 
## extra filenames for indexing, space separated
 
# index.filenames =
 
#    .dockerignore
 
#    .editorconfig
 
#    INSTALL
 
#    CHANGELOG
 

	
 
####################################
 
###        CELERY CONFIG        ####
 
####################################
 

	
 
use_celery = false
 

	
 
## Example: connect to the virtual host 'rabbitmqhost' on localhost as rabbitmq:
 
broker.url = amqp://rabbitmq:qewqew@localhost:5672/rabbitmqhost
 

	
 
celery.imports = kallithea.lib.celerylib.tasks
 
celery.accept.content = pickle
 
celery.result.backend = amqp
 
celery.result.dburi = amqp://
 
celery.result.serialier = json
 

	
 
#celery.send.task.error.emails = true
 
#celery.amqp.task.result.expires = 18000
 

	
 
celeryd.concurrency = 2
 
celeryd.max.tasks.per.child = 1
 

	
 
## If true, tasks will never be sent to the queue, but executed locally instead.
 
celery.always.eager = false
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 

	
 
#beaker.cache.data_dir = %(here)s/data/cache/data
 
beaker.cache.data_dir = %(here)s/../../data/test/cache/data
 
#beaker.cache.lock_dir = %(here)s/data/cache/lock
 
beaker.cache.lock_dir = %(here)s/../../data/test/cache/lock
 

	
 
beaker.cache.regions = short_term,long_term,sql_cache_short
 

	
 
beaker.cache.short_term.type = memory
 
beaker.cache.short_term.expire = 60
 
beaker.cache.short_term.key_length = 256
 

	
 
beaker.cache.long_term.type = memory
 
beaker.cache.long_term.expire = 36000
 
beaker.cache.long_term.key_length = 256
 

	
 
beaker.cache.sql_cache_short.type = memory
 
#beaker.cache.sql_cache_short.expire = 10
 
beaker.cache.sql_cache_short.expire = 1
 
beaker.cache.sql_cache_short.key_length = 256
 

	
 
####################################
 
###       BEAKER SESSION        ####
 
####################################
 

	
 
## Name of session cookie. Should be unique for a given host and path, even when running
 
## on different ports. Otherwise, cookie sessions will be shared and messed up.
 
beaker.session.key = kallithea
 
## Sessions should always only be accessible by the browser, not directly by JavaScript.
 
beaker.session.httponly = true
 
## Session lifetime. 2592000 seconds is 30 days.
 
beaker.session.timeout = 2592000
 

	
 
## Server secret used with HMAC to ensure integrity of cookies.
 
beaker.session.secret = {74e0cd75-b339-478b-b129-07dd221def1f}
 
## Further, encrypt the data with AES.
 
#beaker.session.encrypt_key = <key_for_encryption>
 
#beaker.session.validate_key = <validation_key>
 

	
 
## Type of storage used for the session, current types are
 
## dbm, file, memcached, database, and memory.
 

	
scripts/generate-ini.py
Show inline comments
 
#!/usr/bin/env python2
 
"""
 
Based on kallithea/lib/paster_commands/template.ini.mako, generate
 
  development.ini
 
  kallithea/tests/test.ini
 
"""
 

	
 
import re
 

	
 
makofile = 'kallithea/lib/paster_commands/template.ini.mako'
 

	
 
# the mako conditionals used in all other ini files and templates
 
selected_mako_conditionals = set([
 
    "database_engine == 'sqlite'",
 
    "http_server == 'waitress'",
 
    "error_aggregation_service == 'appenlight'",
 
    "error_aggregation_service == 'sentry'",
 
])
 

	
 
# the mako variables used in all other ini files and templates
 
mako_variable_values = {
 
    'host': '127.0.0.1',
 
    'port': '5000',
 
    'here': '%(here)s',
 
    'uuid()': '${app_instance_uuid}',
 
}
 

	
 
# files to be generated from the mako template
 
ini_files = [
 
    ('kallithea/tests/test.ini',
 
        '''
 
        Kallithea - config for tests:
 
        initial_repo_scan = true
 
        sqlalchemy and kallithea_test.sqlite
 
        custom logging
 

	
 
        The %(here)s variable will be replaced with the parent directory of this file
 
        ''',
 
        {
 
            '[server:main]': {
 
                'port': '4999',
 
            },
 
            '[app:main]': {
 
                'initial_repo_scan': 'true',
 
                'app_instance_uuid': 'test',
 
                'show_revision_number': 'true',
 
                'beaker.cache.sql_cache_short.expire': '1',
 
                'beaker.session.secret': '{74e0cd75-b339-478b-b129-07dd221def1f}',
 
                'cache_dir': '%(here)s/../../data/test/cache',
 
                'index_dir': '%(here)s/../../data/test/index',
 
                'archive_cache_dir': '%(here)s/../../data/test/tarballcache',
 
                'beaker.cache.data_dir': '%(here)s/../../data/test/cache/data',
 
                'beaker.cache.lock_dir': '%(here)s/../../data/test/cache/lock',
 
                'sqlalchemy.url': 'sqlite:///%(here)s/kallithea_test.sqlite',
 
            },
 
            '[handler_console]': {
 
                'level': 'DEBUG',
 
                'formatter': 'color_formatter',
 
            },
 
            # The 'handler_console_sql' block is very similar to the one in
 
            # development.ini, but without the explicit 'level=DEBUG' setting:
 
            # it causes duplicate sqlalchemy debug logs, one through
 
            # handler_console_sql and another through another path.
 
            '[handler_console_sql]': {
 
                'formatter': 'color_formatter_sql',
 
            },
 
        },
 
    ),
 
    ('development.ini',
 
        '''
 
        Kallithea - Development config:
 
        listening on *:5000
 
        sqlite and kallithea.db
 
        initial_repo_scan = true
 
        debug = true
 
        verbose and colorful logging
 

	
 
        The %(here)s variable will be replaced with the parent directory of this file
 
        ''',
 
        {
 
            '[server:main]': {
 
                'host': '0.0.0.0',
 
            },
 
            '[app:main]': {
 
                'initial_repo_scan': 'true',
 
                'debug': 'true',
 
                'app_instance_uuid': 'development-not-secret',
 
                'beaker.session.secret': 'development-not-secret',
 
            },
 
            '[handler_console]': {
 
                'level': 'DEBUG',
 
                'formatter': 'color_formatter',
 
            },
 
            '[handler_console_sql]': {
 
                'level': 'DEBUG',
 
                'formatter': 'color_formatter_sql',
 
            },
 
        },
 
    ),
 
]
 

	
 

	
 
def main():
 
    # make sure all mako lines starting with '#' (the '##' comments) are marked up as <text>
 
    print 'reading:', makofile
 
    mako_org = file(makofile).read()
 
    mako_no_text_markup = re.sub(r'</?%text>', '', mako_org)
 
    mako_marked_up = re.sub(r'\n(##.*)', r'\n<%text>\1</%text>', mako_no_text_markup, flags=re.MULTILINE)
 
    if mako_marked_up != mako_org:
 
        print 'writing:', makofile
 
        file(makofile, 'w').write(mako_marked_up)
 

	
 
    # select the right mako conditionals for the other less sophisticated formats
 
    def sub_conditionals(m):
 
        """given a %if...%endif match, replace with just the selected
 
        conditional sections enabled and the rest as comments
 
        """
 
        conditional_lines = m.group(1)
 
        def sub_conditional(m):
 
            """given a conditional and the corresponding lines, return them raw
 
            or commented out, based on whether conditional is selected
 
            """
 
            criteria, lines = m.groups()
 
            if criteria not in selected_mako_conditionals:
 
                lines = '\n'.join((l if not l or l.startswith('#') else '#' + l) for l in lines.split('\n'))
 
            return lines
 
        conditional_lines = re.sub(r'^%(?:el)?if (.*):\n((?:^[^%\n].*\n|\n)*)',
 
            sub_conditional, conditional_lines, flags=re.MULTILINE)
 
        return conditional_lines
 
    mako_no_conditionals = re.sub(r'^(%if .*\n(?:[^%\n].*\n|%elif .*\n|\n)*)%endif\n',
 
        sub_conditionals, mako_no_text_markup, flags=re.MULTILINE)
 

	
 
    # expand mako variables
 
    def pyrepl(m):
 
        return mako_variable_values.get(m.group(1), m.group(0))
 
    mako_no_variables = re.sub(r'\${([^}]*)}', pyrepl, mako_no_conditionals)
 

	
 
    # remove utf-8 coding header
 
    base_ini = re.sub(r'^## -\*- coding: utf-8 -\*-\n', '', mako_no_variables)
 

	
 
    # create ini files
 
    for fn, desc, settings in ini_files:
 
        print 'updating:', fn
 
        ini_lines = re.sub(
 
            '# Kallithea - config file generated with kallithea-config *#\n',
 
            ''.join('# %-77s#\n' % l.strip() for l in desc.strip().split('\n')),
 
            base_ini)
 
        def process_section(m):
 
            """process a ini section, replacing values as necessary"""
 
            sectionname, lines = m.groups()
 
            if sectionname in settings:
 
                section_settings = settings[sectionname]
 
                def process_line(m):
 
                    """process a section line and update value if necessary"""
 
                    setting, value = m.groups()
 
                    line = m.group(0)
 
                    if setting in section_settings:
 
                        line = '%s = %s' % (setting, section_settings[setting])
 
                        if '$' not in value:
 
                            line = '#%s = %s\n%s' % (setting, value, line)
 
                    return line.rstrip()
 
                lines = re.sub(r'^([^#\n].*) = ?(.*)', process_line, lines, flags=re.MULTILINE)
 
            return sectionname + '\n' + lines
 
        ini_lines = re.sub(r'^(\[.*\])\n((?:(?:[^[\n].*)?\n)*)', process_section, ini_lines, flags=re.MULTILINE)
 
        file(fn, 'w').write(ini_lines)
 

	
 
if __name__ == '__main__':
 
    main()
0 comments (0 inline, 0 general)