blob: 0edac8dcc4145ac3513505f03ac64466487f23d7 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2016 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""Protocol buffers for Monorail projects."""
6
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11from protorpc import messages
12
13# Project state affects permissions in that project, and project deletion.
14# It is edited on the project admin page. If it is anything other that LIVE
15# it triggers a notice at the top of every project page.
16# For more info, see the "Project deletion in Monorail" design doc.
17class ProjectState(messages.Enum):
18 """Enum for states in the project lifecycle."""
19 # Project is visible and indexed. This is the typical state.
20 #
21 # If moved_to is set, this project is live but has been moved
22 # to another location, so redirects will be used or links shown.
23 LIVE = 1
24
25 # Project owner has requested the project be archived. Project is
26 # read-only to members only, off-limits to non-members. Issues
27 # can be searched when in the project, but should not appear in
28 # site-wide searches. The project name is still in-use by this
29 # project.
30 #
31 # If a delete_time is set, then the project is doomed: (1) the
32 # state can only be changed by a site admin, and (2) the project
33 # will automatically transition to DELETABLE after that time is
34 # reached.
35 ARCHIVED = 2
36
37 # Project can be deleted at any time. The project name should
38 # have already been changed to a generated string, so it's
39 # impossible to navigate to this project, and the original name
40 # can be reused by a new project.
41 DELETABLE = 3
42
43
44# Project access affects permissions in that project.
45# It is edited on the project admin page.
46class ProjectAccess(messages.Enum):
47 """Enum for possible project access levels."""
48 # Anyone may view this project, even anonymous users.
49 ANYONE = 1
50
51 # Only project members may view the project.
52 MEMBERS_ONLY = 3
53
54
55# A Project PB represents a project in Monorail, which is a workspace for
56# project members to collaborate on issues.
57# A project is created on the project creation page, searched on the project
58# list page, and edited on the project admin page.
59# Next message: 74
60class Project(messages.Message):
61 """This protocol buffer holds all the metadata associated with a project."""
62 state = messages.EnumField(ProjectState, 1, required=True)
63 access = messages.EnumField(ProjectAccess, 18, default=ProjectAccess.ANYONE)
64
65 # The short identifier for this project. This value is lower-cased,
66 # and must be between 3 and 20 characters (inclusive). Alphanumeric
67 # and dashes are allowed, and it must start with an alpha character.
68 # Project names must be unique.
69 project_name = messages.StringField(2, required=True)
70
71 # A numeric identifier for this project.
72 project_id = messages.IntegerField(3, required=True)
73
74 # A one-line summary (human-readable) name of the project.
75 summary = messages.StringField(4, default='')
76
77 # A detailed description of the project.
78 description = messages.StringField(5, default='')
79
80 # Description of why this project has the state set as it is.
81 # This is used for administrative purposes to notify Owners that we
82 # are going to delete their project unless they can provide a good
83 # reason to not do so.
84 state_reason = messages.StringField(9)
85
86 # Time (in seconds) at which an ARCHIVED project may automatically
87 # be changed to state DELETABLE. The state change is done by a
88 # cron job.
89 delete_time = messages.IntegerField(10)
90
91 # Note that these lists are disjoint (a user ID will not appear twice).
92 owner_ids = messages.IntegerField(11, repeated=True)
93 committer_ids = messages.IntegerField(12, repeated=True)
94 contributor_ids = messages.IntegerField(15, repeated=True)
95
96 class ExtraPerms(messages.Message):
97 """Nested message for each member's extra permissions in a project."""
98 member_id = messages.IntegerField(1, required=True)
99 # Each custom perm is a single word [a-zA-Z0-9].
100 perms = messages.StringField(2, repeated=True)
101
102 extra_perms = messages.MessageField(ExtraPerms, 16, repeated=True)
103
104 # Project owners may choose to have ALL issue change notifications go to a
105 # mailing list (in addition to going directly to the users interested
106 # in that issue).
107 issue_notify_address = messages.StringField(14)
108
109 # These fields keep track of the cumulative size of all issue attachments
110 # in a given project. Normally, the number of bytes used is compared
111 # to a constant defined in the web application. However, if a custom
112 # quota is specified here, it will be used instead. An issue attachment
113 # will fail if its size would put the project over its quota. Not all
114 # projects have these fields: they are only set when the first attachment
115 # is uploaded.
116 attachment_bytes_used = messages.IntegerField(38, default=0)
117 # If quota is not set, default from tracker_constants.py is used.
118 attachment_quota = messages.IntegerField(39)
119
120 # NOTE: open slots 40, 41
121
122 # Recent_activity is a timestamp (in seconds since the Epoch) of the
123 # last time that an issue was entered, updated, or commented on.
124 recent_activity = messages.IntegerField(42, default=0)
125
126 # NOTE: open slots 43...
127
128 # Timestamp (in seconds since the Epoch) of the most recent change
129 # to this project that would invalidate cached content. It is set
130 # whenever project membership is edited, or any component config PB
131 # is edited. HTTP requests for auto-complete feeds include this
132 # value in the URL.
133 cached_content_timestamp = messages.IntegerField(53, default=0)
134
135 # If set, this project has been moved elsewhere. This can
136 # be an absolute URL, the name of another project on the same site.
137 moved_to = messages.StringField(60)
138
139 # Enable inbound email processing for issues.
140 process_inbound_email = messages.BooleanField(63, default=False)
141
142 # Limit removal of Restrict-* labels to project owners.
143 only_owners_remove_restrictions = messages.BooleanField(64, default=False)
144
145 # A per-project read-only lock. This lock (1) is meant to be
146 # long-lived (lasting as long as migration operations, project
147 # deletion, or anything else might take and (2) is meant to only
148 # limit user mutations; whether or not it limits automated actions
149 # that would change project data (such as workflow items) is
150 # determined based on the action.
151 #
152 # This lock is implemented as a user-visible string describing the
153 # reason for the project being in a read-only state. An absent or empty
154 # value indicates that the project is read-write; a present and
155 # non-empty value indicates that the project is read-only for the
156 # reason described.
157 read_only_reason = messages.StringField(65)
158
159 # This option is rarely used, but it makes sense for projects that aim for
160 # hub-and-spoke collaboration bewtween a vendor organization (like Google)
161 # and representatives of partner companies who are not supposed to know
162 # about each other.
163 # When true, it prevents project committers, contributors, and visitors
164 # from seeing the list of project members on the project summary page,
165 # on the People list page, and in autocomplete for issue owner and Cc.
166 # Project owners can always see the complete list of project members.
167 only_owners_see_contributors = messages.BooleanField(66, default=False)
168
169 # This configures the URLs generated when autolinking revision numbers.
170 # E.g., gitiles, viewvc, or crrev.com.
171 revision_url_format = messages.StringField(67)
172
173 # The home page of the Project.
174 home_page = messages.StringField(68)
175 # The url to redirect to for wiki/documentation links.
176 docs_url = messages.StringField(71)
177 # The url to redirect to for wiki/documentation links.
178 source_url = messages.StringField(72)
179 # The GCS object ID of the Project's logo.
180 logo_gcs_id = messages.StringField(69)
181 # The uploaded file name of the Project's logo.
182 logo_file_name = messages.StringField(70)
183
184 # Always send the full content of update in notifications.
185 issue_notify_always_detailed = messages.BooleanField(73, default=False)
186
187
188# This PB documents some of the duties of some of the members
189# in a given project. This info is displayed on the project People page.
190class ProjectCommitments(messages.Message):
191 project_id = messages.IntegerField(50)
192
193 class MemberCommitment(messages.Message):
194 member_id = messages.IntegerField(11, required=True)
195 notes = messages.StringField(13)
196
197 commitments = messages.MessageField(MemberCommitment, 2, repeated=True)
198
199
200def MakeProject(
201 project_name, project_id=None, state=ProjectState.LIVE,
202 access=ProjectAccess.ANYONE, summary=None, description=None,
203 moved_to=None, cached_content_timestamp=None,
204 owner_ids=None, committer_ids=None, contributor_ids=None,
205 read_only_reason=None, home_page=None, docs_url=None, source_url=None,
206 logo_gcs_id=None, logo_file_name=None):
207 """Returns a project protocol buffer with the given attributes."""
208 project = Project(
209 project_name=project_name, access=access, state=state)
210 if project_id:
211 project.project_id = project_id
212 if moved_to:
213 project.moved_to = moved_to
214 if cached_content_timestamp:
215 project.cached_content_timestamp = cached_content_timestamp
216 if summary:
217 project.summary = summary
218 if description:
219 project.description = description
220 if home_page:
221 project.home_page = home_page
222 if docs_url:
223 project.docs_url = docs_url
224 if source_url:
225 project.source_url = source_url
226 if logo_gcs_id:
227 project.logo_gcs_id = logo_gcs_id
228 if logo_file_name:
229 project.logo_file_name = logo_file_name
230
231 project.owner_ids.extend(owner_ids or [])
232 project.committer_ids.extend(committer_ids or [])
233 project.contributor_ids.extend(contributor_ids or [])
234
235 if read_only_reason is not None:
236 project.read_only_reason = read_only_reason
237
238 return project