#2507 Fixes the README.rst file
Closed 6 years ago by pingou. Opened 6 years ago by ompragash.
ompragash/pagure UpdateREADME  into  master

file modified
+1 -1
@@ -98,7 +98,7 @@ 

  * Create the folder that will receive the projects, forks, docs, requests and

    tickets' git repo::

  

-     mkdir -p lcl/{repos,docs,forks,tickets,requests,remotes,attachments}

+     mkdir -p lcl/{repos,docs,forks,tickets,requests,remotes,attachments,releases}

  

  

  * Create the inital database scheme::

@@ -16,22 +16,22 @@ 

  

  pstart (){

      systemctl --user start pagure.service pagure-docs.service pagure_ci.service\

-         pagure_ev.service pagure_webhook.service

+         pagure_ev.service pagure_webhook.service pagure_worker.service

      echo 'The application is running on http://localhost:5000/'

  }

  

  pstop (){

      systemctl --user stop pagure.service pagure-docs.service pagure_ci.service\

-         pagure_ev.service pagure_webhook.service

+         pagure_ev.service pagure_webhook.service pagure_worker.service

  }

  

  prestart (){

      systemctl --user restart pagure.service pagure-docs.service pagure_ci.service\

-         pagure_ev.service pagure_webhook.service

+         pagure_ev.service pagure_webhook.service pagure_worker.service

      echo 'The application is running on http://localhost:5000/'

  }

  

  pstatus (){

      systemctl --user status pagure.service pagure-docs.service pagure_ci.service\

-         pagure_ev.service pagure_webhook.service

+         pagure_ev.service pagure_webhook.service pagure_worker.service

  }

@@ -4,7 +4,7 @@ 

  

  [Service]

  Environment="PAGURE_CONFIG=/home/vagrant/pagure.cfg"

- ExecStart=/home/vagrant/.virtualenvs/python2-pagure/bin/python %h/devel/runserver.py --host 0.0.0.0

+ ExecStart=/home/vagrant/.virtualenvs/python2-pagure/bin/python %h/devel/runserver.py --host 0.0.0.0 --debug

  Type=simple

  

  [Install]

@@ -0,0 +1,13 @@ 

+ [Unit]

+ Description=Pagure worker for backend git interaction

+ After=redis.target

+ Documentation=https://pagure.io/pagure

+ 

+ [Service]

+ ExecStart=/usr/bin/celery worker -A pagure.lib.tasks --loglevel=info --autoreload

+ Environment="PAGURE_CONFIG=/home/vagrant/pagure.cfg"

+ Type=simple

+ Restart=on-failure

+ 

+ [Install]

+ WantedBy=multi-user.target

@@ -174,3 +174,18 @@ 

      - pagure_ci.service

      - pagure_ev.service

      - pagure_webhook.service

+     - pagure_worker.service

+ 

+ - name: Enable the Pagure systemd services

+   become: False

+   systemd:

+     name: "{{ item }}"

+     enabled: True

+     user: yes

+   with_items:

+     - pagure

+     - pagure-docs

+     - pagure_ci

+     - pagure_ev

+     - pagure_webhook

+     - pagure_worker

file modified
+92
@@ -387,6 +387,49 @@ 

  all projects hosted on this pagure instance.

  

  

+ API token ACLs

+ --------------

+ 

+ ACLS

+ ~~~~

+ 

+ This configuration key lists all the ACLs that can be associated with an API

+ token with a short description of what the ACL allows to do.

+ This key it not really meant to be changed unless you really know what you

+ are doing.

+ 

+ USER_ACLS

+ ~~~~~~~~~

+ 

+ This configuration key allows to list which of the ACLs listed in ``ACLS``

+ can be associated with an API token of a project in the (web) user interface.

+ 

+ Use this configuration key in combination with ``ADMIN_API_ACLS`` to disable

+ certain ACLs for users while allowing admins to generate keys with them.

+ 

+ Defaults to: ``ACLS.keys()`` (ie: all the ACLs in ``ACLS``)

+ 

+ 

+ ADMIN_API_ACLS

+ ~~~~~~~~~~~~~~

+ 

+ This configuration key allows to list which of the ACLs listed in ``ACLS``

+ can be generated by the ``pagure-admin`` CLI tool by admins.

+ 

+ Defaults to: ``['create_project', 'fork_project', 'modify_project']``

+ 

+ 

+ CROSS_PROJECT_ACLS

+ ~~~~~~~~~~~~~~~~~~

+ 

+ This configuration key allows to list which of the ACLs listed in ``ACLS``

+ can be associated with a project-less API token in the (web) user interface.

+ These project-less API tokens can be generated in the user's settings page

+ and allows action in multiple projects instead of being restricted to a

+ specific one.

+ 

+ Defaults to: ``['issue_comment', 'issue_create', 'issue_change_status', 'pull_request_flag', 'pull_request_comment', 'pull_request_merge']``

+ 

  

  Optional options

  ----------------
@@ -578,6 +621,37 @@ 

      This does not disable emails to the email address set in ``EMAIL_ERROR``.

  

  

+ ALLOW_DELETE_BRANCH

+ ~~~~~~~~~~~~~~~~~~~

+ 

+ This configuration keys enables or disables allowing users to delete git

+ branches from the user interface. In sensible pagure instance you may

+ want to turn this off and with a customized gitolite configuration you can

+ prevent users from deleting branches in their git repositories.

+ 

+ Defaults to: ``True``.

+ 

+ 

+ LOCAL_SSH_KEY

+ ~~~~~~~~~~~~~

+ 

+ This configuration key allows to let pagure administrate the user's ssh keys

+ or have a third party tool do it for you.

+ In most cases, it will be fine to let pagure handle it.

+ 

+ Defaults to ``True``.

+ 

+ 

+ DEPLOY_KEY

+ ~~~~~~~~~~

+ 

+ This configuration key allows to disable the deploy keys feature of an

+ entire pagure instance. This feature enable to add extra public ssh keys

+ that a third party could use to push to a project.

+ 

+ Defaults to ``True``.

+ 

+ 

  OLD_VIEW_COMMIT_ENABLED

  ~~~~~~~~~~~~~~~~~~~~~~~

  
@@ -809,6 +883,24 @@ 

  Defaults to: ``{}``

  

  

+ HTML_TITLE

+ ~~~~~~~~~~

+ 

+ This configuration key allows you to customize the HTML title of all the

+ pages, from ``... - pagure`` (default) to ``... - <your value>``.

+ 

+ Defaults to: ``Pagure``

+ 

+ 

+ CASE_SENSITIVE

+ ~~~~~~~~~~~~~~

+ 

+ This configuration key allows to make this pagure instance case sensitive

+ instead of its default: case-insensitive.

+ 

+ Defaults to: ``False``

+ 

+ 

  Deprecated configuration keys

  -----------------------------

  

file modified
+9 -5
@@ -3,18 +3,18 @@ 

  

  Pagure would be nothing without its contributors.

  

- On July 24, 2017 (release 3.3.1), the list looks as follow:

+ On August 08, 2017 (release 3.5), the list looks as follow:

  

  =================  ===========

  Number of commits  Contributor

  =================  ===========

-   5337              Pierre-Yves Chibon <pingou@pingoured.fr>

+   5361              Pierre-Yves Chibon <pingou@pingoured.fr>

     191              Ryan Lerch <rlerch@redhat.com>

-    143              Vivek Anand <vivekanand1101@gmail.com>

+    145              Vivek Anand <vivekanand1101@gmail.com>

     139              farhaanbukhsh <farhaan.bukhsh@gmail.com>

     126              Patrick Uiterwijk <puiterwijk@redhat.com>

      77              Farhaan Bukhsh <farhaan.bukhsh@gmail.com>

-     66              Clement Verna <cverna@tutanota.com>

+     68              Clement Verna <cverna@tutanota.com>

      59              Johan Cwiklinski <johan@x-tnd.be>

      47              Mark Reynolds <mreynolds@redhat.com>

      32              Pradeep CE (cep) <breathingcode@gmail.com>
@@ -55,6 +55,7 @@ 

       3              Till Maas <opensource@till.name>

       3              bill auger <mr.j.spam.me@gmail.com>

       3              cep <breathingcode@gmail.com>

+      3              shivani <smshivani579@gmail.com>

       3              skrzepto <shims506@gmail.com>

       3              tenstormavi <avi.avinash3008@gmail.com>

       2              Carlos Mogas da Silva <r3pek@r3pek.org>
@@ -69,20 +70,23 @@ 

       2              bruno <bruno@wolff.to>

       2              clime <clime@redhat.com>

       2              dhrish20 <dhrish20@gmail.com>

-      2              shivani <smshivani579@gmail.com>

       2              “AnjaliPardeshi” <“anjalipardeshi92@gmail.com”>

       1              Aleksandra Fedorova (bookwar) <afedorova@mirantis.com>

       1              Amol Kahat <akahat@redhat.com>

       1              Anthony Lackey <alackey@localhost.localdomain>

       1              Arti Laddha <artiladdha53@gmail.com>

       1              Brian (bex) Exelbierd <bex@pobox.com>

+      1              Carl George <carl@george.computer>

       1              Charelle Collett <ccollett@redhat.com>

       1              David Caro <dcaroest@redhat.com>

       1              Eashan <eashankadam@gmail.com>

       1              Haikel Guemar <hguemar@fedoraproject.org>

+      1              Hazel Smith <hazel@hazelesque.uk>

       1              Igor Gnatenko <ignatenkobrain@fedoraproject.org>

       1              Kunaal Jain <kunaalus@gmail.com>

       1              Mathew Robinson <mathew.robinson3114@gmail.com>

+      1              Ompragash <om.apsara@gmail.com>

+      1              Patrick Uiterwijk <patrick@puiterwijk.org>

       1              Pierre-YvesChibon <pingou@fedoraproject.org>

       1              Robert Bost <rbost@redhat.com>

       1              Snehal Karale <skarale@redhat.com>

file modified
+38 -1
@@ -2,7 +2,7 @@ 

  %distutils.sysconfig import get_python_lib; print (get_python_lib())")}

  

  Name:               pagure

- Version:            3.3.1

+ Version:            3.5

  Release:            1%{?dist}

  Summary:            A git-centered forge

  
@@ -384,6 +384,43 @@ 

  

  

  %changelog

+ * Tue Aug 08 2017 Pierre-Yves Chibon <pingou@pingoured.fr> - 3.5-1

+ - Update to 3.5

+ - Fix login when groups are managed outside

+ - Fix the ordering of the issues by priority using JS and its documentation

+ - Indicate the issue/PR status in the title of its link

+ - Correct typo in waiting page template: 'You task' -> 'Your task' (Hazel Smith)

+ - Fix redirect in search (Carl George)

+ - Fix removing users of a project

+ - Allow customizing the HTML title globally

+ - Drop the new line character and the '# end of body' message when loading the

+   config

+ - Scroll to the comment section on clicking reply. (shivani)

+ - only show issues on the My Issue page if the issue tracker is on for the

+   project (Vivek Anand)

+ - Update the refresh-gitolite action of pagure-admin for the new interface

