1<!-- Copyright 2022 The Fuchsia Authors
2
3Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6This file may not be copied, modified, or distributed except according to
7those terms. -->
8
9# How to Contribute
10
11We'd love to accept your patches and contributions to zerocopy. There are just a
12few small guidelines you need to follow.
13
14Once you've read the rest of this doc, check out our [good-first-issue
15label][good-first-issue] for some good issues you can use to get your toes wet!
16
17## Contributor License Agreement
18
19Contributions to this project must be accompanied by a Contributor License
20Agreement. You (or your employer) retain the copyright to your contribution;
21this simply gives us permission to use and redistribute your contributions as
22part of the project. Head over to <https://cla.developers.google.com/> to see
23your current agreements on file or to sign a new one.
24
25You generally only need to submit a CLA once, so if you've already submitted one
26(even if it was for a different project), you probably don't need to do it
27again.
28
29## Code Reviews
30
31All submissions, including submissions by project members, require review. We
32use GitHub pull requests for this purpose. Consult [GitHub
33Help][about_pull_requests] for more information on using pull requests.
34
35## Code Guidelines
36
37### Philosophy
38
39This section is inspired by [Flutter's style guide][flutter_philosophy], which
40contains many general principles that you should apply to all your programming
41work. Read it. The below calls out specific aspects that we feel are
42particularly important.
43
44#### Dogfood Your Features
45
46In non-library code, it's often advised to only implement features you need.
47After all, it's hard to correctly design code without a concrete use case to
48guide its design. Since zerocopy is a library, this advice is not as applicable;
49we want our API surface to be featureful and complete even if not every feature
50or method has a known use case. However, the observation that unused code is
51hard to design still holds.
52
53Thus, when designing external-facing features, try to make use of them somehow.
54This could be by using them to implement other features, or it could be by
55writing prototype code which won't actually be checked in anywhere. If you're
56feeling ambitious, you could even add (and check in) a [Cargo
57example][cargo_example] that exercises the new feature.
58
59#### Go Down the Rabbit Hole
60
61You will occasionally encounter behavior that surprises you or seems wrong. It
62probably is! Invest the time to find the root cause - you will either learn
63something, or fix something, and both are worth your time. Do not work around
64behavior you don't understand.
65
66### Avoid Duplication
67
68Avoid duplicating code whenever possible. In cases where existing code is not
69exposed in a manner suitable to your needs, prefer to extract the necessary
70parts into a common dependency.
71
72### Comments
73
74When writing comments, take a moment to consider the future reader of your
75comment. Ensure that your comments are complete sentences with proper grammar
76and punctuation. Note that adding more comments or more verbose comments is not
77always better; for example, avoid comments that repeat the code they're anchored
78on.
79
80Documentation comments should be self-contained; in other words, do not assume
81that the reader is aware of documentation in adjacent files or on adjacent
82structures. Avoid documentation comments on types which describe _instances_ of
83the type; for example, `AddressSet is a set of client addresses.` is a comment
84that describes a field of type `AddressSet`, but the type may be used to hold
85any kind of `Address`, not just a client's.
86
87Phrase your comments to avoid references that might become stale; for example:
88do not mention a variable or type by name when possible (certain doc comments
89are necessary exceptions). Also avoid references to past or future versions of
90or past or future work surrounding the item being documented; explain things
91from first principles rather than making external references (including past
92revisions).
93
94When writing TODOs:
95
961. Include an issue reference using the format `TODO(#123):`
971. Phrase the text as an action that is to be taken; it should be possible for
98   another contributor to pick up the TODO without consulting any external
99   sources, including the referenced issue.
100
101### Tests
102
103Much of the code in zerocopy has the property that, if it is buggy, those bugs
104may not cause user code to fail. This makes it extra important to write thorough
105tests, but it also makes it harder to write those tests correctly. Here are some
106guidelines on how to test code in zerocopy:
1071. All code added to zerocopy must include tests that exercise it completely.
1081. Tests must be deterministic. Threaded or time-dependent code, random number
109   generators (RNGs), and communication with external processes are common
110   sources of nondeterminism. See [Write reproducible, deterministic
111   tests][determinism] for tips.
1121. Avoid [change detector tests][change_detector_tests]; tests that are
113   unnecessarily sensitive to changes, especially ones external to the code
114   under test, can hamper feature development and refactoring.
1151. Since we run tests in [Miri][miri], make sure that tests exist which exercise
116   any potential [undefined behavior][undefined_behavior] so that Miri can catch
117   it.
1181. If there's some user code that should be impossible to compile, add a
119   [trybuild test][trybuild] to ensure that it's properly rejected.
120
121### Source Control Best Practices
122
123Commits should be arranged for ease of reading; that is, incidental changes
124such as code movement or formatting changes should be committed separately from
125actual code changes.
126
127Commits should always be focused. For example, a commit could add a feature,
128fix a bug, or refactor code, but not a mixture.
129
130Commits should be thoughtfully sized; avoid overly large or complex commits
131which can be logically separated, but also avoid overly separated commits that
132require code reviews to load multiple commits into their mental working memory
133in order to properly understand how the various pieces fit together.
134
135#### Commit Messages
136
137Commit messages should be _concise_ but self-contained (avoid relying on issue
138references as explanations for changes) and written such that they are helpful
139to people reading in the future (include rationale and any necessary context).
140
141Avoid superfluous details or narrative.
142
143Commit messages should consist of a brief subject line and a separate
144explanatory paragraph in accordance with the following:
145
1461. [Separate subject from body with a blank line](https://chris.beams.io/posts/git-commit/#separate)
1471. [Limit the subject line to 50 characters](https://chris.beams.io/posts/git-commit/#limit-50)
1481. [Capitalize the subject line](https://chris.beams.io/posts/git-commit/#capitalize)
1491. [Do not end the subject line with a period](https://chris.beams.io/posts/git-commit/#end)
1501. [Use the imperative mood in the subject line](https://chris.beams.io/posts/git-commit/#imperative)
1511. [Wrap the body at 72 characters](https://chris.beams.io/posts/git-commit/#wrap-72)
1521. [Use the body to explain what and why vs. how](https://chris.beams.io/posts/git-commit/#why-not-how)
153
154If the code affects a particular subsystem, prefix the subject line with the
155name of that subsystem in square brackets, omitting any "zerocopy" prefix
156(that's implicit). For example, for a commit adding a feature to the
157zerocopy-derive crate:
158
159```text
160[derive] Support AsBytes on types with parameters
161```
162
163The body may be omitted if the subject is self-explanatory; e.g. when fixing a
164typo. The git book contains a [Commit Guidelines][commit_guidelines] section
165with much of the same advice, and the list above is part of a [blog
166post][beams_git_commit] by [Chris Beams][chris_beams].
167
168Commit messages should make use of issue integration. Including an issue
169reference like `#123` will cause the GitHub UI to link the text of that
170reference to the referenced issue, and will also make it so that the referenced
171issue back-links to the commit. Use "Closes", "Fixes", or "Resolves" on its own
172line to automatically close an issue when your commit is merged:
173
174```text
175Closes #123
176Fixes #123
177Resolves #123
178```
179
180When using issue integration, don't omit necessary context that may also be
181included in the relevant issue (see "Commit messages should be _concise_ but
182self-contained" above). Git history is more likely to be retained indefinitely
183than issue history (for example, if this repository is migrated away from GitHub
184at some point in the future).
185
186Commit messages should never contain references to any of:
187
1881. Relative moments in time
1891. Non-public URLs
1901. Individuals
1911. Hosted code reviews (such as on https://github.com/google/zerocopy/pulls)
192    + Refer to commits in this repository by their SHA-1 hash
193    + Refer to commits in other repositories by public web address (such as
194      https://github.com/google/zerocopy/commit/789b3deb)
1951. Other entities which may not make sense to arbitrary future readers
196
197## Community Guidelines
198
199This project follows [Google's Open Source Community
200Guidelines][google_open_source_guidelines].
201
202[about_pull_requests]: https://help.github.com/articles/about-pull-requests/
203[beams_git_commit]: https://chris.beams.io/posts/git-commit/
204[cargo_example]: http://xion.io/post/code/rust-examples.html
205[change_detector_tests]: https://testing.googleblog.com/2015/01/testing-on-toilet-change-detector-tests.html
206[chris_beams]: https://chris.beams.io/
207[commit_guidelines]: https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines
208[determinism]: https://fuchsia.dev/fuchsia-src/contribute/testing/best-practices#write_reproducible_deterministic_tests
209[flutter_philosophy]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#philosophy
210[good-first-issue]: https://github.com/google/zerocopy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
211[google_open_source_guidelines]: https://opensource.google/conduct/
212[magic_number]: https://en.wikipedia.org/wiki/Magic_number_(programming)
213[miri]: https://github.com/rust-lang/miri
214[trybuild]: https://crates.io/crates/trybuild
215[undefined_behavior]: https://raphlinus.github.io/programming/rust/2018/08/17/undefined-behavior.html
216