Changeset - 3bc8d2e08966
[Not reviewed]
beta
0 2 0
Marcin Kuzminski - 13 years ago 2012-11-08 14:24:31
marcin@python-works.com
git hook installation should be only executed for git backend
2 files changed with 6 insertions and 7 deletions:
0 comments (0 inline, 0 general)
docs/usage/git_support.rst
Show inline comments
 
.. _git_support:
 

	
 
===========
 
GIT support
 
===========
 

	
 

	
 
Git support in RhodeCode 1.3 was enabled by default. You need to have a git
 
client installed on the machine to make git fully work.
 

	
 
Although There are some limitations on git usage.
 
Although There is one limitation on git usage.
 

	
 
- hooks that are executed on pull/push are not *real* hooks, they are 
 
  just emulating the behavior, and are executed **BEFORE** action takes place.
 
- large pushes needs http server with chunked encoding support.
 
- large pushes requires a http server with chunked encoding support.
 
 
 
if you plan to use git you need to run RhodeCode with some
 
http server that supports chunked encoding which git http protocol uses, 
 
i recommend using waitress_ or gunicorn_ (linux only) for `paste` wsgi app 
 
replacement.
 
replacement. Starting from version 1.4 waitress_ is the default wsgi server
 
used in RhodeCode.
 

	
 
To use, simply change change the following in the .ini file::
 

	
 
    use = egg:Paste#http
 

	
 
to::
 
    
 
    use = egg:waitress#main
 

	
 
or::
 

	
 
    use = egg:gunicorn#main
 
    
 
    
 
And comment out bellow options::
 

	
 
    threadpool_workers = 
 
    threadpool_max_requests = 
 
    use_threadpool = 
 
    
 

	
 
You can simply run `paster serve` as usual.
 

	
 
  
 
You can always disable git/hg support by editing a 
 
file **rhodecode/__init__.py** and commenting out backends
 

	
 
.. code-block:: python
 
 
 
   BACKENDS = {
 
       'hg': 'Mercurial repository',
 
       #'git': 'Git repository',
 
   }
 

	
 
.. _waitress: http://pypi.python.org/pypi/waitress
 
.. _gunicorn: http://pypi.python.org/pypi/gunicorn
 
\ No newline at end of file
rhodecode/lib/celerylib/tasks.py
Show inline comments
 