+   (turns out this wasn't in fact merged in 3.4)

+ - Add a configuration key to make pagure case sensitive

+ - Add an USER_ACLS configuration key

+ - Document the different API token ACLs configuration keys

+ - Fix syncing groups from external account sources (Patrick Uiterwijk)

+ 

+ * Mon Jul 31 2017 Pierre-Yves Chibon <pingou@pingoured.fr> - 3.4-1

+ - Update to 3.4

+ - Fix layout breakage in the doc

+ - Stop using readlines() to drop the trailing new line character

+ - Fix logging by properly formatting the message

+ - Fix the issue count in the My Issues page (Vivek Anand)

+ - Add a configuration key to disable deleting branches from the UI

+ - Add a configuration key to disable managing user's ssh key in pagure

+ - Fix the vagrant environment (Clement Verna)

+ - Fix branch support for the git blame view

+ - Update the PR ref when the PR is updated

+ - Add a configuration key to disable the deploy keys in a pagure instance

+ - Fix login when groups are managed outside of pagure

+ - Fix setting up the git hooks when there is no DOCS_FOLDER set

+ - Fix installing up the pagure hooks when there is no DOCS_FOLDER set

+ 

  * Mon Jul 24 2017 Pierre-Yves Chibon <pingou@pingoured.fr> - 3.3.1-1

  - Update to 3.3.1

  - Fix typo in the alembic migration present in 3.3

@@ -158,7 +158,8 @@ 

                   '%s/' % namespace if namespace else '',

                   repo, username)

          project = pagure.lib._get_project(

-             session, repo, user=username, namespace=namespace)

+             session, repo, user=username, namespace=namespace,

+             case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

          if not project:

              _log.info('No project found')

@@ -104,7 +104,8 @@ 

                   '%s/' % namespace if namespace else '',

                   repo, username)

          project = pagure.lib._get_project(

-             pagure.SESSION, repo, user=username, namespace=namespace)

+             pagure.SESSION, repo, user=username, namespace=namespace,

+             case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

          if not project:

              _log.info('No project found')

@@ -139,7 +139,8 @@ 

          session = pagure.lib.create_session(pagure.APP.config['DB_URL'])

          project = pagure.lib._get_project(

              session=session, name=projectname, user=username,

-             namespace=namespace)

+             namespace=namespace,

+             case=pagure.APP.config.get('CASE_SENSITIVE', False))

          if not project:

              log.info('No project found with these criteria')

              session.close()

file modified
+34 -27
@@ -12,7 +12,7 @@ 

  __requires__ = ['SQLAlchemy >= 0.8', 'jinja2 >= 2.4']

  import pkg_resources  # noqa: E402,F401

  

- __version__ = '3.3.1'

+ __version__ = '3.5'

  __api_version__ = '0.15'

  

  
@@ -139,33 +139,37 @@ 

                  fas_groups = set(flask.g.fas_user.groups)

                  # Add the new groups

                  for group in fas_groups - groups:

-                     group = pagure.lib.search_groups(

-                         SESSION, group_name=group)

-                     if not group:

-                         continue

-                     try:

-                         pagure.lib.add_user_to_group(

-                             session=SESSION,

-                             username=flask.g.fas_user.username,

-                             group=group,

-                             user=flask.g.fas_user.username,

-                             is_admin=is_admin(),

-                         )

-                     except pagure.exceptions.PagureException as err:

-                         APP.logger.debug(err)

+                     groupobj = None

+                     if group:

+                         groupobj = pagure.lib.search_groups(

+                             SESSION, group_name=group)

+                     if groupobj:

+                         try:

+                             pagure.lib.add_user_to_group(

+                                 session=SESSION,

+                                 username=flask.g.fas_user.username,

+                                 group=groupobj,

+                                 user=flask.g.fas_user.username,

+                                 is_admin=is_admin(),

+                                 from_external=True,

+                             )

+                         except pagure.exceptions.PagureException as err:

+                             APP.logger.error(err)

                  # Remove the old groups

                  for group in groups - fas_groups:

-                     try:

-                         pagure.lib.delete_user_of_group(

-                             session=SESSION,

-                             username=flask.g.fas_user.username,

-                             groupname=group,

-                             user=flask.g.fas_user.username,

-                             is_admin=is_admin(),

-                             force=True,

-                         )

-                     except pagure.exceptions.PagureException as err:

-                         APP.logger.debug(err)

+                     if group:

+                         try:

+                             pagure.lib.delete_user_of_group(

+                                 session=SESSION,

+                                 username=flask.g.fas_user.username,

+                                 groupname=group,

+                                 user=flask.g.fas_user.username,

+                                 is_admin=is_admin(),

+                                 force=True,

+                                 from_external=True,

+                             )

+                         except pagure.exceptions.PagureException as err:

+                             APP.logger.error(err)

  

              SESSION.commit()

          except SQLAlchemyError as err:
@@ -386,7 +390,10 @@ 

      :rtype: Project

  

      '''

-     repo = pagure.lib._get_project(session, project_name, user, namespace)

+     repo = pagure.lib._get_project(

+         session, project_name, user, namespace,

+         case=APP.config.get('CASE_SENSITIVE', False)

+     )

  

      if repo and repo.private and not is_repo_admin(repo):

          return None

file modified
+2 -1
@@ -45,7 +45,8 @@ 

      """

  

      project = pagure.lib._get_project(

-         SESSION, repo, user=username, namespace=namespace)

+         SESSION, repo, user=username, namespace=namespace,

+         case=APP.config.get('CASE_SENSITIVE', False))

      flask.g.repo_locked = True

      flask.g.repo = project

      if not project:

file modified
+2 -1
@@ -764,7 +764,8 @@ 

                  result = pagure.lib.tasks.get_result(taskid).get()

                  project = pagure.lib._get_project(

                      SESSION, name=result['repo'],

-                     namespace=result['namespace'])

+                     namespace=result['namespace'],

+                     case=APP.config.get('CASE_SENSITIVE', False))

                  output = {'message': 'Project "%s" created' % project.fullname}

          except pagure.exceptions.PagureException as err:

              raise pagure.exceptions.APIError(

file modified
+52 -10
@@ -23,6 +23,7 @@ 

  import pagure.exceptions  # noqa: E402

  import pagure.lib  # noqa: E402

  import pagure.lib.git  # noqa: E402

+ import pagure.lib.tasks  # noqa: E402

  from pagure import (SESSION, APP, generate_user_key_files)  # noqa: E402

  

  
@@ -34,6 +35,16 @@ 

      local_parser = subparser.add_parser(

          'refresh-gitolite',

          help='Re-generate the gitolite config file')

+     local_parser.add_argument(

+         '--user', help="User of the project (to use only on forks)")

+     local_parser.add_argument(

+         '--project', help="Project to update (as namespace/project if there "

+         "is a namespace)")

+     local_parser.add_argument(

+         '--group', help="Group to refresh")

+     local_parser.add_argument(

+         '--all', dest="all_", default=False, action='store_true',

+         help="Refresh all the projects")

      local_parser.set_defaults(func=do_generate_acl)

  

  
@@ -156,23 +167,54 @@ 

      return raw_input(text)

  

  

- def do_generate_acl(_):

+ def do_generate_acl(args):

      """ Regenerate the gitolite ACL file.

  

  

-     :arg _: the argparse object returned by ``parse_arguments()``, which is

-         ignored as there are no argument to pass to this action.

+     :arg args: the argparse object returned by ``parse_arguments()``.

  

      """

-     cmd = pagure.lib.git._get_gitolite_command()

-     if not cmd:

-         raise pagure.exceptions.PagureException(

-             '/!\ un-able to generate the right gitolite command')

+     _log.debug('group:          %s', args.group)

+     _log.debug('project:        %s', args.project)

+     _log.debug('user:           %s', args.user)

+     _log.debug('all:            %s', args.all_)

+ 

+     title = None

+     project = None

+     if args.project:

+         namespace = None

+         if '/' in args.project:

+             if args.project.count('/') > 1:

+                 raise pagure.exceptions.PagureException(

+                     'Invalid project name, has more than one "/": %s' %

+                     args.project)

+             namespace, name = args.project.split('/')

+         else:

+             name = args.project

+         project = pagure.lib._get_project(

+             SESSION, namespace=namespace, name=name, user=args.user)

+         title = project.fullname

+     if args.all_:

+         title = 'all'

+         project = -1

+ 

+     helper = pagure.lib.git_auth.get_git_auth_helper(

+         APP.config['GITOLITE_BACKEND'])

+     _log.debug('Got helper: %s', helper)

+ 

+     group_obj = None

+     if args.group:

+         group_obj = pagure.lib.search_groups(SESSION, group_name=args.group)

+     _log.debug(

+         'Calling helper: %s with arg: project=%s, group=%s',

+         helper, project, group_obj)

+ 

      print(

-         'Do you want to re-generate the gitolite.conf file then '

-         'calling: %s' % cmd)

+         'Do you want to re-generate the gitolite.conf file for group: %s '

+         'and project: %s?' % (group_obj, title))

      if _ask_confirmation():

-         pagure.lib.git._generate_gitolite_acls()

+         helper.generate_acls(project=project, group=group_obj)

+         pagure.lib.tasks.gc_clean()

          print('Gitolite ACLs updated')

  

  

file modified
+13
@@ -65,6 +65,15 @@ 

  # Enables / Disables private projects

  PRIVATE_PROJECTS = False

  

+ # Enable / Disable deleting branches in the UI

+ ALLOW_DELETE_BRANCH = True

+ 

+ # Enable / Disable having pagure manage the user's ssh keys

+ LOCAL_SSH_KEY = True

+ 

+ # Enable / Disable deploy keys

+ DEPLOY_KEY = True

+ 

  # Enables / Disables showing all the projects by default on the front page

  SHOW_PROJECTS_INDEX = ['repos', 'myrepos', 'myforks']

  
@@ -255,6 +264,10 @@ 

      'modify_project': 'Modify an existing project'

  }

  

+ # List of ACLs which a regular user is allowed to associate to an API token

+ # from the ACLs above

+ USER_ACLS = ACLS.keys()

+ 

  # From the ACLs above lists which ones are tolerated to be associated with

  # an API token that isn't linked to a particular project.

  CROSS_PROJECT_ACLS = [

file modified
+4 -3
@@ -53,9 +53,10 @@ 

          for folder in [

                  APP.config.get('DOCS_FOLDER'),

                  APP.config.get('REQUESTS_FOLDER')]:

-             repopaths.append(

-                 os.path.join(folder, project.path)

-             )

+             if folder:

+                 repopaths.append(

+                     os.path.join(folder, project.path)

+                 )

  

          hook_files = os.path.join(

              os.path.dirname(os.path.realpath(__file__)), 'files')

@@ -38,7 +38,8 @@ 

          print('namespace:', namespace)

  

      project = pagure.lib._get_project(

-         pagure.SESSION, repo, user=username, namespace=namespace)

+         pagure.SESSION, repo, user=username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

      for line in sys.stdin:

          if pagure.APP.config.get('HOOK_DEBUG', False):

@@ -52,7 +52,9 @@ 

      username = pagure.lib.git.get_username(abspath)

      namespace = pagure.lib.git.get_repo_namespace(abspath)

      project = pagure.lib._get_project(

-         pagure.SESSION, project_name, username, namespace=namespace)

+         pagure.SESSION, project_name, username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

+ 

      if not project:

          project = project_name

  

@@ -32,7 +32,9 @@ 

          print 'namspaces:', namespace

  

      repo = pagure.lib._get_project(

-         pagure.SESSION, reponame, user=username, namespace=namespace)

+         pagure.SESSION, reponame, user=username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

+ 

      if not repo:

          print 'Unknown repo %s of username: %s in namespace %s' % (

              reponame, username, namespace)

@@ -37,7 +37,8 @@ 

          print('namespace:', namespace)

  

      project = pagure.lib._get_project(

-         pagure.SESSION, repo, user=username, namespace=namespace)

+         pagure.SESSION, repo, user=username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

      for line in sys.stdin:

          if pagure.APP.config.get('HOOK_DEBUG', False):

file modified
+8 -6
@@ -116,9 +116,10 @@ 

          for folder in [

                  APP.config.get('DOCS_FOLDER'),

                  APP.config.get('REQUESTS_FOLDER')]:

-             repopaths.append(

-                 os.path.join(folder, project.path)

-             )

+             if folder:

+                 repopaths.append(

+                     os.path.join(folder, project.path)

+                 )

  

          cls.base_install(repopaths, dbobj, 'pagure', 'pagure_hook.py')

  
@@ -134,8 +135,9 @@ 

          for folder in [

                  APP.config.get('DOCS_FOLDER'),

                  APP.config.get('REQUESTS_FOLDER')]:

-             repopaths.append(

-                 os.path.join(folder, project.path)

-             )

+             if folder:

+                 repopaths.append(

+                     os.path.join(folder, project.path)

+                 )

  

          cls.base_remove(repopaths, 'pagure')

file modified
+26 -9
@@ -2006,20 +2006,32 @@ 

          return query.all()

  

  

- def _get_project(session, name, user=None, namespace=None):

+ def _get_project(session, name, user=None, namespace=None, case=False):

      '''Get a project from the database

      '''

      query = session.query(

          model.Project

-     ).filter(

-         func.lower(model.Project.name) == name.lower()

      )

  

-     if namespace:

+     if not case:

          query = query.filter(

-             func.lower(model.Project.namespace) == namespace.lower()

+             func.lower(model.Project.name) == name.lower()

          )

      else:

+         query = query.filter(

+             model.Project.name == name

+         )

+ 

+     if namespace:

+         if not case:

+             query = query.filter(

+                 func.lower(model.Project.namespace) == namespace.lower()

+             )

+         else:

+             query = query.filter(

+                 model.Project.namespace == namespace

+             )

+     else:

          query = query.filter(model.Project.namespace == namespace)

  

      if user is not None:
@@ -3074,8 +3086,11 @@ 

          return query.all()

  

  

- def add_user_to_group(session, username, group, user, is_admin):

+ def add_user_to_group(session, username, group, user, is_admin,

+                       from_external=False):

      ''' Add the specified user to the given group.

