Project

General

Profile

Coding Standards » History » Version 49

Brett Smith, 07/18/2025 04:05 PM
add checklist item about having recent main

1 1 Tom Clegg
h1. Coding Standards
2
3 41 Peter Amstutz
The rules are always up for debate. However, when debate is needed, it should happen outside the source tree. In other words, if the rules are wrong, first debate the rules at sprint retrospective, then fix the rules, then follow the new rules.
4 1 Tom Clegg
5 2 Tom Clegg
{{toc}}
6 1 Tom Clegg
7 41 Peter Amstutz
h2. Ready to implement checklist
8
9
Before starting full implementation, please fill out this template with information about pre-planning:
10
11
<pre>
12
* Goals and scope of the ticket are clear to the assigned developer and assigned reviewer.
13
** _comments_
14 44 Peter Amstutz
* New or changed UX/UX has a mockup and has gotten feedback from stakeholders.
15 41 Peter Amstutz
** _comments_
16 42 Peter Amstutz
* If part of a larger project, ticket is linked to upstream and downstream tasks.
17 41 Peter Amstutz
** _comments_
18
</pre>
19
20 44 Peter Amstutz
UX/UX stands for "User Interface / User Experience".  This includes new or modified GUI elements in workbench and as well as usability elements of command line tools.
21 41 Peter Amstutz
22
Mockups can consist of a wireframe sketched using a drawing tool (e.g. https://excalidraw.com/) or a coding a non-functional prototype focusing on visual design and avoiding implement behavior and uses hardcoded values.
23
24 44 Peter Amstutz
Stakeholders include the rest of the engineering team, as well as designers, salespeople, customers and other end users as appropriate.  In this process, the assigned developer presents the mockup, makes note of any feedback, and then based on their judgement either: alters the mockup, iterates on feedback, or begins implementation.
25 41 Peter Amstutz
26 32 Peter Amstutz
h2. Ready to merge checklist
27
28
Before asking for a branch review, please fill out this template with information about the branch.
29
30 33 Peter Amstutz
+template begins below, replace the bits between < >+
31 32 Peter Amstutz
32
<pre>
33
<00000-branch-title> @ commit:<git hash>
34
35
<https://ci.arvados.org/... (link to developer test job on jenkins)>
36
37 1 Tom Clegg
_Note each item completed with additional detail if necessary.  If an item is irrelevant to a specific branch, briefly explain why._
38 32 Peter Amstutz
39 43 Peter Amstutz
* All agreed upon points are implemented / addressed.  Describe changes from pre-implementation design.
40 1 Tom Clegg
** _comments_
41 32 Peter Amstutz
* Anything not implemented (discovered or discussed during work) has a follow-up story.
42 1 Tom Clegg
** _comments_
43 41 Peter Amstutz
* Code is tested and passing, both automated and manual, what manual testing was done is described.
44 32 Peter Amstutz
** _comments_
45 49 Brett Smith
* The tested code incorporates recent main branch changes.
46
** _confirm_ ("Incorporates" = merged or rebased. "Recent" = 2-3 working days. The more active development on this component is, the more important it is to be based on recent main to avoid surprising test failures post-merge.)
47 48 Tom Clegg
* New or changed UI/UX has gotten feedback from stakeholders.
48 41 Peter Amstutz
** _comments_
49 32 Peter Amstutz
* Documentation has been updated.
50
** _comments_
51
* Behaves appropriately at the intended scale (describe intended scale).
52
** _comments_
53
* Considered backwards and forwards compatibility issues between client and server.
54 1 Tom Clegg
** _comments_
55 46 Tom Clegg
* Follows our "coding standards":https://dev.arvados.org/projects/arvados/wiki/Coding_Standards and "GUI style guidelines.":https://dev.arvados.org/projects/arvados/wiki/Coding_Standards#GUI-Design-Guidelines-Workbench-2
56 1 Tom Clegg
** _comments_
57
58
<Additional detail about what, why and how this branch changes the code>
59
</pre>
60 44 Peter Amstutz
61 47 Brett Smith
UI/UX stands for "User Interface / User Experience".  This includes new or modified GUI elements in workbench and as well as usability elements of command line tools.
62 44 Peter Amstutz
63
Stakeholders include the rest of the engineering team, as well as designers, salespeople, customers and other end users as appropriate.  In this process, the assigned developer demos the new feature, makes note of any feedback, and then based on their judgement either: implements the changes, provides a reason why the feedback cannot be acted on, or discusses how to handle the feedback with the assigned reviewer and/or product manager.
64 32 Peter Amstutz
65 2 Tom Clegg
h2. Git commits
66
67 1 Tom Clegg
Make sure your name and email address are correct.
68
69
* Use @git config --global user.email foo@example.com@ et al.
70
* It's a little unfortunate to have commits with author @foo@myworkstation.local@ but not bad enough to rewrite history, so fix this before you push!
71
72 19 Tom Clegg
Refer to a story number in the first (summary) line of each commit comment. This first line should be <80 chars long, and should be followed by a blank line.
73 9 Tom Clegg
74
* @1234: Remove useless button.@
75
76
*When merging/committing to master,* refer to the story number in a way Redmine will notice. Redmine will list these commits/merges on the story page itself.
77
78 1 Tom Clegg
* @closes #1234@, or
79 19 Tom Clegg
* @refs #1234@, or
80
* @no issue #@ if no Redmine issue is especially relevant.
81 9 Tom Clegg
82 1 Tom Clegg
Use descriptive commit comments.
83
84
* Describe the delta between the old and new tree. If possible, describe the delta in *behavior* rather than the source code itself.
85 9 Tom Clegg
* Good: "1234: Support use of spaces in filenames."
86
* Good: "1234: Fix crash when user_id is nil."
87 1 Tom Clegg
* Less good: "Add some controller methods." (What do they do?)
88
* Less good: "More progress on UI branch." (What is different?)
89
* Less good: "Incorporate Tom's suggestions." (Who cares whose suggestions -- what changed?)
90
91
If further background or explanation is needed, separate it from the summary with a blank line.
92
93
* Example: "Users found it confusing that the boxes had different colors even though they represented the same kinds of things."
94
95 18 Tom Clegg
*Every commit* (even merge commits) must have a DCO sign-off. See [[Developer Certificate Of Origin]].
96 1 Tom Clegg
97
* Example: <code>Arvados-DCO-1.1-Signed-off-by: Joe Smith <joe.smith@example.com></code>
98 19 Tom Clegg
99
Full examples:
100
101
<pre>
102
commit 9c6540b9d42adc4a397a28be1ac23f357ba14ab5
103
Author: Tom Clegg <tom@curoverse.com>
104
Date:   Mon Aug 7 09:58:04 2017 -0400
105
106
    12027: Recognize a new "node failed" error message.
107
    
108
    "srun: error: Cannot communicate with node 0.  Aborting job."
109
    
110
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curoverse.com>
111
</pre>
112
113
<pre>
114
commit 0b4800608e6394d66deec9cecea610c5fbbd75ad
115
Merge: 6f2ce94 3a356c4
116
Author: Tom Clegg <tom@curoverse.com>
117
Date:   Thu Aug 17 13:16:36 2017 -0400
118
119
    Merge branch '12081-crunch-job-retry'
120
    
121
    refs #12080
122
    refs #12081
123
    refs #12108
124
    
125
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curoverse.com>
126
</pre>
127
128 21 Ward Vandewege
h2. Copyright headers
129
130 23 Ward Vandewege
Each Arvados component is released either under the AGPL 3.0 license or the Apache 2.0 license. Documentation is licensed under CC-BY-SA-3.0. See the [[Arvados Licenses FAQ]] for the rationale behind this system.
131 21 Ward Vandewege
132 22 Ward Vandewege
Every file must start with a copyright header that follows this format:
133 21 Ward Vandewege
134
Code under the "AGPLv3 license":http://www.gnu.org/licenses/agpl-3.0.en.html (this example uses Go formatting):
135
136
<pre>
137
// Copyright (C) The Arvados Authors. All rights reserved.
138
//
139
// SPDX-License-Identifier: AGPL-3.0
140
</pre>
141
142
Code under the "Apache 2.0 license":http://www.apache.org/licenses/LICENSE-2.0 (this example uses Python formatting):
143
144
<pre>
145
# Copyright (C) The Arvados Authors. All rights reserved.
146
#
147
# SPDX-License-Identifier: Apache-2.0
148
</pre>
149
150
Documentation under the "Creative Commons Attribution-Share Alike 3.0 United States license":https://creativecommons.org/licenses/by-sa/3.0/us/ (this example uses textile formatting):
151
152
<pre>
153
###. Copyright (C) The Arvados Authors. All rights reserved.
154
....
155
.... SPDX-License-Identifier: CC-BY-SA-3.0
156
</pre>
157
158 1 Tom Clegg
When adding a new file to a component, use the same license as the other files of the component.
159
160 22 Ward Vandewege
When adding a new component, choose either the AGPL or Apache license. Generally speaking, the Apache license is only used for components where integrations in proprietary code must be possible (e.g. our SDKs), though this is not a hard rule. When uncertain which license to choose for a new component, ask on the IRC channel or mailing list.
161 21 Ward Vandewege
162 22 Ward Vandewege
When adding a file in a format that does not support the addition of a copyright header (e.g. in a binary format like an image), add the path to the .licenseignore file in the root of the source tree. This should be done sparingly, and must be discussed explicitly as part of code review. The file must be available under a license that is compatible with the rest of the Arvados code base.
163 21 Ward Vandewege
164 22 Ward Vandewege
When adding a file that originates from an external source under a different license, add the appropriate SPDX line for that license. This is exceptional, and must be discussed explicitly as part of code review. Not every license is compatible with the rest of the Arvados code base.
165 16 Tom Clegg
166 28 Ward Vandewege
There is a helper script at https://github.com/arvados/arvados/blob/master/build/check-copyright-notices that can be used to check - and optionally, fix - the copyright headers in the Arvados source tree.
167 24 Ward Vandewege
168 29 Ward Vandewege
The actual git hook that enforces the copyright headers lives at https://github.com/arvados/arvados-dev/blob/master/git/hooks/check-copyright-headers.rb
169 25 Ward Vandewege
170 13 Tom Clegg
h2. Source code formatting
171 1 Tom Clegg
172 13 Tom Clegg
(Unless otherwise specified by style guide...)
173
174 10 Tom Clegg
No TAB characters in source files. "Except go programs.":https://golang.org/cmd/gofmt/
175 1 Tom Clegg
176 6 Tom Clegg
* Emacs: add to @~/.emacs@ &rarr; @(setq-default indent-tabs-mode nil)@
177
* Vim: add to @~/.vimrc@ &rarr; @:set expandtab@
178 8 Tom Clegg
* See [[Coding Standards#Git setup|Git setup]] below
179 4 Ward Vandewege
180 37 Tom Clegg
No long (>80 column) lines, except
181
* when the alternative is really clunky
182
* in Go where Google style guide prevails, and e.g., "function and method calls should not be separated based solely on line length":https://google.github.io/styleguide/go/decisions#function-formatting
183 6 Tom Clegg
184 4 Ward Vandewege
No whitespace at the end of lines. Make git-diff show you:
185 5 Ward Vandewege
186
  git config color.diff.whitespace "red reverse"
187 6 Tom Clegg
git diff --check
188 1 Tom Clegg
189 13 Tom Clegg
h2. What to include
190
191 1 Tom Clegg
No commented-out blocks of code that have been replaced or obsoleted.
192
193
* It is in the git history if we want it back.
194
* If its absence would confuse someone reading the new code (despite never having read the old code), explain its absence in an English comment. If the old code is really still needed to support the English explanation, then go ahead -- now we know why it's there.
195
196
No commented-out debug statements.
197
198
* If the debug statements are likely to be needed in the future, use a logging facility that can be enabled at run time. @logger.debug "foo"@
199
200 13 Tom Clegg
h2. Style mismatch
201
202 1 Tom Clegg
Adopt indentation style of surrounding lines or (when starting a new file) the nearest existing source code in this tree/language.
203
204
If you fix up existing indentation/formatting, do that in a separate commit.
205
* If you bundle formatting changes with functional changes, it makes functional changes hard to find in the diff.
206
207 13 Tom Clegg
h2. Go
208
209
gofmt, golint, etc., and https://github.com/golang/go/wiki/CodeReviewComments
210
211 40 Tom Clegg
Use @%w@ when wrapping an error with fmt.Errorf(), so errors.As() can access the wrapped error.
212
213
<pre><code class="go">
214
        if err != nil {
215
                return fmt.Errorf("could not swap widgets: %w", err)
216
        }
217
</code></pre>
218
219
Use @(logrus.FieldLogger)WithError()@ (instead of @Logf("blah: %s", err)@) when logging an error.
220
221
<pre><code class="go">
222
        if err != nil {
223
                logger.WithError(err).Warn("error swapping widgets")
224
        }
225
</code></pre>
226
227
228 13 Tom Clegg
h2. Ruby
229
230
https://github.com/bbatsov/ruby-style-guide
231
232 1 Tom Clegg
h2. Python
233 13 Tom Clegg
234 30 Brett Smith
h3. Python code
235 12 Tom Clegg
236 30 Brett Smith
For code, follow "PEP 8":https://peps.python.org/pep-0008/.
237 1 Tom Clegg
238 30 Brett Smith
When you add functions, methods, or attributes that SDK users should not use, their name should start with a leading underscore. This is a common convention to signal that an interface is not intended to be public. Anything named this way will be excluded from our SDK web documentation by default.
239
240 39 Brett Smith
You're encouraged to add type annotations to functions and methods. As of May 2024 these are purely for documentation: we are not type checking any of our Python. Note that your annotations must be understood by the oldest version of Python we currently support (3.8).
241 36 Brett Smith
242 30 Brett Smith
h3. Python docstrings
243
244
Public classes, methods, and functions should all have docstrings. The content of the docstring should follow "PEP 257":https://peps.python.org/pep-0257/.
245
246 1 Tom Clegg
Format docstrings with Markdown and follow these style rules:
247
248 36 Brett Smith
* Document function argument lists after the high-level description following this format for each argument: <pre>* name: type --- Description</pre>Use exactly three minus-hyphens to get an em dash in the web rendering. Provide a helpful type hint whenever practical. The type hint should be written in "modern" style:
249
** Use builtin subscripting from PEP 585/Python 3.9, like @dict[str, str]@, @list[tuple[int, str]]@
250
** Use type union syntax from PEP 604/Python 3.10, like @int | None@, @list[str | bytes]@
251
** Use fully qualified names for custom types. This way pdoc hyperlinks them.
252 34 Brett Smith
* When something is deprecated, write a @.. WARNING:: Deprecated@ admonition immediately after the first line. Its text should explain that the thing is deprecated, and suggest what to use instead. For example:<pre>def add(a, b):
253
    """Add two things.
254
255 1 Tom Clegg
    .. WARNING:: Deprecated
256
       This function is deprecated. Use the `+` operator instead.
257 30 Brett Smith
258
259 36 Brett Smith
    """</pre>You can similarly note private methods with @.. ATTENTION:: Internal@.
260
* Mark up all identifiers outside the type hint with backticks. When the identifier exists in the current module, use the short name. Otherwise, use the fully-qualified name. Our web documentation will automatically link these identifiers to their corresponding documentation.
261 30 Brett Smith
* Mark up links using Markdown's footnote style. For example:<pre>"""Python docstring following [PEP 257][pep257].
262
263
[pep257]: https://peps.python.org/pep-0257/
264
"""</pre>This looks best in plaintext. A descriptive identifier is nice if you can keep it short, but if that's challenging, plain ordinals are fine too.
265
* Mark up headers (e.g., in a module docstring) using underline style. For example:<pre>"""Generic utility module
266
267
Filesystem functions
268
--------------------
269
270
271
272
Regular expressions
273
-------------------
274
275
276
"""</pre>This looks best in plaintext.
277
278
The goal of these style rules is to provide a readable, consistent appearance whether people read the documentation in plain text (e.g., using @pydoc@) or their browser (as rendered by @pdoc@).
279 12 Tom Clegg
280 11 Brett Smith
h2. JavaScript
281
282 20 Tom Clegg
Follow the Airbnb Javascript coding style guide unless otherwise stated:
283 14 Tom Morris
https://github.com/airbnb/javascript
284 20 Tom Clegg
285
We already have 4-space indents everywhere, though, so do that.
286
287 14 Tom Morris
288 7 Tom Clegg
h2. Git setup
289 6 Tom Clegg
290 7 Tom Clegg
Configure git to prevent you from committing whitespace errors.
291 1 Tom Clegg
292 6 Tom Clegg
<pre>
293 7 Tom Clegg
git config --global core.whitespace tab-in-indent,trailing-space
294 1 Tom Clegg
git config --global apply.whitespace error
295 17 Tom Clegg
</pre>
296
297
Add a DCO sign-off to the default commit message.
298
299
<pre>
300
cd .../arvados
301
printf '\n\nArvados-DCO-1.1-Signed-off-by: %s <%s>\n' "$(git config user.name)" "$(git config user.email)" >~/.arvados-dco.txt
302
git config commit.template ~/.arvados-dco.txt
303
</pre>
304
305
Add a DCO sign-off and "refs #xxxx" comment (referencing the issue# in the name of the branch being merged) to the default merge commit message.
306
307
<pre>
308
cd .../arvados
309 26 Eric Biagiotti
cat >.git/hooks/prepare-commit-msg <<'EOF'
310 17 Tom Clegg
#!/bin/sh
311
312
case "$2,$3" in
313
    merge,)
314
        br=$(head -n1 ${1})
315
        n=$(echo "${br}" | egrep -o '[0-9]+')
316
        exec >${1}
317
        echo "${br}"
318
        echo
319
        echo "refs #${n}"
320
        echo
321 27 Eric Biagiotti
        echo "Arvados-DCO-1.1-Signed-off-by: $(git config user.name) <$(git config user.email)>"
322 17 Tom Clegg
        ;;
323
    *)
324
        ;;
325
esac
326
EOF
327 26 Eric Biagiotti
chmod +x .git/hooks/prepare-commit-msg
328 6 Tom Clegg
</pre>
329 31 Brett Smith
330 38 Stephen Smith
h2. GUI Design Guidelines (Workbench 2)
331 31 Brett Smith
332
h3. Font Sizes
333
334
* Minimum 12pt (16px) 
335
* Minimum 9 pt (12px) for things like by copyright, footer
336
337
This should be able to be-resized up to 200% without loss of content or functionality.
338
339
h3. Color
340
341
* Text and images of text have a color contrast ratio of at least 4.5:1 You can use "this contrast tool":https://snook.ca/technical/colour_contrast/colour.html#fg=1F7EA1,bg=FFFFFF to check.
342
* Non-text icon, controls, etc - 3:1 must have a color contrast ratio of 3:1.
343
* Avoid hard-coding colors. Use theme colors. If a new color is needed, add it to the theme.  
344
* Used defined grays when possible using RGB value and changing the a value to indicate different meanings (i.e. Active icons have an opacity of 87%, Inactive icons have an opacity of 60%, Disabled icons have an opacity of 38%)
345
346
h3. Icons
347
348
h4. General
349
350
* Interaction target size of at least 44 x 44 pixels
351
* Label should be on right, icon on left for maximum readability
352
* Use minimum 3:1 color contrast (see Color above)
353 45 Stephen Smith
* User appropriate concise alt text for people using screen readers
354 31 Brett Smith
355
h4. Menu/Navigation 
356
357
* No navigation should only supported via breadcrumbs
358
* If less than 5 menu options, consider visible navigation options
359
* If more than 5 menu options, consider a combination navigation where some options are visible and some are hidden
360
* Use the following menu consistently:	
361
** Hamburger (three bars stacked vertically): Used to indicate navigation bar/menu that toggles between being collapsed behind the button or displayed on the screen, often used for global/site-wide/whole application navigation
362
** Döner (three bars that narrow vertically):  Indicates a group filtering menu
363
** Bento (3×3 grid of squares):  Indicates a menu presenting a grid of options (not currently applicable to WB)
364
** Kebab (three dots stacked vertically): Indicates a smaller inline-menu or an overflow/combination menu
365
** Meatballs (three dots stacked horizontally):  Used to indicate a smaller inline-menu.  Often used to indicate action on a related item (i.e. item next to the meatball), good for repeated use in tables, or horizontal elements
366
* If component is an accordion window,  use caret(‸)
367
368
Preferred Icon Repositories:
369 45 Stephen Smith
* https://v5.mui.com/material-ui/material-icons/
370 31 Brett Smith
* https://materialdesignicons.com/
371
* https://fontawesome.com/v5/search
372
373
h3. Buttons
374
375
* Label button with action for usability/to reduce ambiguity (avoid generic button labels for actions)
376
* Buttons vs Links
377
** Buttons should cause change in current context
378
** Links should navigate to a different content or a new resource (e.g. different page)
379
* If text on button - color contract should be 4.5 :1 between button and text
380
* Button color and background color contrast should be 3:1
381
382
h3. Arvados Specific Components
383
384 1 Tom Clegg
Use chips for displaying tokenized values/arrays
385 38 Stephen Smith
386
h3. Loading Indicators
387
388
h4. Page Navigation
389
390
* Navigation between pages should be indicated using @progressIndicatorActions.START_WORKING@ and @progressIndicatorActions.STOP_WORKING@ to show the global top-of-page pulser
391
* Only the initial load or refresh of the full page (eg. triggered by the upper right refresh button) should use this indicator. Partial refreshes should use a more local indicator.
392
** Refreshes of only one section of a page should only show its own loading indicator in that section
393
* Full page refreshes where the location is unchanged should avoid using the initial full-page spinner in favor of the top-of-page spinner, with updated values substituting in the UI when loaded
394
395
h4. User Actions
396
397
* Form submissions or user actions should be indicated by both the @progressIndicatorActions.START_WORKING@ and by enabling the spinner on the submit button of the form (if the action takes place through a form AND if the form stays open for the duration of the action in order to show errors). If the form closes immediately then the page spinner is the only indicator.
398
* Toasts should not be used to notify the user of an in-progress action but only completion / error
399
400
h4. Lazy-loaded fields
401
402
* Fields that load or update (eg. with extra info) after the main view should wait 3-5 seconds before showing a spinner/pulser icon while loading - if the request for extra data fails, a placeholder icon should show with a hint (text or tooltip) indicating that the data failed to load.
403
** The delayed indicator should be implemented as a reusable component (tbd)
404
* Suggested loading indicator for inline fields: https://mhnpd.github.io/react-loader-spinner/docs/components/three-dots)
405 31 Brett Smith
406
h3. References
407
408
"WCAG2.1":https://www.w3.org/WAI/WCAG21/Understanding/
409
410
"Sarah’s talk for references":https://docs.google.com/presentation/d/1HNrhvK7zVZ7jgH3ELbX7KB97SdXCZXrvov_I4Oe1l2c/edit?usp=sharing