@@ -218,231 +218,231 @@ def get_commits_stats(repo_name, ts_min_
 
        stats.commit_activity_combined = json.dumps(overview_data)
 

	
 
        log.debug('last revison %s' % last_rev)
 
        leftovers = len(repo.revisions[last_rev:])
 
        log.debug('revisions to parse %s' % leftovers)
 

	
 
        if last_rev == 0 or leftovers < parse_limit:
 
            log.debug('getting code trending stats')
 
            stats.languages = json.dumps(__get_codes_stats(repo_name))
 

	
 
        try:
 
            stats.repository = dbrepo
 
            stats.stat_on_revision = last_cs.revision if last_cs else 0
 
            DBS.add(stats)
 
            DBS.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            DBS.rollback()
 
            lock.release()
 
            return False
 

	
 
        # final release
 
        lock.release()
 

	
 
        # execute another task if celery is enabled
 
        if len(repo.revisions) > 1 and CELERY_ON:
 
            run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
 
        return True
 
    except LockHeld:
 
        log.info('LockHeld')
 
        return 'Task with key %s already running' % lockkey
 

	
 
@task(ignore_result=True)
 
@dbsession
 
def send_password_link(user_email):
 
    from rhodecode.model.notification import EmailNotificationModel
 

	
 
    log = get_logger(send_password_link)
 
    DBS = get_session()
 

	
 
    try:
 
        user = User.get_by_email(user_email)
 
        if user:
 
            log.debug('password reset user found %s' % user)
 
            link = url('reset_password_confirmation', key=user.api_key,
 
                       qualified=True)
 
            reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
 
            body = EmailNotificationModel().get_email_tmpl(reg_type,
 
                                                **{'user':user.short_contact,
 
                                                   'reset_url':link})
 
            log.debug('sending email')
 
            run_task(send_email, user_email,
 
                     _("password reset link"), body)
 
            log.info('send new password mail to %s' % user_email)
 
        else:
 
            log.debug("password reset email %s not found" % user_email)
 
    except:
 
        log.error(traceback.format_exc())
 
        return False
 

	
 
    return True
 

	
 
@task(ignore_result=True)
 
@dbsession
 
def reset_user_password(user_email):
 
    from rhodecode.lib import auth
 

	
 
    log = get_logger(reset_user_password)
 
    DBS = get_session()
 

	
 
    try:
 
        try:
 
            user = User.get_by_email(user_email)
 
            new_passwd = auth.PasswordGenerator().gen_password(8,
 
                             auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
 
            if user:
 
                user.password = auth.get_crypt_password(new_passwd)
 
                user.api_key = auth.generate_api_key(user.username)
 
                DBS.add(user)
 
                DBS.commit()
 
                log.info('change password for %s' % user_email)
 
            if new_passwd is None:
 
                raise Exception('unable to generate new password')
 
        except:
 
            log.error(traceback.format_exc())
 
            DBS.rollback()
 

	
 
        run_task(send_email, user_email,
 
                 'Your new password',
 
                 'Your new RhodeCode password:%s' % (new_passwd))
 
        log.info('send new password mail to %s' % user_email)
 

	
 
    except:
 
        log.error('Failed to update user password')
 
        log.error(traceback.format_exc())
 

	
 
    return True
 

	
 

	
 
@task(ignore_result=True)
 
@dbsession
 
def send_email(recipients, subject, body, html_body=''):
 
    """
 
    Sends an email with defined parameters from the .ini files.
 

	
 
    :param recipients: list of recipients, it this is empty the defined email
 
        address from field 'email_to' is used instead
 
    :param subject: subject of the mail
 
    :param body: body of the mail
 
    :param html_body: html version of body
 
    """
 
    log = get_logger(send_email)
 
    DBS = get_session()
 

	
 
    email_config = config
 
    subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
 
    if not recipients:
 
        # if recipients are not defined we send to email_config + all admins
 
        admins = [u.email for u in User.query()
 
                  .filter(User.admin == True).all()]
 
        recipients = [email_config.get('email_to')] + admins
 

	
 
    mail_from = email_config.get('app_email_from', 'RhodeCode')
 
    user = email_config.get('smtp_username')
 
    passwd = email_config.get('smtp_password')
 
    mail_server = email_config.get('smtp_server')
 
    mail_port = email_config.get('smtp_port')
 
    tls = str2bool(email_config.get('smtp_use_tls'))
 
    ssl = str2bool(email_config.get('smtp_use_ssl'))
 
    debug = str2bool(config.get('debug'))
 
    smtp_auth = email_config.get('smtp_auth')
 

	
 
    try:
 
        m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
 
                       mail_port, ssl, tls, debug=debug)
 
        m.send(recipients, subject, body, html_body)
 
    except:
 
        log.error('Mail sending failed')
 
        log.error(traceback.format_exc())
 
        return False
 
    return True
 

	
 

	
 
@task(ignore_result=True)
 
@dbsession
 
def create_repo_fork(form_data, cur_user):
 
    """
 
    Creates a fork of repository using interval VCS methods
 

	
 
    :param form_data:
 
    :param cur_user:
 
    """
 
    from rhodecode.model.repo import RepoModel
 
    from rhodecode.model.user import UserModel
 

	
 
    log = get_logger(create_repo_fork)
 
    DBS = get_session()
 

	
 
    base_path = Repository.base_path()
 
    cur_user = UserModel(DBS)._get_user(cur_user)
 

	
 
    fork_name = form_data['repo_name_full']
 
    repo_type = form_data['repo_type']
 
    description = form_data['description']
 
    owner = cur_user
 
    private = form_data['private']
 
    clone_uri = form_data.get('clone_uri')
 
    repos_group = form_data['repo_group']
 
    landing_rev = form_data['landing_rev']
 
    copy_fork_permissions = form_data.get('copy_permissions')
 
    fork_of = RepoModel(DBS)._get_repo(form_data.get('fork_parent_id'))
 

	
 
    fork_repo = RepoModel(DBS).create_repo(
 
        fork_name, repo_type, description, owner, private, clone_uri,
 
        repos_group, landing_rev, just_db=True, fork_of=fork_of,
 
        copy_fork_permissions=copy_fork_permissions
 
    )
 

	
 
    update_after_clone = form_data['update_after_clone']
 

	
 
    source_repo_path = os.path.join(base_path, fork_of.repo_name)
 
    destination_fork_path = os.path.join(base_path, fork_name)
 

	
 
    log.info('creating fork of %s as %s', source_repo_path,
 
             destination_fork_path)
 
    backend = get_backend(repo_type)
 

	
 
    if repo_type == 'git':
 
        r = backend(safe_str(destination_fork_path), create=True,
 
                src_url=safe_str(source_repo_path),
 
                update_after_clone=update_after_clone,
 
                bare=True)
 
        # add rhodecode hook into this repo
 
        ScmModel().install_git_hook(repo=r)
 
    elif repo_type == 'hg':
 
        r = backend(safe_str(destination_fork_path), create=True,
 
                src_url=safe_str(source_repo_path),
 
                update_after_clone=update_after_clone)
 
    else:
 
        raise Exception('Unknown backend type %s' % repo_type)
 

	
 
    # add rhodecode hook into this repo
 
    ScmModel().install_git_hook(repo=r)
 
    log_create_repository(fork_repo.get_dict(), created_by=cur_user.username)
 

	
 
    action_logger(cur_user, 'user_forked_repo:%s' % fork_name,
 
                   fork_of.repo_name, '', DBS)
 

	
 
    action_logger(cur_user, 'user_created_fork:%s' % fork_name,
 
                   fork_name, '', DBS)
 
    # finally commit at latest possible stage
 
    DBS.commit()
 

	
 

	
 
def __get_codes_stats(repo_name):
 
    from rhodecode.config.conf import  LANGUAGES_EXTENSIONS_MAP
 
    repo = Repository.get_by_repo_name(repo_name).scm_instance
 

	
 
    tip = repo.get_changeset()
 
    code_stats = {}
 

	
 
    def aggregate(cs):
 
        for f in cs[2]:
 
            ext = lower(f.extension)
 
            if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
 
                if ext in code_stats:
 
                    code_stats[ext] += 1
 
                else:
 
                    code_stats[ext] = 1
 

	
 
    map(aggregate, tip.walk('/'))
 

	
 
    return code_stats or {}
0 comments (0 inline, 0 general)