+ 

+     from_external indicates whether this is a remotely synced group.

      '''

      new_user = search_user(session, username=username)

      if not new_user:
@@ -3088,7 +3103,8 @@ 

          raise pagure.exceptions.PagureException(

              'No user `%s` found' % action_user)

  

-     if group.group_name not in user.groups and not is_admin\

+     if not from_external and \

+             group.group_name not in user.groups and not is_admin\

              and user.username != group.creator.username:

          raise pagure.exceptions.PagureException(

              'You are not allowed to add user to this group')
@@ -3154,7 +3170,7 @@ 

  

  

  def delete_user_of_group(session, username, groupname, user, is_admin,

-                          force=False):

+                          force=False, from_external=False):

      ''' Removes the specified user from the given group.

      '''

      group_obj = search_groups(session, group_name=groupname)
@@ -3174,7 +3190,8 @@ 

          raise pagure.exceptions.PagureException(

              'Could not find user %s' % action_user)

  

-     if group_obj.group_name not in user.groups and not is_admin:

+     if not from_external and \

+             group_obj.group_name not in user.groups and not is_admin:

          raise pagure.exceptions.PagureException(

              'You are not allowed to remove user from this group')

  

file modified
+17 -5
@@ -365,8 +365,10 @@ 

      project_user = None

      if jsondata.get('parent'):

          project_user = user.username

+ 

      project = pagure.lib._get_project(

-         session, name, user=project_user, namespace=namespace)

+         session, name, user=project_user, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

      if not project:

          parent = None
@@ -406,7 +408,8 @@ 

  

          session.commit()

          project = pagure.lib._get_project(

-             session, name, user=user.username, namespace=namespace)

+             session, name, user=user.username, namespace=namespace,

+             case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

          tags = jsondata.get('tags', None)

          if tags:
@@ -484,7 +487,8 @@ 

      """

  

      repo = pagure.lib._get_project(

-         session, reponame, user=username, namespace=namespace)

+         session, reponame, user=username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

  

      if not repo:

          raise pagure.exceptions.PagureException(
@@ -663,7 +667,9 @@ 

      """

  

      repo = pagure.lib._get_project(

-         session, reponame, user=username, namespace=namespace)

+         session, reponame, user=username, namespace=namespace,

+         case=pagure.APP.config.get('CASE_SENSITIVE', False))

+ 

      if not repo:

          raise pagure.exceptions.PagureException(

              'Unknown repo %s of username: %s in namespace: %s' % (
@@ -1474,6 +1480,12 @@ 

          request.commit_stop = diff_commits[0].oid.hex

          session.add(request)

          session.commit()

+         tasks.sync_pull_ref.delay(

+             request.project.name,

+             request.project.namespace,

+             request.project.user.username if request.project.is_fork else None,

+             request.id

+         )

  

          tasks.sync_pull_ref.delay(

              request.project.name,
@@ -1517,7 +1529,7 @@ 

          _log.info(

              '  Pushing refs/heads/%s to refs/pull/%s',

              request.branch_from, request.id)

-         refname = 'refs/heads/%s:refs/pull/%s/head' % (

+         refname = '+refs/heads/%s:refs/pull/%s/head' % (

              request.branch_from, request.id)

          PagureRepo.push(remote, refname)

      finally:

file modified
+3 -1
@@ -283,7 +283,9 @@ 

          """

          _log.info('Reading in the current configuration: %s', configfile)

          with open(configfile) as stream:

-             current_config = [line for line in stream]

+             current_config = [line.rstrip() for line in stream]

+         if current_config and current_config[-1] == '# end of body':

+             current_config = current_config[:-1]

  

          if preconfig:

              idx = None

file modified
-1
@@ -384,7 +384,6 @@ 

          primaryjoin="projects.c.id==user_projects.c.project_id",

          secondaryjoin="users.c.id==user_projects.c.user_id",

          backref='co_projects',

-         viewonly=True

      )

  

      admins = relation(

file modified
+44 -22
@@ -86,7 +86,9 @@ 

      project = None

      if name and name != -1:

          project = pagure.lib._get_project(

-             session, namespace=namespace, name=name, user=user)

+             session, namespace=namespace, name=name, user=user,

+             case=APP.config.get('CASE_SENSITIVE', False))

+ 

      elif name == -1:

          project = name

      helper = pagure.lib.git_auth.get_git_auth_helper(
@@ -125,8 +127,10 @@ 

      """

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace,

-                                       name=name)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          userobj = pagure.lib.search_user(session, username=username)

          gitrepo = os.path.join(APP.config['GIT_FOLDER'], project.path)
@@ -231,8 +235,10 @@ 

  def update_git(name, namespace, user, ticketuid=None, requestuid=None):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace, name=name,

-                                       user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          if ticketuid is not None:

              obj = pagure.lib.get_issue_by_uid(session, ticketuid)
@@ -257,8 +263,10 @@ 

  def clean_git(name, namespace, user, ticketuid):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace, name=name,

-                                       user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          obj = pagure.lib.get_issue_by_uid(session, ticketuid)

          folder = APP.config['TICKETS_FOLDER']
@@ -278,8 +286,9 @@ 

      session = pagure.lib.create_session()

  

      userobj = pagure.lib.search_user(session, username=username)

-     project = pagure.lib._get_project(session, namespace=namespace, name=name,

-                                       user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

  

      with project.lock('WORKER'):

          pagure.lib.git._update_file_in_git(project, branch, branchto, filename,
@@ -294,8 +303,10 @@ 

  def delete_branch(name, namespace, user, branchname):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace, name=name,

-                                       user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          repo_obj = pygit2.Repository(pagure.get_repo_path(project))

  
@@ -332,9 +343,12 @@ 

      session = pagure.lib.create_session()

  

      repo_from = pagure.lib._get_project(

-         session, namespace=namespace, name=name, user=user_owner)

+         session, namespace=namespace, name=name, user=user_owner,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      repo_to = pagure.lib._get_project(

-         session, namespace=namespace, name=name, user=user_forker)

+         session, namespace=namespace, name=name, user=user_forker,

+         case=APP.config.get('CASE_SENSITIVE', False))

  

      with repo_to.lock('WORKER'):

          reponame = os.path.join(APP.config['GIT_FOLDER'], repo_from.path)
@@ -436,8 +450,9 @@ 

  def refresh_pr_cache(name, namespace, user):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace,

-                                       name=name, user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

  

      pagure.lib.reset_status_pull_request(session, project)

  
@@ -449,8 +464,10 @@ 

  def merge_pull_request(name, namespace, user, requestid, user_merger):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace,

-                                       name=name, user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          request = pagure.lib.search_pull_requests(

              session, project_id=project.id, requestid=requestid)
@@ -470,8 +487,10 @@ 

  def add_file_to_git(name, namespace, user, user_attacher, issueuid, filename):

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace,

-                                       name=name, user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          issue = pagure.lib.get_issue_by_uid(session, issueuid)

          user_attacher = pagure.lib.search_user(session, username=user_attacher)
@@ -502,8 +521,10 @@ 

  

      session = pagure.lib.create_session()

  

-     project = pagure.lib._get_project(session, namespace=namespace,

-                                       name=name, user=user)

+     project = pagure.lib._get_project(

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

+ 

      with project.lock('WORKER'):

          time.sleep(10)

  
@@ -521,7 +542,8 @@ 

      session = pagure.lib.create_session()

  

      project = pagure.lib._get_project(

-         session, namespace=namespace, name=name, user=user)

+         session, namespace=namespace, name=name, user=user,

+         case=APP.config.get('CASE_SENSITIVE', False))

  

      with project.lock('WORKER'):

          request = pagure.lib.search_pull_requests(

file modified
+8 -2
@@ -376,12 +376,18 @@ 

          if obj.private:

              title = 'Private issue'

          else:

-             title = obj.title

+             if obj.status:

+                 title = '[%s] %s' % (obj.status, obj.title)

+             else:

+                 title = obj.title

      else:

          url = flask.url_for(

              'request_pull', username=user, namespace=namespace, repo=repo,

              requestid=obj.id)

-         title = obj.title

+         if obj.status:

+             title = '[%s] %s' % (obj.status, obj.title)

+         else:

+             title = obj.title

  

      element = markdown.util.etree.Element("a")

      element.set('href', url)

@@ -145,6 +145,7 @@ 

                      repo=repo.name,

                      username=username,

                      namespace=repo.namespace,

+                     identifier=branchname,

                      filename=filename) | unicode }}" title="View git blame">Blame</a>

  

                  <a class="btn btn-secondary btn-sm" href="{{ url_for(

file modified
+5 -1
@@ -568,7 +568,11 @@ 

        }

        $( "#comment" ).val(_output.join("\n"));

      }

-   );

+   ).click(function(){

+ 	 $('html, body').animate({

+         scrollTop: $("#comment").offset().top

+     }, 2000);

+ });

  };

  

  $(document).ready(function() {

file modified
+2 -2
@@ -354,8 +354,8 @@ 

  <script type="text/javascript"

    src="{{ url_for('static', filename='vendor/stupidtable/stupidtable.min.js') }}">

  </script>

- <script>

- $.ready(function() {

+ <script type="text/javascript">

+ $(document).ready(function() {

    $("#pagure-issues-list").stupidtable();

  });

  </script>

file modified
+1 -1
@@ -2,7 +2,7 @@ 

  <html lang='en'>

  <head>

      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

-     <title>{% block title %}{% endblock %} - Pagure</title>

+     <title>{% block title %}{% endblock %} - {{ config.get('HTML_TITLE', 'Pagure') }}</title>

      <link rel="shortcut icon" type="image/vnd.microsoft.icon"

          href="{{ url_for('static', filename='favicon.ico')}}"/>

      <link href="{{ config['BOOTSTRAP_URLS_CSS'] }}"

@@ -129,7 +129,7 @@ 

  

                  </div>

                  <div class="branch_del col-md-4">

-                   {% if g.repo_committer and branch != head %}

+                   {% if g.repo_committer and branch != head and config.get('ALLOW_DELETE_BRANCH', True) %}

                    <form id="delete_branch_form-{{ branch | replace('/', '__') }}" action="{{

                      url_for('.delete_branch',

                              repo=repo.name,

@@ -499,7 +499,7 @@ 

      </div>

      {% endif %}

  

- 

+     {% if config.get('DEPLOY_KEY', True) %}

      <div class="col-md-8 col-md-offset-2">

        <div class="card">

          <div class="card-header">
@@ -546,6 +546,7 @@ 

            </ul>

        </div>

      </div>

+     {% endif %}

  

  

      {% if plugins %}
@@ -596,7 +597,7 @@ 

            <p>

              Below are the priorities you may assign to a ticket, allowing you

              to sort them with it. The Weight determines the ordering. Higher

-             priority should correspond to higher weight.

+             priority should correspond to lower weight.

              <span class="italic">

                To remove an entry, simply clean the Weight and Title

              </span>

@@ -42,7 +42,7 @@ 

          <tfoot>

          </tfoot>

          <tbody>

-         {% for issue in issues %}

+         {% for issue in issues if issue.project.settings.get('issue_tracker', True) %}

            <tr class="issue-status issue-status-{{issue.status|lower}} loop-index-{{outer_loop.index}}"

                {%- if issue.status|lower != "open" %} style="display:none;"{% endif %}>

                  <td class="nowrap"><span class="label label-default">#{{ issue.id }}</span></td>

@@ -98,6 +98,7 @@ 

        </div>

      </div>

  

+     {% if config.get('LOCAL_SSH_KEY', True) %}

      <div class="card m-b-3">

        <div class="card-header">

            <strong>Authentication</strong>
@@ -113,7 +114,7 @@ 

          </form>

        </div>

      </div>

- 

+     {% endif %}

  

    <div class="card m-b-3">

      <div class="card-header">

@@ -17,7 +17,7 @@ 

              <a href="{{ url_for('wait_task', taskid=task.id) }}">Here</a>

            </p>

            <p>

-               You task is currently <span id="status">{{ task.status }}</span>

+               Your task is currently <span id="status">{{ task.status }}</span>

            </p>

            <p id="slow" class="hidden">

              This is taking longer than usual... Sorry for that

file modified
+2 -1
@@ -289,6 +289,7 @@ 

          flask.flash('Only one result found, redirecting you to it')

          return flask.redirect(flask.url_for(

              'view_repo', repo=projects[0].name,

+             namespace=projects[0].namespace,

              username=projects[0].user.username if projects[0].is_fork else None

          ))

  
@@ -564,7 +565,7 @@ 

      user = _get_user(username=flask.g.fas_user.username)

  

      form = pagure.forms.UserSettingsForm()

-     if form.validate_on_submit():

+     if form.validate_on_submit() and APP.config.get('LOCAL_SSH_KEY', True):

          ssh_key = form.ssh_key.data

  

          try:

file modified
+4 -2
@@ -881,7 +881,8 @@ 

  

      if pagure.lib._get_project(

              SESSION, repo.name, user=flask.g.fas_user.username,

-             namespace=namespace):

+             namespace=namespace,

+             case=APP.config.get('CASE_SENSITIVE', False)):

          return flask.redirect(flask.url_for(

              'view_repo', repo=repo.name, username=flask.g.fas_user.username,

              namespace=namespace))
@@ -1256,7 +1257,8 @@ 

          flask.abort(400)

  

      if pagure.lib._get_project(

-             SESSION, repo.name, user=flask.g.fas_user.username):

+             SESSION, repo.name, user=flask.g.fas_user.username,

+             case=APP.config.get('CASE_SENSITIVE', False)):

          flask.flash('You had already forked this project')

          return flask.redirect(flask.url_for(

              'edit_file',

file modified
+19 -3
@@ -679,7 +679,12 @@ 

      if repo_obj.is_empty or repo_obj.head_is_unborn:

          flask.abort(404, 'Empty repo cannot have a file')

  

-     commit = repo_obj[repo_obj.head.target]

+     if branchname in repo_obj.listall_branches():

+         branch = repo_obj.lookup_branch(branchname)

+         commit = branch.get_object()

+     else:

+         commit = repo_obj[repo_obj.head.target]

+ 

      content = __get_file_in_tree(

          repo_obj, commit.tree, filename.split('/'), bail_on_tree=True)

      if not content:
@@ -703,7 +708,7 @@ 

          lexer,

          HtmlFormatter(noclasses=True, style="tango")

      )

-     blame = repo_obj.blame(filename)

+     blame = repo_obj.blame(filename, newest_commit=commit.oid.hex)

  

      return flask.render_template(

          'blame.html',
@@ -1490,6 +1495,9 @@ 

      """ Remove the specified deploy key from the project.

      """

  

+     if not APP.config.get('DEPLOY_KEY', True):

+         flask.abort(404, 'This pagure instance disabled deploy keys')

+ 

      if admin_session_timedout():

          flask.flash('Action canceled, try it again', 'error')

          url = flask.url_for(
@@ -1614,6 +1622,9 @@ 

      """ Add the specified deploy key to the project.

      """

  

+     if not APP.config.get('DEPLOY_KEY', True):

+         flask.abort(404, 'This pagure instance disabled deploy keys')

+ 

      if admin_session_timedout():

          if flask.request.method == 'POST':

              flask.flash('Action canceled, try it again', 'error')
@@ -1984,7 +1995,8 @@ 

              403,

              'You are not allowed to change the settings for this project')

  

-     acls = pagure.lib.get_acls(SESSION)

+     acls = pagure.lib.get_acls(

+         SESSION, restrict=APP.config.get('USER_ACLS'))

      form = pagure.forms.NewTokenForm(acls=acls)

  

      if form.validate_on_submit():
@@ -2172,6 +2184,10 @@ 

  def delete_branch(repo, branchname, username=None, namespace=None):

      """ Delete the branch of a project.

      """

+     if not APP.config.get('ALLOW_DELETE_BRANCH', True):

+         flask.abort(

+             404, 'This pagure instance does not allow branch deletion')

+ 

      repo_obj = flask.g.repo_obj

  

      if not flask.g.repo_committer:

file modified
+156 -2
@@ -97,10 +97,16 @@ 

          cmd = ['python', PAGURE_ADMIN, 'refresh-gitolite', '--help']

          self.assertEqual(

              _get_ouput(cmd)[0],

-             '''usage: admin.py refresh-gitolite [-h]

