1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
Code Guidelines
---------------
A few code guidelines to try to stick to, please comment if none of
these make sense, they are pretty basic and mostly apply to old code.
However for people who are looking at current code, they may take up
bad habits that exist in the current codebase.
Python Version
--------------
Python 3.9 is the minimum supported version.
Dependencies
------------
Python and Bash should be the only hard dependencies. Any other
dependencies, including external Python modules that are not included
with Python itself, must be optionally enabled by runtime detection.
Tabs
----
We comply with PEP 8 so we now use spaces in Python source files.
We use tabs in Bash files for consistency with ebuild code.
Line-Wrapping
-------------
Please use Black for formatting of Python source files.
Lines should typically not be longer than 80 characters; if they are, an
attempt should be made to wrap them. Move code to the line below and
indent once (\t).
errors.append(MalformedMetadata(
errors.DESCRIPTION_TOO_LONG_ERROR % \
(length, max_desc_len),
attr='DESCRIPTION.toolong')
Do not do this:
errors.append(MalformedMetadata(
errors.DESCRIPTION_TOO_LONG_ERROR % \
(length, max_desc_len),
attr='DESCRIPTION.toolong')
The mixing of tabs and spaces means other developers can't read what you
did. This is why the Python PEPs state spaces over tabs; because with
spaces the line wrapping is always clear (but you cannot convert spaces
as easily as tabwidth).
Comparisons
-----------
if foo != None
should be replaced with:
if foo is not None:
Is not does a reference comparison (address1 = address2 basically) and
the == forces a by value compare (with __eq__())
Dict Lookups
------------
Try not to use has_key, you can use
if foo in dict
instead of if dict.has_key(foo)
Also don't do stuff like:
if foo in dict and dict[foo]:
Generally you can do two things here, if you are messing with defaults..
dict.get(foo, some_default)
will try to retrieve foo from dict, if there is a KeyError, will insert
foo into dict with the value of some_default. This method is preferred
in cases where you are messing with defaults:
try:
dict[foo]
except KeyError:
dict[foo] = default_value
The get call is nicer (compact) and faster (try,except are slow).
Imports
-------
Import things one per line
YES:
import os
import time
import sys
NO:
import os,sys,time
When importing from a module, you may import more than 1 thing at a
time.
YES:
from portage.module import foo, bar, baz
Multiline imports are ok (for now :))
Try to group system and package imports separately.
YES:
import os
import sys
import time
from portage.locks import lockfile
from portage.versions import vercmp
NO:
import os
import portage
import portage.util
import time
import sys
Try not to import large numbers of things into the namespace of a module.
I realize this is done all over the place in current code but it really
makes it a pain to do code reflection when the namespace is cluttered
with identifiers from other modules.
YES:
from portage import output
NO:
from portage.output import bold, create_color_func, darkgreen, \
green, nocolor, red, turquoise, yellow
The YES example imports the 'output' module into the current namespace.
The negative here is having to use output.COLOR all over the place
instead of just COLOR. However it means during introspection of the
current namespace 'green','red', 'yellow', etc. will not show up.
The NO example just imports a set of functions from the output module.
It is somewhat annoying because the import line needs to be modified
when functions are needed and often unused functions are left in the
import line until someone comes along with a linter to clean up (does
not happen often).
Commits
-------
Prefer small commits that change specific things to big commits that
change a lot of unrelated things. This makes it easier to see what
parts of the system have actually changed. It also makes it easier to
cherry-pick and revert commits. Use your common sense!
When you make a significant change, make sure to update NEWS
for the to-be-released version. See the current entries to these files for
examples of what constitutes significant.
Commit messages
---------------
Commit messages should be in the imperative mood with a capitalised
header, optionally followed by a newline and a more detailed explanatory
text. The headline should be capped at 70 characters, the detailed text
at 72. Prefix the message with the component you touched if this makes
sense. Postfix the message with the bug it fixes, if it does.
Feel free to use the following notes (if applicable):
Signed-off-by: Wrote (a substantial portion of) the patch
Reviewed-by: Reviewed the patch thoroughly
Tested-by: Tested the patch thoroughly
Acked-by: Approved the concept but did not read the patch in detail
(typically used by the maintainer of a specific portion, or a lead)
Suggested-by: Designed the implementation
Requested-by: Reported the bug/made the feature request
Example:
"""
emerge: Fix --tree output (bug 555555)
Make sure newlines appear where they are supposed to. Fix a bug with
colourisation of --tree output when used in tandem with --verbose
--pretend --ask.
Signed-off-by: Foo Bar <fbar@gentoo.org>
Reviewed-by: Fu Baz <fub@gentoo.org>
Reported-by: Qux Quux <qq@gentoo.org>
"""
For a more detailed explanation (and rationalisation) of these rules:
<http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>
Releases
--------
0. Before starting: CI MUST BE GREEN!
1. Repository mangling:
- Update NEWS (for both new version & release date)
- Update meson.build
and commit.
2. Create a git tag for this release:
git tag -a -s portage-3.0.30
3. Create the tarball and run the tests:
- meson setup -Dmodules-only=true build
- meson test -C build --verbose
Use meson setup's --native-file to override the Python version. See
Python versions listed in tox.ini.
4. Version bump the ebuild locally (don't push) and verify it can re-install itself:
emerge --oneshot sys-apps/portage
emerge --oneshot sys-apps/portage # this is using the new Portage
5. Publish the results (no going back now):
- Push the new git tag
- Upload the tarball
- Commit the new ebuild version and tag the tracker bug for the commit
6. Create the release for pypi and upload it there:
- python -m venv .venv
- . .venv/bin/activate
- pip install build twine
- python -m build # build the sdist and arch/Python-specific wheel
- python -m build --wheel -Csetup-args="-Dnative-extensions=false" # build the pure wheel
- twine upload dist/<filenames>
7. Bugzilla wrangling:
- Close the bugs blocked by the tracker bug for this release and
the tracker itself.
- File a new bug in Portage Development > Core named
"[TRACKER] sys-apps/portage-${NEW_VERSION}"
with the 'Tracker' Bugzilla Keyword and the following text:
"""
Tracks bugs fixed in this release.
'Depends on' now means 'we want to fix this before release'
'Blocks' means 'fixed in this release'
"""
8. Done! Congratulations!
|