Add a patch_committer relation (closes #1655136)

Allows explicit designation of the user handling the patch application.

authorJulien Cristau <julien.cristau@logilab.fr>
changeset99ec0ca760a3
branchdefault
phasepublic
hiddenno
parent revision#912662358a5a closes #1872859: fix and simplify task state change handling by using a user callback
child revision#87606143e9d5 0.8
files modified by this revision
migration/0.7.1_Any.py
schema.py
views/facets.py
views/primary.py
views/startup.py
# HG changeset patch
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1311771651 -7200
# Wed Jul 27 15:00:51 2011 +0200
# Node ID 99ec0ca760a3057add5494625fdefe70706f6104
# Parent 912662358a5a1078a318e592264bfa8ff5524dfc
Add a patch_committer relation (closes #1655136)

Allows explicit designation of the user handling the patch application.

diff --git a/migration/0.7.1_Any.py b/migration/0.7.1_Any.py
@@ -0,0 +1,2 @@
1 +
2 +add_relation_type('patch_committer')
diff --git a/schema.py b/schema.py
@@ -120,10 +120,23 @@
3      subject = 'Patch'
4      object = 'CWUser'
5      constraints = [RQLConstraint('EXISTS(O in_group G, G name "reviewers") '
6                                   'OR EXISTS(S patch_repository R, R repository_reviewer O)')]
7 
8 +class patch_committer(RelationDefinition):
9 +    __permissions__ = {
10 +        'read': ('managers', 'users', 'guests'),
11 +        'add': ('managers', 'committers',
12 +                RRQLExpression('S patch_repository R, R repository_committer U')),
13 +        'delete': ('managers', 'committers',
14 +                   RRQLExpression('S patch_repository R, R repository_committer U')),
15 +        }
16 +    subject = 'Patch'
17 +    object = 'CWUser'
18 +    constraints = [RQLConstraint('EXISTS(O in_group G, G name "committers") '
19 +                                 'OR EXISTS(S patch_repository R, R repository_committer O)')]
20 +
21  class patch_depends_on(RelationDefinition):
22      subject = 'Patch'
23      object = 'Patch'
24 
25  # ability to reference diff chunks #############################################
diff --git a/views/facets.py b/views/facets.py
@@ -46,6 +46,10 @@
26      __regid__ = 'vcvreview.patch.branch'
27      __select__ = facet.AttributeFacet.__select__ & is_instance('Patch')
28      rtype = 'branch'
29      i18nable = False
30 
31 -
32 +class PatchCommitterFacet(facet.RelationFacet):
33 +    __regid__ = 'vcreview.patch_committer'
34 +    rtype = 'patch_committer'
35 +    role = 'subject'
36 +    target_attr = 'login'
diff --git a/views/primary.py b/views/primary.py
@@ -40,10 +40,11 @@
37  # patch primary view ###########################################################
38 
39  _pvs.tag_subject_of(('Patch', 'patch_repository', '*'), 'hidden') # in breadcrumbs
40  _pvs.tag_subject_of(('Patch', 'patch_revision', '*'), 'hidden') # table in attributes
41  _pvs.tag_subject_of(('Patch', 'patch_reviewer', '*'), 'attributes')
42 +_pvs.tag_subject_of(('Patch', 'patch_committer', '*'), 'attributes')
43  _pvdc.tag_subject_of(('Patch', 'applied_at', '*'), {'vid': 'incontext'})
44 
45  class PatchPrimaryView(tabs.TabbedPrimaryView):
46      __select__ = is_instance('Patch')
47 
@@ -171,11 +172,11 @@
48 
49  class RepositoryPatchesTable(EntityView):
50      __regid__ = 'vcreview.repository.patches'
51      __select__ = is_instance('Repository') & score_entity(lambda x: x.patchrepo_of)
52 
53 -    rql = ('Any P,PO,P,PB,PS,COUNT(TR) GROUPBY P,PO,PB,PS WHERE '
54 +    rql = ('Any P,PO,P,P,PB,PS,COUNT(TR) GROUPBY P,PO,PB,PS WHERE '
55             'P originator PO, P branch PB, P in_state PS, TR? wf_info_for P, '
56             'P patch_repository R, R eid %(x)s')
57 
58      def entity_call(self, entity):
59          linktitle = self._cw._('Patches for %s') % entity.dc_title()
diff --git a/views/startup.py b/views/startup.py
@@ -30,11 +30,11 @@
60 
61  class AllActivePatches(view.StartupView):
62      __regid__ = 'vcreview.allactivepatches'
63      title = _('All active patches')
64 
65 -    rql = ('Any P,PO,P,PB,PS,COUNT(TR),R GROUPBY R,P,PO,PB,PS '
66 +    rql = ('Any P,PO,P,P,PB,PS,COUNT(TR),R GROUPBY R,P,PO,PB,PS '
67             'ORDERBY RT,PB,PO WHERE P originator PO, P branch PB, P in_state PS,'
68             'TR? wf_info_for P, P patch_repository R, R title RT, '
69             'PS name %s')
70 
71      @cached
@@ -50,16 +50,17 @@
72 
73  class UserWorkList(AllActivePatches):
74      __regid__ = 'vcreview.patches.worklist'
75      title = _('My review worklist')
76 
77 -    rql = ('Any P,PO,P,PB,PS,COUNT(TR),R GROUPBY R,P,PO,PB,PS '
78 +    rql = ('Any P,PO,P,P,PB,PS,COUNT(TR),R GROUPBY R,P,PO,PB,PS '
79             'ORDERBY RT,PB,PO WHERE P originator PO, P branch PB, P in_state PS,'
80             'TR? wf_info_for P, P patch_repository R, R title RT, U eid %(u)s, '
81             'EXISTS(PS name "pending-review" AND P patch_reviewer U) '
82 -           'OR EXISTS(PS name IN ("reviewed", "deleted") AND (EXISTS(R repository_committer U) '
83 -           'OR EXISTS(U in_group G, G name "committers")))')
84 +           'OR EXISTS(PS name "reviewed" AND P patch_committer U) '
85 +           'OR (EXISTS(PS name IN ("reviewed", "deleted") AND NOT EXISTS(P patch_committer V) '
86 +           '    AND (EXISTS(R repository_committer U) OR EXISTS(U in_group G, G name "committers"))))')
87 
88      @cached
89      def filter_box_context_info(self):
90          rset = self._cw.execute(self.rql, {'u': self._cw.user.eid})
91          return rset, 'vcreview.patches.table', domid(self.__regid__), False
@@ -69,26 +70,35 @@
92  class PatchesTable(tableview.TableView):
93      __regid__ = 'vcreview.patches.table'
94      # XXX selector
95      def call(self, **kwargs):
96          kwargs['paginate'] = True
97 -        super(PatchesTable, self).call(cellvids={2: 'vcreview.patch.reviewers'},
98 +        super(PatchesTable, self).call(cellvids={2: 'vcreview.patch.reviewers', 3: 'vcreview.patch.committers'},
99                                         **kwargs)
100 
101      def label_column_2(self):
102          return self._cw._('patch_reviewer')
103 -    def label_column_5(self):
104 +    def label_column_3(self):
105 +        return self._cw._('patch_committer')
106 +    def label_column_6(self):
107          return self._cw.__('Transition_plural').lower()
108 
109 
110  class PatchReviewer(view.EntityView):
111      __regid__ = 'vcreview.patch.reviewers'
112      __select__ = is_instance('Patch')
113      def entity_call(self, entity, **kwargs):
114          self._cw.view('csv', entity.related('patch_reviewer'), 'null',
115                        w=self.w)
116 
117 +class PatchCommitter(view.EntityView):
118 +    __regid__ = 'vcreview.patch.committers'
119 +    __select__ = is_instance('Patch')
120 +    def entity_call(self, entity, **kwargs):
121 +        self._cw.view('csv', entity.related('patch_committer'), 'null',
122 +                      w=self.w)
123 +
124 
125  class WorkListLink(component.CtxComponent):
126      __regid__ = 'vcreview.worklist.warning'
127      __select__ = (component.CtxComponent.__select__
128                    & ~anonymous_user()