+             '''usage: admin.py refresh-gitolite [-h] [--user USER] [--project PROJECT]

+                                  [--group GROUP] [--all]

  

  optional arguments:

-   -h, --help  show this help message and exit

+   -h, --help         show this help message and exit

+   --user USER        User of the project (to use only on forks)

+   --project PROJECT  Project to update (as namespace/project if there is a

+                      namespace)

+   --group GROUP      Group to refresh

+   --all              Refresh all the projects

  ''')

  

      def test_parser_refresh_ssh_help(self):
@@ -253,6 +259,154 @@ 

          self.assertEqual(_get_ouput(cmd)[0], 'No admin tokens found\n')

  

  

+ class PagureAdminAdminRefreshGitolitetests(tests.Modeltests):

+     """ Tests for pagure-admin refresh-gitolite """

+ 

+     def setUp(self):

+         """ Set up the environnment, ran before every tests. """

+         super(PagureAdminAdminRefreshGitolitetests, self).setUp()

+ 

+         self.configfile = os.path.join(self.path, 'config')

+         self.dbpath = "sqlite:///%s/pagure_dev.sqlite" % self.path

+         with open(self.configfile, 'w') as stream:

+             stream.write('DB_URL="%s"\n' % self.dbpath)

+ 

+         os.environ['PAGURE_CONFIG'] = self.configfile

+ 

+         createdb = os.path.abspath(

+             os.path.join(tests.HERE, '..', 'createdb.py'))

+         cmd = ['python', createdb]

+         _get_ouput(cmd)

+ 

+         self.session = pagure.lib.model.create_tables(

+             self.dbpath, acls=pagure.APP.config.get('ACLS', {}))

+ 

+         # Create the user pingou

+         item = pagure.lib.model.User(

+             user='pingou',

+             fullname='PY C',

+             password='foo',

+             default_email='bar@pingou.com',

+         )

+         self.session.add(item)

+         item = pagure.lib.model.UserEmail(

+             user_id=1,

+             email='bar@pingou.com')

+         self.session.add(item)

+         self.session.commit()

+ 

+         # Create a couple of projects

+         tests.create_projects(self.session)

+ 

+         # Add a group

+         msg = pagure.lib.add_group(

+             self.session,

+             group_name='foo',

+             display_name='foo group',

+             description=None,

+             group_type='bar',

+             user='pingou',

+             is_admin=False,

+             blacklist=[],

+         )

+         self.session.commit()

+         self.assertEqual(msg, 'User `pingou` added to the group `foo`.')

+ 

+         # Make the imported pagure use the correct db session

+         pagure.cli.admin.SESSION = self.session

+ 

+     def tearDown(self):

+         """ Tear down the environnment after running the tests. """

+         super(PagureAdminAdminRefreshGitolitetests, self).tearDown()

+         del(os.environ['PAGURE_CONFIG'])

+ 

+     @patch('pagure.cli.admin._ask_confirmation')

+     @patch('pagure.lib.git_auth.get_git_auth_helper')

+     def test_do_refresh_gitolite_no_args(self, get_helper, conf):

+         """ Test the do_generate_acl function with no special args. """

+         conf.return_value = True

+         helper = MagicMock()

+         get_helper.return_value = helper

+ 

+         args = munch.Munch(

+             {'group': None, 'project': None, 'all_': False, 'user': None})

+         pagure.cli.admin.do_generate_acl(args)

+ 

+         get_helper.assert_called_with('gitolite3')

+         args = helper.generate_acls.call_args

+         self.assertIsNone(args[1].get('group'))

+         self.assertIsNone(args[1].get('project'))

+ 

+     @patch('pagure.cli.admin._ask_confirmation')

+     @patch('pagure.lib.git_auth.get_git_auth_helper')

+     def test_do_refresh_gitolite_all_project(self, get_helper, conf):

+         """ Test the do_generate_acl function for all projects. """

+         conf.return_value = True

+         helper = MagicMock()

+         get_helper.return_value = helper

+ 

+         args = munch.Munch(

+             {'group': None, 'project': None, 'all_': True, 'user': None})

+         pagure.cli.admin.do_generate_acl(args)

+ 

+         get_helper.assert_called_with('gitolite3')

+         args = helper.generate_acls.call_args

+         self.assertIsNone(args[1].get('group'))

+         self.assertEqual(args[1].get('project'), -1)

+ 

+     @patch('pagure.cli.admin._ask_confirmation')

+     @patch('pagure.lib.git_auth.get_git_auth_helper')

+     def test_do_refresh_gitolite_one_project(self, get_helper, conf):

+         """ Test the do_generate_acl function for a certain project. """

+         conf.return_value = True

+         helper = MagicMock()

+         get_helper.return_value = helper

+ 

+         args = munch.Munch(

+             {'group': None, 'project': 'test', 'all_': False, 'user': None})

+         pagure.cli.admin.do_generate_acl(args)

+ 

+         get_helper.assert_called_with('gitolite3')

+         args = helper.generate_acls.call_args

+         self.assertIsNone(args[1].get('group'))

+         self.assertEqual(args[1].get('project').fullname, 'test')

+ 

+     @patch('pagure.cli.admin._ask_confirmation')

+     @patch('pagure.lib.git_auth.get_git_auth_helper')

+     def test_do_refresh_gitolite_one_project_and_all(self, get_helper, conf):

+         """ Test the do_generate_acl function for a certain project and all.

+         """

+         conf.return_value = True

+         helper = MagicMock()

+         get_helper.return_value = helper

+ 

+         args = munch.Munch(

+             {'group': None, 'project': 'test', 'all_': True, 'user': None})

+         pagure.cli.admin.do_generate_acl(args)

+ 

+         get_helper.assert_called_with('gitolite3')

+         args = helper.generate_acls.call_args

