diff --git a/alembic/versions/131ad2dc5bbd_table_for_no_new_branches_hook.py b/alembic/versions/131ad2dc5bbd_table_for_no_new_branches_hook.py new file mode 100644 index 0000000..4ca7659 --- /dev/null +++ b/alembic/versions/131ad2dc5bbd_table_for_no_new_branches_hook.py @@ -0,0 +1,38 @@ +"""Table for no new branches hook + +Revision ID: 131ad2dc5bbd +Revises: 7f31a9fad89f +Create Date: 2018-05-11 10:52:05.088806 + +""" + +# revision identifiers, used by Alembic. +revision = '131ad2dc5bbd' +down_revision = '7f31a9fad89f' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + """ Create table for PagureNoNewBranchesHook. """ + op.create_table( + 'hook_pagure_no_new_branches', + sa.Column('id', sa.INTEGER(), nullable=False), + sa.Column('project_id', sa.INTEGER(), nullable=False), + sa.Column('active', sa.BOOLEAN(), nullable=False), + sa.CheckConstraint(u'active IN (0, 1)'), + sa.ForeignKeyConstraint( + ['project_id'], + [u'projects.id'], + name=u'hook_pagure_no_new_branches_project_id_fkey', + onupdate=u'CASCADE', + ondelete=u'CASCADE' + ), + sa.PrimaryKeyConstraint('id', name=u'hook_pagure_no_new_branches_pkey') + ) + + +def downgrade(): + """ Remove table for PagureNoNewBranchesHook. """ + op.drop_table('hook_pagure_no_new_branches') diff --git a/pagure/hooks/files/pagure_no_new_branches b/pagure/hooks/files/pagure_no_new_branches new file mode 100755 index 0000000..759c9c4 --- /dev/null +++ b/pagure/hooks/files/pagure_no_new_branches @@ -0,0 +1,12 @@ +#!/bin/bash +# adapted from https://stackoverflow.com/a/29880516 + +retcode=0 +while read -r old new refname; do + if [[ $refname == refs/heads/* && $old != *[^0]* ]]; then + retcode=1 + echo "Creating new branches is disabled on this project." + fi +done + +exit $retcode diff --git a/pagure/hooks/pagure_no_new_branches.py b/pagure/hooks/pagure_no_new_branches.py new file mode 100644 index 0000000..a8a929d --- /dev/null +++ b/pagure/hooks/pagure_no_new_branches.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- + +""" + (c) 2014-2018 - Copyright Red Hat Inc + + Authors: + Slavek Kabrda <bkabrda@redhat.com> + +""" + +from __future__ import unicode_literals + +import os + +import sqlalchemy as sa +import wtforms +try: + from flask_wtf import FlaskForm +except ImportError: + from flask_wtf import Form as FlaskForm +from sqlalchemy.orm import relation +from sqlalchemy.orm import backref + +from pagure.hooks import BaseHook +from pagure.lib.model import BASE, Project +from pagure.utils import get_repo_path + + +class PagureNoNewBranchesTable(BASE): + """ Stores information about the pagure hook deployed on a project. + + Table -- hook_pagure_no_new_branches + """ + + __tablename__ = 'hook_pagure_no_new_branches' + + id = sa.Column(sa.Integer, primary_key=True) + project_id = sa.Column( + sa.Integer, + sa.ForeignKey( + 'projects.id', onupdate='CASCADE', ondelete='CASCADE'), + nullable=False, + unique=True, + index=True) + + active = sa.Column(sa.Boolean, nullable=False, default=False) + + project = relation( + 'Project', remote_side=[Project.id], + backref=backref( + 'pagure_hook_no_new_branches', + cascade="delete, delete-orphan", + single_parent=True, uselist=False) + ) + + +class PagureNoNewBranchesForm(FlaskForm): + ''' Form to configure the pagure hook. ''' + active = wtforms.BooleanField( + 'Active', + [wtforms.validators.Optional()] + ) + + +class PagureNoNewBranchesHook(BaseHook): + ''' PagureNoNewBranches hook. ''' + + name = 'Prevent creating new branches by git push' + description = 'This hook prevents creating new branches by git push.' + form = PagureNoNewBranchesForm + db_object = PagureNoNewBranchesTable + backref = 'pagure_hook_no_new_branches' + form_fields = ['active'] + hook_type = 'pre-receive' + + @classmethod + def install(cls, project, dbobj): + ''' Method called to install the hook for a project. + + :arg project: a ``pagure.model.Project`` object to which the hook + should be installed + + ''' + repopaths = [get_repo_path(project)] + + cls.base_install(repopaths, dbobj, 'pagure_no_new_branches', + 'pagure_no_new_branches') + + @classmethod + def remove(cls, project): + ''' Method called to remove the hook of a project. + + :arg project: a ``pagure.model.Project`` object to which the hook + should be installed + + ''' + cls.base_remove(repopaths, 'pagure_no_new_branches')