pagure_request_hook.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2014-2016 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals
  8. import sqlalchemy as sa
  9. import wtforms
  10. try:
  11. from flask_wtf import FlaskForm
  12. except ImportError:
  13. from flask_wtf import Form as FlaskForm
  14. from sqlalchemy.orm import relation
  15. from sqlalchemy.orm import backref
  16. import pagure.lib.git
  17. import pagure.lib.tasks_services
  18. from pagure.hooks import BaseHook, BaseRunner
  19. from pagure.lib.model import BASE, Project
  20. class PagureRequestsTable(BASE):
  21. """ Stores information about the pagure requests hook deployed on a
  22. project.
  23. Table -- hook_pagure_requests
  24. """
  25. __tablename__ = "hook_pagure_requests"
  26. id = sa.Column(sa.Integer, primary_key=True)
  27. project_id = sa.Column(
  28. sa.Integer,
  29. sa.ForeignKey("projects.id", onupdate="CASCADE", ondelete="CASCADE"),
  30. nullable=False,
  31. unique=True,
  32. index=True,
  33. )
  34. active = sa.Column(sa.Boolean, nullable=False, default=False)
  35. project = relation(
  36. "Project",
  37. remote_side=[Project.id],
  38. backref=backref(
  39. "pagure_hook_requests",
  40. cascade="delete, delete-orphan",
  41. single_parent=True,
  42. uselist=False,
  43. ),
  44. )
  45. class PagureRequestRunner(BaseRunner):
  46. """ Runner for the hook updating the db about requests on push to the
  47. git repo containing the meta-data about pull-requests.
  48. """
  49. @staticmethod
  50. def post_receive(session, username, project, repotype, repodir, changes):
  51. """ Run the default post-receive hook.
  52. For args, see BaseRunner.runhook.
  53. """
  54. if repotype != "requests":
  55. print(
  56. "The pagure requests hook only runs on the requests "
  57. "git repo."
  58. )
  59. return
  60. if username == "pagure":
  61. # This was an update from inside the UI. Do not trigger further
  62. # database updates, as this has already been done
  63. return
  64. for refname in changes:
  65. (oldrev, newrev) = changes[refname]
  66. if set(newrev) == set(["0"]):
  67. print(
  68. "Deleting a reference/branch, so we won't run the "
  69. "pagure hook"
  70. )
  71. return
  72. commits = pagure.lib.git.get_revs_between(
  73. oldrev, newrev, repodir, refname
  74. )
  75. pagure.lib.tasks_services.load_json_commits_to_db.delay(
  76. name=project.name,
  77. commits=commits,
  78. abspath=repodir,
  79. data_type="pull-request",
  80. agent=username,
  81. namespace=project.namespace,
  82. username=project.user.user if project.is_fork else None,
  83. )
  84. class PagureRequestsForm(FlaskForm):
  85. """ Form to configure the pagure hook. """
  86. active = wtforms.BooleanField("Active", [wtforms.validators.Optional()])
  87. class PagureRequestHook(BaseHook):
  88. """ Pagure request hook. """
  89. name = "Pagure requests"
  90. description = (
  91. "Pagure specific hook to update pull-requests stored "
  92. "in the database based on the information pushed in the requests "
  93. "git repository."
  94. )
  95. form = PagureRequestsForm
  96. db_object = PagureRequestsTable
  97. backref = "pagure_hook_requests"
  98. form_fields = ["active"]
  99. runner = PagureRequestRunner