+         self.assertIsNone(args[1].get('group'))

+         self.assertEqual(args[1].get('project'), -1)

+ 

+     @patch('pagure.cli.admin._ask_confirmation')

+     @patch('pagure.lib.git_auth.get_git_auth_helper')

+     def test_do_refresh_gitolite_one_group(self, get_helper, conf):

+         """ Test the do_generate_acl function for a certain group. """

+         conf.return_value = True

+         helper = MagicMock()

+         get_helper.return_value = helper

+ 

+         args = munch.Munch(

+             {'group': 'foo', 'project': None, 'all_': False, 'user': None})

+         pagure.cli.admin.do_generate_acl(args)

+ 

+         get_helper.assert_called_with('gitolite3')

+         args = helper.generate_acls.call_args

+         self.assertEqual(args[1].get('group').group_name, 'foo')

+         self.assertIsNone(args[1].get('project'))

+ 

+ 

  class PagureAdminAdminTokentests(tests.Modeltests):

      """ Tests for pagure-admin admin-token """

  

@@ -32,6 +32,8 @@ 

  class PagureFlaskApiUSertests(tests.Modeltests):

      """ Tests for the flask API of pagure for issue """

  

+     maxDiff = None

+ 

      def setUp(self):

          """ Set up the environnment, ran before every tests. """

          super(PagureFlaskApiUSertests, self).setUp()
@@ -368,7 +370,7 @@ 

                "date": date,

                "date_created": "1477558752",

                "type": "pull-request",

-               "description_mk": "<p>pingou created PR <a href=\"/test/pull-request/1\" title=\"test pull-request\">test#1</a></p>",

+               "description_mk": "<p>pingou created PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",

                "id": 1,

                "ref_id": "1",

                "type": "created",
@@ -381,7 +383,7 @@ 

                "date": date,

                "date_created": "1477558752",

                "type": "pull-request",

-               "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"test pull-request\">test#1</a></p>",

+               "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",

                "id": 2,

                "ref_id": "1",

                "type": "commented",
@@ -394,7 +396,7 @@ 

                "date": date,

                "date_created": "1477558752",

                "type": "pull-request",

-               "description_mk": "<p>pingou closed PR <a href=\"/test/pull-request/1\" title=\"test pull-request\">test#1</a></p>",

+               "description_mk": "<p>pingou closed PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",

                "id": 3,

                "ref_id": "1",

                "type": "closed",
@@ -407,7 +409,7 @@ 

                "date": date,

                "date_created": "1477558752",

                "type": "pull-request",

-               "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"test pull-request\">test#1</a></p>",

+               "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",

                "id": 4,

                "ref_id": "1",

                "type": "commented",

@@ -26,6 +26,7 @@ 

  import pagure

  import pagure.lib

  import tests

+ from pagure.lib.repo import PagureRepo

  

  

  class PagureFlaskInternaltests(tests.Modeltests):
@@ -437,10 +438,13 @@ 

  

          # Create a git repo to play with

  

-         gitrepo = os.path.join(self.path, 'repos', 'test.git')

-         self.assertFalse(os.path.exists(gitrepo))

-         os.makedirs(gitrepo)

-         repo = pygit2.init_repository(gitrepo)

+         origgitrepo = os.path.join(self.path, 'repos', 'test.git')

+         self.assertFalse(os.path.exists(origgitrepo))

+         os.makedirs(origgitrepo)

+         orig_repo = pygit2.init_repository(origgitrepo, bare=True)

+         os.makedirs(os.path.join(self.path, 'repos_tmp'))

+         gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')

+         repo = pygit2.clone_repository(origgitrepo, gitrepo)

  

          # Create a file in that git repo

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -466,6 +470,9 @@ 

          )

  

          first_commit = repo.revparse_single('HEAD')

+         refname = 'refs/heads/master:refs/heads/master'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Edit the sources file again

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -492,6 +499,9 @@ 

          )

  

          second_commit = repo.revparse_single('HEAD')

+         refname = 'refs/heads/feature:refs/heads/feature'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Create a PR for these changes

          tests.create_projects(self.session)
@@ -681,10 +691,13 @@ 

  

          # Create a git repo to play with

  

-         gitrepo = os.path.join(self.path, 'repos', 'test.git')

-         self.assertFalse(os.path.exists(gitrepo))

-         os.makedirs(gitrepo)

-         repo = pygit2.init_repository(gitrepo)

+         origgitrepo = os.path.join(self.path, 'repos', 'test.git')

+         self.assertFalse(os.path.exists(origgitrepo))

+         os.makedirs(origgitrepo)

+         orig_repo = pygit2.init_repository(origgitrepo, bare=True)

+         os.makedirs(os.path.join(self.path, 'repos_tmp'))

+         gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')

+         repo = pygit2.clone_repository(origgitrepo, gitrepo)

  

          # Create a file in that git repo

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -710,6 +723,9 @@ 

          )

  

          first_commit = repo.revparse_single('HEAD')

+         refname = 'refs/heads/master:refs/heads/master'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Edit the sources file again

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -734,6 +750,9 @@ 

              # list of binary strings representing parents of the new commit

              [first_commit.oid.hex]

          )

+         refname = 'refs/heads/feature:refs/heads/feature'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Create another file in the master branch

          with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
@@ -757,6 +776,9 @@ 

              # list of binary strings representing parents of the new commit

              [first_commit.oid.hex]

          )

+         refname = 'refs/heads/master:refs/heads/master'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Create a PR for these changes

          tests.create_projects(self.session)
@@ -821,11 +843,13 @@ 

          send_email.return_value = True

  

          # Create a git repo to play with

- 

-         gitrepo = os.path.join(self.path, 'repos', 'test.git')

-         self.assertFalse(os.path.exists(gitrepo))

-         os.makedirs(gitrepo)

-         repo = pygit2.init_repository(gitrepo)

+         origgitrepo = os.path.join(self.path, 'repos', 'test.git')

+         self.assertFalse(os.path.exists(origgitrepo))

+         os.makedirs(origgitrepo)

+         orig_repo = pygit2.init_repository(origgitrepo, bare=True)

+         os.makedirs(os.path.join(self.path, 'repos_tmp'))

+         gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')

+         repo = pygit2.clone_repository(origgitrepo, gitrepo)

  

          # Create a file in that git repo

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -851,6 +875,9 @@ 

          )

  

          first_commit = repo.revparse_single('HEAD')

+         refname = 'refs/heads/master:refs/heads/master'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Edit the sources file again

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -875,6 +902,9 @@ 

              # list of binary strings representing parents of the new commit

              [first_commit.oid.hex]

          )

+         refname = 'refs/heads/feature:refs/heads/feature'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Create another file in the master branch

          with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
@@ -898,6 +928,9 @@ 

              # list of binary strings representing parents of the new commit

              [first_commit.oid.hex]

          )

+         refname = 'refs/heads/master:refs/heads/master'

+         ori_remote = repo.remotes[0]

+         PagureRepo.push(ori_remote, refname)

  

          # Create a PR for these changes

          tests.create_projects(self.session)

@@ -43,11 +43,22 @@ 

          pagure.ui.filters.SESSION = self.session

          pagure.ui.repo.SESSION = self.session

  

+     @patch.dict('pagure.APP.config', {'HTML_TITLE': 'Pagure HTML title set'})

+     def test_index_html_title(self):

+         """ Test the index endpoint with a set html title. """

+ 

+         output = self.app.get('/')

+         self.assertEqual(output.status_code, 200)

+         self.assertIn(

+             '<title>Home - Pagure HTML title set</title>',

+             output.data)

+ 

      def test_index(self):

          """ Test the index endpoint. """

  

          output = self.app.get('/')

          self.assertEqual(output.status_code, 200)

+         self.assertIn('<title>Home - Pagure</title>', output.data)

          self.assertIn(

              '<h2 class="m-b-1">All Projects '

              '<span class="label label-default">0</span></h2>', output.data)
@@ -514,6 +525,74 @@ 

              output = self.app.get('/settings/')

              self.assertEqual(output.status_code, 302)

  

+     @patch.dict('pagure.APP.config', {'LOCAL_SSH_KEY': False})

+     @patch('pagure.ui.app.admin_session_timedout')

+     def test_user_settings_no_local_ssh_key_ui(self, ast):

+         """ Test the ssh key field doesn't show when pagure is not managing

+         the ssh keys. """

+         ast.return_value = False

+         self.test_new_project()

+ 

+         user = tests.FakeUser(username = 'foo')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.get('/settings/')

+             self.assertEqual(output.status_code, 200)

+             self.assertIn(

+                 '<div class="card-header">\n          Basic Information\n'

+                 '      </div>', output.data)

+             self.assertNotIn(

+                 '<textarea class="form-control" id="ssh_key" name="ssh_key">'

+                 '</textarea>', output.data)

+ 

+     @patch.dict('pagure.APP.config', {'LOCAL_SSH_KEY': False})

+     @patch('pagure.ui.app.admin_session_timedout')

+     def test_user_settings_no_local_ssh_key(self, ast):

+         """ Test the user_settings endpoint when pagure is not managing the

+         ssh keys. """

+         ast.return_value = False

+         self.test_new_project()

+ 

+         user = tests.FakeUser(username = 'foo')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.get('/settings/')

+             self.assertEqual(output.status_code, 200)

+             self.assertIn(

+                 '<div class="card-header">\n          Basic Information\n'

+                 '      </div>', output.data)

+             self.assertNotIn(

+                 '<textarea class="form-control" id="ssh_key" name="ssh_key">'

+                 '</textarea>', output.data)

+ 

+             # Before

+             user = pagure.lib.get_user(self.session, 'foo')

+             self.assertIsNone(user.public_ssh_key)

+ 

+             csrf_token = self.get_csrf(output=output)

+ 

+             data = {

+                 'ssh_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDUkub32fZnNI'

+                            '1zJYs43vhhx3c6IcYo4yzhw1gQ37BLhrrNeS6x8l5PKX4J8ZP5'

+                            '1XhViPaLbeOpl94Vm5VSCbLy0xtY9KwLhMkbKj7g6vvfxLm2sT'

+                            'Osb15j4jzIkUYYgIE7cHhZMCLWR6UA1c1HEzo6mewMDsvpQ9wk'

+                            'cDnAuXjK3Q==',

+                 'csrf_token': csrf_token

+             }

+ 

+             output = self.app.post(

+                 '/settings/', data=data, follow_redirects=True)

+             self.assertEqual(output.status_code, 200)

+             self.assertNotIn('Public ssh key updated', output.data)

+             self.assertIn(

+                 '<div class="card-header">\n          Basic Information\n'

+                 '      </div>', output.data)

+             self.assertNotIn(

+                 '<textarea class="form-control" id="ssh_key" name="ssh_key">'

+                 'ssh-rsa AAAA', output.data)

+ 

+             # After

+             user = pagure.lib.get_user(self.session, 'foo')

+             self.assertIsNone(user.public_ssh_key)

+ 

      def patched_commit_exists(user, namespace, repo, githash):

          ''' Patched version of pagure.pfmarkdown._commit_exists to enforce

          returning true on some given hash without having us actually check
@@ -1212,7 +1291,8 @@ 

          self.assertEqual(output.status_code, 200)

          self.assertIn('Test issue #1', output.data)

          self.assertEqual(

-             output.data.count('<tr class="issue-status issue-status-open"'),

+             output.data.count(

+                 '<tr class="issue-status issue-status-open'),

              1)

  

          # Add an issue in a fork
@@ -1267,7 +1347,54 @@ 

          self.assertIn('Test issue #2', output.data)

          self.assertIn('Test issue #3', output.data)

          self.assertEqual(

-             output.data.count('<tr class="issue-status issue-status-open"'), 3)

+             output.data.count('<tr class="issue-status issue-status-open'),

+             3)

+ 

+     @patch(

+         'pagure.lib.git.update_git', MagicMock(return_value=True))

+     @patch(

+         'pagure.lib.notify.send_email', MagicMock(return_value=True))

+     def test_view_my_issues_disabled(self):

+         """Test the view_user_issues endpoint when the project disabled issue

+         tracking."""

+         # Create the issue

+         tests.create_projects(self.session)

+         repo = pagure.lib._get_project(self.session, 'test')

+         msg = pagure.lib.new_issue(

+             session=self.session,

+             repo=repo,

+             title='Test issue #1',

+             content='We should work on this for the second time',

+             user='pingou',

+             status='Open',

+             ticketfolder=None

+         )

+         self.session.commit()

+         self.assertEqual(msg.title, 'Test issue #1')

+ 

+         # Before

+         output = self.app.get('/user/pingou/issues')

+         self.assertEqual(output.status_code, 200)

+         self.assertIn('Test issue #1', output.data)

+         self.assertEqual(

+             output.data.count('<tr class="issue-status issue-status-open'),

+             1)

+ 

+         # Disable issue tracking

+         repo = pagure.lib._get_project(self.session, 'test')

+         settings = repo.settings

+         settings['issue_tracker'] = False

+         repo.settings = settings

+         self.session.add(repo)

+         self.session.commit()

+ 

+         # After

+         output = self.app.get('/user/pingou/issues')

+         self.assertEqual(output.status_code, 200)

+         self.assertNotIn('Test issue #1', output.data)

+         self.assertEqual(

+             output.data.count('<tr class="issue-status issue-status-open'),

+             0)

  

      def test_view_my_issues_tickets_turned_off(self):

          """Test the view_user_issues endpoint when the user exists and

@@ -42,12 +42,12 @@ 

          pagure.ui.repo.SESSION = self.session

          pagure.ui.filters.SESSION = self.session

  

- 

-     def test_plugin_fedmsg(self):

-         """ Test the fedmsg plugin on/off endpoint. """

- 

          tests.create_projects(self.session)

          tests.create_projects_git(os.path.join(self.path, 'repos'))

+         tests.create_projects_git(os.path.join(self.path, 'docs'))

+ 

+     def test_plugin_fedmsg_defaul_page(self):

+         """ Test the fedmsg plugin endpoint's default page. """

  

          user = tests.FakeUser(username='pingou')

          with tests.user_set(pagure.APP, user):
@@ -61,8 +61,7 @@ 

                  '<input id="active" name="active" type="checkbox" value="y">'

                  in output.data)

  

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+             csrf_token = self.get_csrf(output=output)

  

              data = {}

  
@@ -79,8 +78,20 @@ 

              self.assertFalse(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.fedmsg')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_fedmsg_no_data(self):

+         """ Test the setting up the fedmsg plugin when there are no Docs

+         folder.

+         """

  

-             data['csrf_token'] = csrf_token

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

+ 

+             data = {'csrf_token': csrf_token}

  

              # With the git repo

              output = self.app.post(
@@ -104,6 +115,18 @@ 

              self.assertFalse(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.fedmsg')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_fedmsg_activate(self):

+         """ Test the setting up the fedmsg plugin when there are no Docs

+         folder.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

  

              # Activate hook

              data = {
@@ -133,6 +156,19 @@ 

              self.assertTrue(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.fedmsg')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_fedmsg_deactivate(self):

+         """ Test the setting up the fedmsg plugin when there are no Docs

+         folder.

+         """

+         self.test_plugin_fedmsg_activate()

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

  

              # De-Activate hook

              data = {'csrf_token': csrf_token}
@@ -158,6 +194,36 @@ 

              self.assertFalse(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.fedmsg')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     @patch.dict('pagure.APP.config', {'DOCS_FOLDER': None})

+     def test_plugin_fedmsg_no_docs(self):

+         """ Test the setting up the fedmsg plugin when there are no Docs

+         folder.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

+ 

+             # Activate hook

+             data = {

+                 'csrf_token': csrf_token,

+                 'active': 'y',

+             }

+ 

+             output = self.app.post(

+                 '/test/settings/Fedmsg', data=data, follow_redirects=True)

+             self.assertEqual(output.status_code, 200)

+ 

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive.fedmsg')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

  

  

  if __name__ == '__main__':

@@ -42,12 +42,12 @@ 

          pagure.ui.repo.SESSION = self.session

          pagure.ui.filters.SESSION = self.session

  

- 

-     def test_plugin_mail(self):

-         """ Test the pagure hook plugin on/off endpoint. """

- 

          tests.create_projects(self.session)

          tests.create_projects_git(os.path.join(self.path, 'repos'))

+         tests.create_projects_git(os.path.join(self.path, 'docs'))

+ 

+     def test_plugin_mail_page(self):

+         """ Test the default page of the pagure hook plugin. """

  

          user = tests.FakeUser(username='pingou')

          with tests.user_set(pagure.APP, user):
@@ -61,8 +61,11 @@ 

                  '<input id="active" name="active" type="checkbox" value="y">'

                  in output.data)

  

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+     def test_plugin_mail_no_data(self):

+         """ Test the pagure hook plugin endpoint when no data is sent. """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

  

              data = {}

  
@@ -76,7 +79,23 @@ 

                  '<input id="active" name="active" type="checkbox" value="y">'

                  in output.data)

  

-             data['csrf_token'] = csrf_token

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_mail_no_data_csrf(self):

+         """ Test the pagure hook plugin endpoint when no data is sent but

+         the csrf token.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

+ 

+             data = {'csrf_token': csrf_token}

  

              tests.create_projects_git(os.path.join(self.path, 'docs'))

              tests.create_projects_git(os.path.join(self.path, 'requests'))
@@ -105,6 +124,20 @@ 

              self.assertFalse(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.pagure')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_mail_activate_hook(self):

+         """ Test the pagure hook plugin endpoint when activating the hook.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

  

              # Activate hook

              data = {
@@ -135,6 +168,21 @@ 

              self.assertTrue(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.pagure')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     def test_plugin_mail_deactivate_hook(self):

+         """ Test the pagure hook plugin endpoint when activating the hook.

+         """

+         self.test_plugin_mail_activate_hook()

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

  

              # De-Activate hook

              data = {'csrf_token': csrf_token}
@@ -161,6 +209,102 @@ 

              self.assertFalse(os.path.exists(os.path.join(

                  self.path, 'repos', 'test.git', 'hooks',

                  'post-receive.pagure')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     @patch.dict('pagure.APP.config', {'DOCS_FOLDER': None})

+     def test_plugin_mail_activate_hook_no_doc(self):

+         """ Test the pagure hook plugin endpoint when activating the hook

+         on a pagure instance that de-activated the doc repos.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

+ 

+             # Activate hook

+             data = {

+                 'csrf_token': csrf_token,

+                 'active': 'y',

+             }

+ 

+             output = self.app.post(

+                 '/test/settings/Pagure', data=data, follow_redirects=True)

+             self.assertTrue(

+                 '</button>\n                      Hook Pagure activated'

+                 in output.data)

+ 

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive.pagure')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+     @patch.dict('pagure.APP.config', {'DOCS_FOLDER': None})

+     def test_plugin_mail_deactivate_hook_no_doc(self):

+         """ Test the pagure hook plugin endpoint when activating then

+         deactivating the hook on a pagure instance that de-activated the

+         doc repos.

+         """

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             csrf_token = self.get_csrf()

+ 

+             # Activate hook

+             data = {

+                 'csrf_token': csrf_token,

+                 'active': 'y',

+             }

+ 

+             output = self.app.post(

+                 '/test/settings/Pagure', data=data, follow_redirects=True)

+             self.assertEqual(output.status_code, 200)

+             self.assertIn(

+                 '<section class="settings">\n  <h3>Settings for test</h3>',

+                 output.data)

+             self.assertTrue(

+                 '</button>\n                      Hook Pagure activated'

+                 in output.data)

+ 

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive.pagure')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

+ 

+             # Deactivate hook

+             data = {

+                 'csrf_token': csrf_token,

+             }

+ 

+             output = self.app.post(

+                 '/test/settings/Pagure', data=data, follow_redirects=True)

+             self.assertTrue(

+                 '</button>\n                      Hook Pagure deactivated'

+                 in output.data)

+ 

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive.pagure')))

+             self.assertTrue(os.path.exists(os.path.join(

+                 self.path, 'repos', 'test.git', 'hooks',

+                 'post-receive')))

+             self.assertFalse(os.path.exists(os.path.join(

+                 self.path, 'docs', 'test.git', 'hooks',

+                 'post-receive')))

  

  

  if __name__ == '__main__':

@@ -14,6 +14,7 @@ 

  import datetime

  import json

  import unittest

+ import re

  import shutil

  import sys

  import tempfile
@@ -204,6 +205,22 @@ 

              self.assertIn('Deploy key added', output.data)

              self.assertIn('PUSH ACCESS', output.data)

  

+     @patch('pagure.ui.repo.admin_session_timedout')

+     @patch.dict('pagure.APP.config', {'DEPLOY_KEY': False})

+     def test_add_deploykey_disabled(self, ast):

+         """ Test the add_deploykey endpoint when it's disabled in the config.

+         """

+         ast.return_value = False

+         tests.create_projects(self.session)

+         tests.create_projects_git(os.path.join(self.path, 'repos'))

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.get('/test/adddeploykey')

+             self.assertEqual(output.status_code, 404)

+ 

+             output = self.app.post('/test/adddeploykey')

+             self.assertEqual(output.status_code, 404)

  

      @patch('pagure.ui.repo.admin_session_timedout')

      def test_add_user(self, ast):
@@ -513,7 +530,6 @@ 

  

          pagure.APP.config['ENABLE_USER_MNGT'] = True

  

- 

      @patch('pagure.ui.repo.admin_session_timedout')

      def test_remove_deploykey(self, ast):

          """ Test the remove_deploykey endpoint. """
@@ -589,6 +605,20 @@ 

              self.assertIn('<h3>Settings for test</h3>', output.data)

              self.assertIn('Deploy key removed', output.data)

  

+     @patch('pagure.ui.repo.admin_session_timedout')

+     @patch.dict('pagure.APP.config', {'DEPLOY_KEY': False})

+     def test_remove_deploykey_disabled(self, ast):

+         """ Test the remove_deploykey endpoint when it's disabled in the

+         config.

+         """

+         ast.return_value = False

+         tests.create_projects(self.session)

+         tests.create_projects_git(os.path.join(self.path, 'repos'))

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.post('/test/dropdeploykey/1')

+             self.assertEqual(output.status_code, 404)

  

      @patch('pagure.ui.repo.admin_session_timedout')

      def test_remove_user(self, ast):
@@ -640,6 +670,7 @@ 

  

          # Add an user to a project

          repo = pagure.get_authorized_project(self.session, 'test')

+         self.assertEqual(len(repo.users), 0)

          msg = pagure.lib.add_user_to_project(

              session=self.session,

              project=repo,
@@ -648,6 +679,7 @@ 

          )

          self.session.commit()

          self.assertEqual(msg, 'User added')

+         self.assertEqual(len(repo.users), 1)

  

          with tests.user_set(pagure.APP, user):

              output = self.app.post('/test/dropuser/2', follow_redirects=True)
@@ -657,6 +689,9 @@ 

              self.assertIn('<h3>Settings for test</h3>', output.data)

              self.assertNotIn(

                  '</button>\n                      User removed', output.data)

+             self.assertIn('action="/test/dropuser/2">', output.data)

+             repo = pagure.get_authorized_project(self.session, 'test')

+             self.assertEqual(len(repo.users), 1)

  

              data = {'csrf_token': csrf_token}

              output = self.app.post(
@@ -667,6 +702,9 @@ 

              self.assertIn('<h3>Settings for test</h3>', output.data)

              self.assertIn(

                  '</button>\n                      User removed', output.data)

+             self.assertNotIn('action="/test/dropuser/2">', output.data)

+             repo = pagure.get_authorized_project(self.session, 'test')

+             self.assertEqual(len(repo.users), 0)

  

  

      @patch('pagure.ui.repo.admin_session_timedout')
@@ -1252,6 +1290,20 @@ 

          self.assertEqual(output.status_code, 200)

          self.assertTrue('This project has not been forked.' in output.data)

  

+     @patch.dict('pagure.APP.config', {'CASE_SENSITIVE': True})

+     def test_view_repo_case_sensitive(self):

+         """ Test the view_repo endpoint. """

+ 

+         tests.create_projects(self.session)

+         tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)

+ 

+         output = self.app.get('/test')

+         self.assertEqual(output.status_code, 200)

+         self.assertTrue('<p>This repo is brand new!</p>' in output.data)

+ 

+         output = self.app.get('/TEST')

+         self.assertEqual(output.status_code, 404)

+ 

      def test_view_repo(self):

          """ Test the view_repo endpoint. """

  
@@ -2072,6 +2124,9 @@ 

          # Add some content to the git repo

          tests.add_content_git_repo(os.path.join(self.path, 'repos',

                                                  'test.git'))

+         tests.add_content_git_repo(

+             os.path.join(self.path, 'repos','test.git'),

+             branch='feature')

          tests.add_readme_git_repo(os.path.join(self.path, 'repos', 'test.git'))

          tests.add_binary_git_repo(

              os.path.join(self.path, 'repos', 'test.git'), 'test.jpg')
@@ -2080,8 +2135,9 @@ 

  

          output = self.app.get('/test/blame/foofile')

          self.assertEqual(output.status_code, 404)

+         regex = re.compile('>(\w+)</a></td>\n<td class="cell2">')

  

-         # View in a branch

+         # View in master branch

          output = self.app.get('/test/blame/sources')

          self.assertEqual(output.status_code, 200)

          self.assertIn(b'<table class="code_table">', output.data)
@@ -2090,6 +2146,21 @@ 

              b'data-line-number="1"></a></td>', output.data)

          self.assertIn(

              b'<td class="cell2"><pre> bar</pre></td>', output.data)

+         data = regex.findall(output.data)

+         self.assertEqual(len(data), 2)

+ 

+         # View in feature branch

+         output = self.app.get('/test/blame/sources?identifier=feature')

+         self.assertEqual(output.status_code, 200)

+         self.assertIn(b'<table class="code_table">', output.data)

+         self.assertIn(

+             b'<tr><td class="cell1"><a id="1" href="#1" '

+             b'data-line-number="1"></a></td>', output.data)

+         self.assertIn(

+             b'<td class="cell2"><pre> bar</pre></td>', output.data)

+         data2 = regex.findall(output.data)

+         self.assertEqual(len(data2), 2)

+         self.assertNotEqual(data, data2)

  

          # View what's supposed to be an image

          output = self.app.get('/test/blame/test.jpg')
@@ -3799,6 +3870,43 @@ 

              self.assertIn('This project has not been tagged.', output.data)

  

      @patch('pagure.ui.repo.admin_session_timedout')

+     def test_add_token_all_tokens(self, ast):

+         """ Test the add_token endpoint. """

+         ast.return_value = False

+         tests.create_projects(self.session)

+         tests.create_projects_git(

+             os.path.join(self.path, 'repos'), bare=True)

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.get('/test/token/new/')

+             self.assertEqual(output.status_code, 200)

+             self.assertIn('<strong>Create a new token</strong>', output.data)

+             self.assertEqual(

+                 output.data.count('<label class="c-input c-checkbox">'),

+                 len(pagure.APP.config['ACLS'].keys())

+             )

+ 

+     @patch.dict('pagure.APP.config', {'USER_ACLS': ['create_project']})

+     @patch('pagure.ui.repo.admin_session_timedout')

+     def test_add_token_one_token(self, ast):

+         """ Test the add_token endpoint. """

+         ast.return_value = False

+         tests.create_projects(self.session)

+         tests.create_projects_git(

+             os.path.join(self.path, 'repos'), bare=True)

+ 

+         user = tests.FakeUser(username='pingou')

+         with tests.user_set(pagure.APP, user):

+             output = self.app.get('/test/token/new/')

+             self.assertEqual(output.status_code, 200)

+             self.assertIn('<strong>Create a new token</strong>', output.data)

+             self.assertEqual(

+                 output.data.count('<label class="c-input c-checkbox">'),

+                 1

+             )

+ 

+     @patch('pagure.ui.repo.admin_session_timedout')

      def test_add_token(self, ast):

          """ Test the add_token endpoint. """

          ast.return_value = False
@@ -4050,6 +4158,51 @@ 

                  '<strong title="Currently viewing branch master"',

                  output.data)

  

+     @patch.dict('pagure.APP.config', {'ALLOW_DELETE_BRANCH': False})

+     def test_delete_branch_disabled_in_ui(self):

+         """ Test that the delete branch button doesn't show when the feature

+         is turned off. """

+         tests.create_projects(self.session)

+         tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)

+ 

+         # Add a branch that we can delete

+         path = os.path.join(self.path, 'repos', 'test.git')

+         tests.add_content_git_repo(path)

+         repo = pygit2.Repository(path)

+         repo.create_branch('foo', repo.head.get_object())

+ 

+         user = tests.FakeUser(username = 'pingou')

+         with tests.user_set(pagure.APP, user):

+             # Check that the UI doesn't offer the button

+             output = self.app.get('/test')

+             self.assertEqual(output.status_code, 200)

+             self.assertIn(

+                 'data-toggle="tooltip">foo',

+                 output.data)

+             self.assertNotIn('<form id="delete_branch_form-foo"', output.data)

+             self.assertNotIn(

+                 'Are you sure you want to remove the branch',

+                 output.data)

+ 

+     @patch.dict('pagure.APP.config', {'ALLOW_DELETE_BRANCH': False})

+     def test_delete_branch_disabled(self):

+         """ Test the delete_branch endpoint when it's disabled in the entire

+         instance. """

+         tests.create_projects(self.session)

+         tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)

+ 

+         # Add a branch that we can delete

+         path = os.path.join(self.path, 'repos', 'test.git')

+         tests.add_content_git_repo(path)

+         repo = pygit2.Repository(path)

+         repo.create_branch('foo', repo.head.get_object())

+ 

+         user = tests.FakeUser(username = 'pingou')

+         with tests.user_set(pagure.APP, user):

+             # Delete the branch

+             output = self.app.post('/test/b/foo/delete', follow_redirects=True)

+             self.assertEqual(output.status_code, 404)

+ 

      def test_view_docs(self):

          """ Test the view_docs endpoint. """

          output = self.app.get('/docs/foo/')

file modified
+7 -7
@@ -4206,33 +4206,33 @@ 

          expected = [

              # 'foo bar test#1 see?',

              '<p>foo bar <a href="http://pagure.org/test/pull-request/1"'

-             ' title="test pull-request">test#1</a> see?</p>',

+             ' title="[Open] test pull-request">test#1</a> see?</p>',

              # 'foo bar pingou/test#2 I mean, really', -- unknown namespace

              '<p>foo bar pingou/test#2 I mean, really</p>',

              # 'foo bar fork/pingou/test#2 bouza!',

              '<p>foo bar <a href="http://pagure.org/fork/'

-             'pingou/test/pull-request/2" title="test pull-request in fork">'

+             'pingou/test/pull-request/2" title="[Open] test pull-request in fork">'

              'pingou/test#2</a> bouza!</p>',

              # 'foo bar forks/pingou/test#2 bouza!',  -- the 's' doesn't matter

              '<p>foo bar <a href="http://pagure.org/fork/'

-             'pingou/test/pull-request/2" title="test pull-request in fork">'

+             'pingou/test/pull-request/2" title="[Open] test pull-request in fork">'

              'pingou/test#2</a> bouza!</p>',

              # 'foo bar ns/test3#4 bouza!',

              '<p>foo bar <a href="http://pagure.org/ns/test3/issue/4"'

-             ' title="test issue">ns/test3#4</a> bouza!</p>',

+             ' title="[Open] test issue">ns/test3#4</a> bouza!</p>',

              # 'foo bar fork/user/ns/test#5 bouza!', -- unknown fork

              '<p>foo bar user/ns/test#5 bouza!</p>',

              # 'foo bar fork/pingou/ns/test#7 bouza!',

              '<p>foo bar <a href="http://pagure.org/'

-             'fork/pingou/ns/test/issue/7" title="test issue #7">'

+             'fork/pingou/ns/test/issue/7" title="[Open] test issue #7">'

              'pingou/ns/test#7</a> bouza!</p>',

              # 'test#1 bazinga!',

              '<p><a href="http://pagure.org/test/pull-request/1" '

-             'title="test pull-request">test#1</a> bazinga!</p>',

+             'title="[Open] test pull-request">test#1</a> bazinga!</p>',

              # 'pingou opened the PR forks/pingou/test#2'

              '<p>pingou opened the PR <a href="http://pagure.org/'

              'fork/pingou/test/pull-request/2" '

-             'title="test pull-request in fork">pingou/test#2</a></p>',

+             'title="[Open] test pull-request in fork">pingou/test#2</a></p>',

              # 'fork/pingou/ns/test#8 is private',

              '<p><a href="http://pagure.org/fork/pingou/ns/test/issue/8" '

              'title="Private issue">pingou/ns/test#8</a> is private</p>',

@@ -16,6 +16,7 @@ 

  import shutil  # noqa

  import sys  # noqa

  import tempfile  # noqa

+ import time  # noqa

  import os  # noqa

  

  import pygit2  # noqa
@@ -146,7 +147,7 @@ 

          ori_remote = clone_repo.remotes[0]

          PagureRepo.push(ori_remote, refname)

  

-         # Add one commit to the fork repo

+         # Add two commits to the fork repo

          repopath = os.path.join(newpath, 'pingou_test')

          clone_repo = pygit2.clone_repository(gitrepo2, repopath)

  
@@ -163,7 +164,7 @@ 

              'Alice Author', 'alice@authors.tld')

          committer = pygit2.Signature(

              'Cecil Committer', 'cecil@committers.tld')

-         clone_repo.create_commit(

+         last_commit = clone_repo.create_commit(

              'refs/heads/feature_foo',  # the name of the reference to update

              author,

              committer,
@@ -174,6 +175,28 @@ 

              [last_commit.oid.hex]

          )

  

+         with open(os.path.join(repopath, 'sources'), 'w') as stream:

+                 stream.write('foo\n bar\nbaz\n')

+         clone_repo.index.add('sources')

+         clone_repo.index.write()

+ 

+         # Commits the files added

+         tree = clone_repo.index.write_tree()

+         author = pygit2.Signature(

+             'Alice Author', 'alice@authors.tld')

+         committer = pygit2.Signature(

+             'Cecil Committer', 'cecil@committers.tld')

+         last_commit = clone_repo.create_commit(

+             'refs/heads/feature_foo',  # the name of the reference to update

+             author,

+             committer,

+             'Second edit on side branch of the file sources for testing',

+             # binary string representing the tree object ID

+             tree,

+             # list of binary strings representing parents of the new commit

+             [last_commit.hex]

+         )

+ 

          # Push to the fork repo

          ori_remote = clone_repo.remotes[0]

          refname = 'refs/heads/feature_foo:refs/heads/feature_foo'
@@ -212,9 +235,13 @@ 

              branch_from='feature_foo',

              branch_to='master'

          )

-         self.assertEqual(len(diff_commits), 1)

+         self.assertEqual(len(diff_commits), 2)

          self.assertEqual(

              diff_commits[0].message,

+             'Second edit on side branch of the file sources for testing'

+         )

+         self.assertEqual(

+             diff_commits[1].message,

              'New edition on side branch of the file sources for testing'

          )

          self.assertEqual(
@@ -264,12 +291,236 @@ 

              with_diff=True

          )

  

-         self.assertEqual(len(diff_commits), 1)

+         self.assertEqual(len(diff_commits), 2)

          self.assertEqual(

              diff_commits[0].message,

+             'Second edit on side branch of the file sources for testing'

+         )

+         self.assertEqual(

+             diff_commits[1].message,

              'New edition on side branch of the file sources for testing'

          )

  

+         # Check that the PR has its PR refs

+         # we don't know the task id but we'll give it 30 sec to finish

+         cnt = 0

+         repo = PagureRepo(gitrepo)

+         while 1:

+             if 'refs/pull/1/head' in list(repo.listall_references()):

+                 break

+             cnt += 1

+             if cnt == 60:

+                 break

+             time.sleep(0.5)

+ 

+         self.assertTrue(cnt < 60)

+ 

+         pr_ref = repo.lookup_reference('refs/pull/1/head')

+         commit = pr_ref.get_object()

+         self.assertEqual(

+             commit.oid.hex,

+             diff_commits[0].oid.hex

+         )

+ 

+     def test_diff_pull_request_updated(self):

+         """ Test that calling pagure.lib.git.diff_pull_request on an updated

+         PR updates the PR reference

+         """

+         gitrepo = os.path.join(self.path, 'repos', 'test.git')

+         gitrepo2 = os.path.join(

+             self.path, 'repos', 'forks', 'pingou', 'test.git')

+         request = pagure.lib.search_pull_requests(

+             self.session, requestid=1, project_id=1)

+ 

+         # Get the diff corresponding to the PR and check its ref

+ 

+         diff_commits, diff = pagure.lib.git.diff_pull_request(

+             self.session,

+             request=request,

+             repo_obj=PagureRepo(gitrepo2),

+             orig_repo=PagureRepo(gitrepo),

+             requestfolder=None,

+             with_diff=True

+         )

+ 

+         self.assertEqual(len(diff_commits), 2)

+ 

+         # Check that the PR has its PR refs

+         # we don't know the task id but we'll give it 30 sec to finish

+         cnt = 0

+         repo = PagureRepo(gitrepo)

+         while 1:

+             if 'refs/pull/1/head' in list(repo.listall_references()):

+                 break

+             cnt += 1

+             if cnt == 60:

+                 break

+             time.sleep(0.5)

+ 

+         self.assertTrue(cnt < 60)

+ 

+         pr_ref = repo.lookup_reference('refs/pull/1/head')

+         commit = pr_ref.get_object()

+         self.assertEqual(

+             commit.oid.hex,

+             diff_commits[0].oid.hex

+         )

+ 

+         # Add a new commit on the fork

+         repopath = os.path.join(self.path, 'pingou_test2')

+         clone_repo = pygit2.clone_repository(

+             gitrepo2, repopath, checkout_branch='feature_foo')

+ 

+         with open(os.path.join(repopath, 'sources'), 'w') as stream:

+                 stream.write('foo\n bar\nbaz\nhey there\n')

+         clone_repo.index.add('sources')

+         clone_repo.index.write()

+ 

+         last_commit = clone_repo.lookup_branch('feature_foo').get_object()

+ 

+         # Commits the files added

+         tree = clone_repo.index.write_tree()

+         author = pygit2.Signature(

+             'Alice Author', 'alice@authors.tld')

+         committer = pygit2.Signature(

+             'Cecil Committer', 'cecil@committers.tld')

+         last_commit = clone_repo.create_commit(

+             'refs/heads/feature_foo',  # the name of the reference to update

+             author,

+             committer,

+             'Third edit on side branch of the file sources for testing',

+             # binary string representing the tree object ID

+             tree,

+             # list of binary strings representing parents of the new commit

+             [last_commit.oid.hex]

+         )

+ 

+         # Push to the fork repo

+         ori_remote = clone_repo.remotes[0]

+         refname = 'refs/heads/feature_foo:refs/heads/feature_foo'

+         PagureRepo.push(ori_remote, refname)

+ 

+         # Get the new diff for that PR and check its new ref

+ 

+         diff_commits, diff = pagure.lib.git.diff_pull_request(

+             self.session,

+             request=request,

+             repo_obj=PagureRepo(gitrepo2),

+             orig_repo=PagureRepo(gitrepo),

+             requestfolder=None,

+             with_diff=True

+         )

+         self.assertEqual(len(diff_commits), 3)

+ 

+         # Check that the PR has its PR refs

+         # we don't know the task id but we'll give it 30 sec to finish

+         cnt = 0

+         repo = PagureRepo(gitrepo)

+         while 1:

+             if 'refs/pull/1/head' in list(repo.listall_references()):

+                 break

+             cnt += 1

+             if cnt == 60:

+                 break

+             time.sleep(0.5)

+ 

+         self.assertTrue(cnt < 60)

+ 

+         pr_ref = repo.lookup_reference('refs/pull/1/head')

+         commit2 = pr_ref.get_object()

+         self.assertEqual(

+             commit2.oid.hex,

+             diff_commits[0].oid.hex

+         )

+         self.assertNotEqual(

+             commit.oid.hex,

+             commit2.oid.hex,

+         )

+ 

+     def test_two_diff_pull_request_sequentially(self):

+         """ Test calling pagure.lib.git.diff_pull_request twice returns

+         the same data

+         """

+         gitrepo = os.path.join(self.path, 'repos', 'test.git')

+         gitrepo2 = os.path.join(

+             self.path, 'repos', 'forks', 'pingou', 'test.git')

+         request = pagure.lib.search_pull_requests(

+             self.session, requestid=1, project_id=1)

+ 

+         # Get the diff corresponding to the PR and check its ref

+ 

+         diff_commits, diff = pagure.lib.git.diff_pull_request(

+             self.session,

+             request=request,

+             repo_obj=PagureRepo(gitrepo2),

+             orig_repo=PagureRepo(gitrepo),

+             requestfolder=None,

+             with_diff=True

+         )

+ 

+         self.assertEqual(len(diff_commits), 2)

+ 

+         # Check that the PR has its PR refs

+         # we don't know the task id but we'll give it 30 sec to finish

+         cnt = 0

+         repo = PagureRepo(gitrepo)

+         while 1:

+             if 'refs/pull/1/head' in list(repo.listall_references()):

+                 break

+             cnt += 1

+             if cnt == 60:

+                 break

+             time.sleep(0.5)

+ 

+         self.assertTrue(cnt < 60)

+ 

+         pr_ref = repo.lookup_reference('refs/pull/1/head')

+         commit = pr_ref.get_object()

+         self.assertEqual(

+             commit.oid.hex,

+             diff_commits[0].oid.hex

+         )

+ 

+         # Run diff_pull_request a second time

+ 

+         diff_commits2, diff = pagure.lib.git.diff_pull_request(

+             self.session,

+             request=request,

+             repo_obj=PagureRepo(gitrepo2),

+             orig_repo=PagureRepo(gitrepo),

+             requestfolder=None,

+             with_diff=True

+         )

+         self.assertEqual(len(diff_commits2), 2)

+         self.assertEqual(

+             [d.oid.hex for d in diff_commits2],

+             [d.oid.hex for d in diff_commits])

+ 

+         # Check that the PR has its PR refs

+         # we don't know the task id but we'll give it 30 sec to finish

+         cnt = 0

+         repo = PagureRepo(gitrepo)

+         while 1:

+             if 'refs/pull/1/head' in list(repo.listall_references()):

+                 break

+             cnt += 1

+             if cnt == 60:

+                 break

+             time.sleep(0.5)

+ 

+         self.assertTrue(cnt < 60)

+ 

+         pr_ref = repo.lookup_reference('refs/pull/1/head')

+         commit2 = pr_ref.get_object()

+         self.assertEqual(

+             commit2.oid.hex,

+             diff_commits[0].oid.hex

+         )

+ 

+         self.assertEqual(

+             commit.oid.hex,

+             commit2.oid.hex

+         )

  

  if __name__ == '__main__':

      unittest.main(verbosity=2)

file modified
+1 -1
@@ -1,6 +1,6 @@ 

  eventlet

  mock==1.1.2

- nose

+ nose>=0.10.4

  nosexcover

  flake8

  

no initial comment

I don't think that gitolite.conf is a directory :)

I confirm it's not :)

1 new commit added

  • Fixes the README.rst file
6 years ago

3 new commits added

  • Merge branch 'UpdateREADME' of ssh://pagure.io/forks/ompragash/pagure into UpdateREADME
  • Fixes the README.rst file
  • Fixes the README.rst file
6 years ago

I thing something went wrong somewhere in the rebase :)

Pull-Request has been closed by pingou

6 years ago
Changes Summary 50
+1 -1
file changed
README.rst
+4 -4
file changed
dev/ansible/roles/pagure-dev/files/bashrc
+1 -1
file changed
dev/ansible/roles/pagure-dev/files/pagure.service
+13
file added
dev/ansible/roles/pagure-dev/files/pagure_worker.service
+15 -0
file changed
dev/ansible/roles/pagure-dev/tasks/main.yml
+92 -0
file changed
doc/configuration.rst
+9 -5
file changed
doc/contributors.rst
+38 -1
file changed
files/pagure.spec
+2 -1
file changed
pagure-loadjson/pagure_loadjson_server.py
+2 -1
file changed
pagure-logcom/pagure_logcom_server.py
+2 -1
file changed
pagure-webhook/pagure-webhook-server.py
+34 -27
file changed
pagure/__init__.py
+2 -1
file changed
pagure/api/ci/jenkins.py
+2 -1
file changed
pagure/api/project.py
+52 -10
file changed
pagure/cli/admin.py
+13 -0
file changed
pagure/default_config.py
+4 -3
file changed
pagure/hooks/__init__.py
+2 -1
file changed
pagure/hooks/files/default_hook.py
+3 -1
file changed
pagure/hooks/files/fedmsg_hook.py
+3 -1
file changed
pagure/hooks/files/pagure_force_commit_hook.py
+2 -1
file changed
pagure/hooks/files/pagure_hook_tickets.py
+8 -6
file changed
pagure/hooks/pagure_hook.py
+26 -9
file changed
pagure/lib/__init__.py
+17 -5
file changed
pagure/lib/git.py
+3 -1
file changed
pagure/lib/git_auth.py
+0 -1
file changed
pagure/lib/model.py
+44 -22
file changed
pagure/lib/tasks.py
+8 -2
file changed
pagure/pfmarkdown.py
+1 -0
file changed
pagure/templates/file.html
+5 -1
file changed
pagure/templates/issue.html
+2 -2
file changed
pagure/templates/issues.html
+1 -1
file changed
pagure/templates/master.html
+1 -1
file changed
pagure/templates/repo_info.html
+3 -2
file changed
pagure/templates/settings.html
+1 -1
file changed
pagure/templates/user_issues.html
+2 -1
file changed
pagure/templates/user_settings.html
+1 -1
file changed
pagure/templates/waiting.html
+2 -1
file changed
pagure/ui/app.py
+4 -2
file changed
pagure/ui/fork.py
+19 -3
file changed
pagure/ui/repo.py
+156 -2
file changed
tests/test_pagure_admin.py
+6 -4
file changed
tests/test_pagure_flask_api_user.py
+46 -13
file changed
tests/test_pagure_flask_internal.py
+129 -2
file changed
tests/test_pagure_flask_ui_app.py
+73 -7
file changed
tests/test_pagure_flask_ui_plugins_fedmsg.py
+151 -7
file changed
tests/test_pagure_flask_ui_plugins_pagure_hook.py
+155 -2
file changed
tests/test_pagure_flask_ui_repo.py
+7 -7
file changed
tests/test_pagure_lib.py
+255 -4
file changed
tests/test_pagure_lib_git_diff_pr.py
+1 -1
file changed
tests_requirements.txt