blob: df2a4abc780c41c4462a588c8c98cf413900a9c8 [file] [log] [blame] [view]
Nick Gordon27b38542017-01-05 10:48:29 -06001# Contributing to the NDN Codebase
2## Getting Started
3
4The NDN team is very glad you are interested in contributing! The NDN
5(Named Data Networking) codebase is composed of many projects, with
6multiple universities across the world contributing. This
7documentation will help you understand how we work and what we expect
8from contributors.
9
10### Code of Conduct
11
12NDN codebase development adheres to the Contributor Covenant, located
13in `CODE_OF_CONDUCT.md`. By contributing, you are expected to also
14adhere to this code. If you feel someone has breached this code of
15conduct,
16please
17[email us](mailto:lixia@cs.ucla.edu,bzhang@cs.arizona.edu,aa@cs.ucla.edu).
18
19### What can I do?
20
21The NDN codebase continually needs help with, among other
22things:
23
241. Implementing new features
252. Writing fixes for bugs
263. Writing documentation for features that have recently changed or
27 that change quickly. Sometimes people forget to update
28 documentation!
294. Code review
30
31## Finding Documentation
32
33The NDN team maintains a community
34([Redmine site](https://redmine.named-data.net/projects/nfd)) for
35issue tracking and documentation hosting. Redmine is the hub for
36design activity. In particular, all design discussion and decisions
37will either occur or be copied there.
38
39**Why did they do it *this* way?** When writing code, if you ever have
40questions about why some design decision was made, the best approach
41is to use `git blame` on a file to inspect the last commit for some
42line of code. In this view there will be a commit hash in hex
43(e.g. `0ab12e3a`) in the first column. Using our example, `git show
440ab12e3a` would show the commit made for that line. In the commit view
45there should be a reference number (e.g. `refs: #1234`). Using this
46number, you can find a pertaining issue on the Redmine
47(e.g., `https://redmine.named-data.net/issues/1234`).
48
49Additionally, in some cases there are published papers you can read in
50order to gain a better understanding of the project. Searching for
51these papers is not difficult; in many cases you can find a pertaining
52paper or technical report listed on
53[the main NDN website](https://named-data.net/publications).
54Usually the title of a project will be a good keyword.
55
56If you cannot find an answer to your question, the best place to go is
57the
58[mailing lists](https://named-data.net/codebase/platform/support/mailing-lists/).
59There are multiple different lists for different interests, so be sure you
60are mailing the right list for a quick response.
61
62## Tracking work on Redmine ##
63
64As mentioned above, Redmine is the organizational hub of the NDN
65projects. As such, extensive use of it is made, and learning how it
66works will help you. In particular, there is a workflow associated
67with Redmine. Generally it is:
68
691. An issue is reported by someone. At this point they should
70 describe the issue, including relationships to other
71 issues. Unless they know what they're doing, they should leave
72 particulars blank. Such particulars are priority, target version,
73 assignees, and categories.
742. Design discussion about the issue occurs, and the issue is either
75 accepted or rejected.
763. Someone either is assigned to, or assigns themselves to work on the
77 issue, setting the status to "In progress."
78 **Note:** You must be a "Developer" of the project before you are
79 able to toggle the Status field. A user should contact a project
80 manager to be granted Developer privilege. Project managers can be
81 found on "Overview" page of the project.
824. After every useful chunk of progress, notes are made on the issue
83 and the progress percentage is updated to reflect this. Remember
84 that notes are actually Markdown, so it is advised to use the
85 'preview' button to ensure your note looks right.
865. The changes are uploaded to Gerrit for review. Once all changes
87 pertaining to an issue are on Gerrit, an issues status should
88 change to "Code review."
896. Once all changes are cleared for merging, they either can be
90 merged, or held for feedback, at which point the issue status
91 should become "Feedback."
927. After all changes have been merged, the issue should be set to
93 "Closed."
94
95Redmine provides other facilities for managing your work on NDN
96projects, too, such as time logging and time estimation.
97
98## Contributing Guidelines
99
100### Repositories ###
101
102All NDN projects are hosted on GitHub, at various organizations, using git
103for version control:
104
105- [Main NDN codebase](https://github.com/named-data)
106- [NDN codebase for mobile platforms](https://github.com/named-data-mobile)
Nick Gordon88043fc2017-08-10 15:34:06 -0500107- [NDN codebase for IoT](https://github.com/named-data-iot)
108- [ndnSIM codebase](https://github.com/named-data-ndnSIM)
Nick Gordon27b38542017-01-05 10:48:29 -0600109- [Other NDN codebase (REMAP)](https://github.com/remap)
110
Nick Gordon88043fc2017-08-10 15:34:06 -0500111If you are unfamiliar with git, some kind
112of [tutorial on git](https://git-scm.com/book/en/v1/Getting-Started)
113should be your first step.
114
Nick Gordon27b38542017-01-05 10:48:29 -0600115There is also a [Git game](http://learngitbranching.js.org/index.html)
116you can play. Finally, there is a
117[wiki page](https://redmine.named-data.net/projects/nfd/wiki#Development-process)
118on NFD's Redmine that has more useful links.
119
120There are a lot of different projects, so take some time to look
121through them for ones that pertain to your interests. NDN projects
122use [Gerrit](https://gerrit.named-data.net/) for code review purposes.
123
124Occasionally there will be other repositories used privately to test
125changes, but this is uncommon. In general, you will not need to refer
126to these repositories.
127
128### Style ###
129
130Most NDN projects are written in C++, and there is a
131[style guide](https://named-data.net/doc/ndn-cxx/current/code-style.html).
132In general the NDN style is similar to the GNU style, but there are
133some significant changes. This style guide is not exhaustive, and in
134all cases not covered by the guide you should emulate the current
135style of the project.
136
137There is a
138[partial styleguide](https://redmine.named-data.net/projects/nfd/wiki/CodeStyle)
139for Python. It applies many of the provisions from the C++ guide, in
140addition to some other Python-specific things.
141
Nick Gordon7b8e7972018-05-07 15:57:47 -0500142Some NDN projects are written in JavaScript, and there is a [style guide](https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/) for that language, too.
Nick Gordon27b38542017-01-05 10:48:29 -0600143
144#### Commit Messages ####
145
146Commit messages are very important, as they are usually the first
147thing (besides the changelog file) a developer looks at when trying to
148understand the timeline of a project. Commit messages should:
149
150- Have a short, descriptive first line, starting with the module
151 they change. A good rule of thumb is a maximum length of 65
152 characters.
153- If including a body, leave a blank line between the first line and
Nick Gordon7b8e7972018-05-07 15:57:47 -0500154 the rest, and ensure that each line is no longer than 72 characters.
Nick Gordon27b38542017-01-05 10:48:29 -0600155- Include Redmine issue numbers. The exact syntax is given below.
156- Be written in an imperative mood. E.g. `"Make foo a bar"` and not
157 `"Foo is now a bar"`
158- Use the present tense. E.g. `"Make foo a bar"` and not `"Made foo a
159 bar"`
160
161To explain, the anatomy of a typical commit message is like this:
162
163 docs: write contributing guide and code of conduct
164
Nick Gordon7b8e7972018-05-07 15:57:47 -0500165 This commit adds a guide that may be useful for new-comers to NDN in
166 becoming productive contributors. This commit also adds a code of
167 conduct.
168
Nick Gordon27b38542017-01-05 10:48:29 -0600169 refs: #3898
170 Change-Id: Ife89360305027dba9020f0b298793c1121ae1fd6c
171
172Explaining this:
173
174- `docs` is the module that the commit affects. We want this because
175 it lets someone know at a glance what part of the project it
176 changes. For some projects, there will be only one module or only
177 very small other modules. This practice should be observed in
178 those cases, too.
179- `#3898` is the Redmine issue number. Gerrit transforms these into
180 clickable links, and it is useful to reviewers to gain background
181 understanding of the issue. You can have multiple by separating
182 them with commas.
Nick Gordon88043fc2017-08-10 15:34:06 -0500183- `Change-Id` should be filled automatically. It is used by Gerrit
184 to track changes.
Nick Gordon27b38542017-01-05 10:48:29 -0600185
186### Unit Tests ###
187With a few exceptions, every patch needs to have unit tests that
188accompany them. For C++, we use
189the [Boost unit test framework](http://www.boost.org/libs/test) to
190help us out. Note that this link points to the newest version of the
191Boost Test library documentation, and you may need to refer to older
192documentation if you are using an older version of Boost. More
193information on this is available in
194the
195[NFD Dev Guide](https://named-data.net/publications/techreports/ndn-0021-7-nfd-developer-guide/)
196
197When designing and writing tests, a few things need to be kept in mind:
198
1991. Unit tests are **design** tools, *not* debug tools. Just because
200 your code passes some unit tests does not mean it is
201 bug-free. Unit tests are tools to convince you that your code does
202 what you think it does.
2032. It can be difficult to know when you should test something. If
204 you find that you are having a hard time designing a test for
205 something, ask yourself whether it is because it doesn't make
206 sense to test what you've just written, or if it's because the way
207 you designed it makes it difficult to test. Consider a second look
208 at your design if you think it's the second one.
2093. The method that gave the world unit tests says that unit tests
210 should be written *before* the code they test. This is
211 a contentious issue, so writing them either before or after is
212 acceptable. If writing them later, keep the tests in mind when
213 writing the code, and it will help design good interfaces.
2144. At the very least, write the test for a completed module/unit of
215 code before moving on. Doing this will ensure that the test gets
216 written, and will help you think about the interface that you need
217 to examine. If you don't, you may forget exactly what each piece
218 is responsible for when you're looking at the whole system
219 afterward.
2205. Separate your I/O, as it is very hard to test, so I/O should be
221 isolated if possible. Consider something like separating a
222 function that invokes I/O into two functions: one that does the
223 I/O and calls the other one, which takes that I/O result. This
224 will make it easier to test that second function than if they were
225 combined.
226
227Writing unit tests using the Boost framework is quite simple, and you
228can refer to existing unit tests for examples.
229([This is a good example.](https://github.com/named-data/NFD/blob/master/tests/rib/rib.t.cpp))
230
231#### Building and running unit tests ####
232This is mentioned in greater depth in
233the [developer's readme](README-dev.md), but the basic procedure is:
234
2351. In the base directory of the project, run `./waf distclean`. This
236 removes all prior build files.
2372. Run `./waf configure --with-tests`. This configures the next build
238 to also build the tests.
2393. Run `./waf`. This will build the tests.
2404. Then, the unit tests will be in the `build` directory, and will be
241 named `unit-tests-<module name`, e.g. `unit-tests-nlsr` or
242 `unit-tests-rib`. To run just one test suite, run
243 `./unit-tests-exampleModule -t ExampleTestSuite`. To run a
244 specific test in a suite, use `./unit-tests-exampleModule -t
245 ExampleTestSuite/ExampleTestCase`.
246
247## Gerrit: Uploading Patches and Code Review ##
248
249As mentioned above, NDN projects
250use [Gerrit](https://gerrit.named-data.net/) for code review. This is
251a web-hosted, open code review platform that allows for interactive
252code review, rebasing, and cross-linking with the Redmine, and a
253developer interacts with it using the familiar git. For issues that
254require a tracker reference, a particularly useful feature is that
255the `refs: #...` becomes a clickable link to the issue for design
256discussion.
257
258### First-time Setup ###
259
260The first-time Gerrit setup goes like this:
261
2621. Log in to Gerrit. You can authenticate using many different
263 methods, including GitHub OAuth. You need to ensure that you have a Gerrit username:
264 1. Log in.
265 2. Click on your name in the top right corner and click "Settings" in the pop-up box.
266 3. In the `Username` box, check for a name. If there's already one there, great.
267 4. If not, type one in, and this will be used in later steps.
Nick Gordon88043fc2017-08-10 15:34:06 -0500268
2692. Set up your Gerrit credentials. This will depend on how you
Nick Gordon27b38542017-01-05 10:48:29 -0600270 configured your Gerrit remote in step 1. Among other things, you
271 need to set up identities so that the email on your Gerrit profile
272 matches whatever email you will be committing with on your git
273 repo.
Nick Gordon88043fc2017-08-10 15:34:06 -0500274 **Note:** We only support using
275 [SSH access to Gerrit](https://gerrit.named-data.net/Documentation/user-upload.html#ssh).
Nick Gordon27b38542017-01-05 10:48:29 -0600276
277 This shows what the identities panel looks like. If you do
278 not see the email here that you have configured git to use, you
279 cannot upload to Gerrit.
280 ![Web page showing what the "identities" panel looks like](./docs/images/gerrit-credentials-blurred.png)
281
282 In that case, add it under contact information panel.
283 ![Web page showing what the "contact information" panel looks like](./docs/images/gerrit-email.png).
284
285 Gerrit itself has
286 [extensive documentation](https://gerrit.named-data.net/Documentation/error-messages.html)
287 regarding error messages, and this identity-based one is by far the most
Nick Gordon88043fc2017-08-10 15:34:06 -0500288 common. This is the
289 [documentation for an identity error.](https://gerrit.named-data.net/Documentation/error-invalid-author.html)
Nick Gordon27b38542017-01-05 10:48:29 -0600290
Nick Gordon88043fc2017-08-10 15:34:06 -05002913. Clone the source for a project from Gerrit.
292 1. While logged in to Gerrit, there will be a link in the top-left
293 area, `Projects`.
294 2. From this project view, click on the `Clone with commit-msg
295 hook` tab.
296 3. Click on the `ssh` tab to select cloning over SSH. **Note:**
297 This will require setting up SSH access to Gerrit first.
298 4. Copy-and-paste the `git clone ...` command into your terminal
299 to fetch the project source.
Nick Gordon27b38542017-01-05 10:48:29 -0600300
Nick Gordon88043fc2017-08-10 15:34:06 -0500301 After this, your remotes will be set up correctly, and pushing to
302 Gerrit will only require `git push origin HEAD:refs/for/master` after
303 committing work. This section has some
304 [git tips and tricks to type less][type-less].
Nick Gordon27b38542017-01-05 10:48:29 -0600305
306### Uploading patches ###
307
308Most patches should have a corresponding Redmine issue that they can
309reference. If you search the Redmine and notice there is no relevant
310issue for a patch you are writing, please create an issue first. You
311will need a Redmine account, which can be created there.
312
313After writing some changes, commit them locally as normal. After
314saving and exiting your editor, the commit hook will insert a unique
315`Change-Id` to the message.
316
Nick Gordon88043fc2017-08-10 15:34:06 -0500317
Nick Gordon27b38542017-01-05 10:48:29 -0600318Once you have a commit message you are happy with, simply run `git
Nick Gordon88043fc2017-08-10 15:34:06 -0500319push HEAD:refs/for/master`.
Nick Gordon27b38542017-01-05 10:48:29 -0600320
321**Note:** Gerrit separates commits into patch sets by the unique
Nick Gordon7b8e7972018-05-07 15:57:47 -0500322`Change-Id`s. As a result, you must either:
Nick Gordon27b38542017-01-05 10:48:29 -0600323
Nick Gordon88043fc2017-08-10 15:34:06 -0500324* Squash your various commits into one with `git rebase -i
325 <initial commit>`, ensuring that the ultimate `Change-Id` in the
326 commit is the one on the patch set on Gerrit. This workflow is
327 generally preferred.
328* Amend your commit with any new changes using `git commit --amend`.
Nick Gordon27b38542017-01-05 10:48:29 -0600329
330If you do not do this, what will happen is that each commit will be
331interpreted by Gerrit as a separate patch set. This is probably not
332what you want.
333
334### Code Review ###
335#### Dealing with Code Review ####
336
337It is important to remember that code review is about improving
338the quality of code contributed, and nothing else. Further, code
339review is highly important, as every line of code that's
340committed comes with a burden of maintenance. Code review helps
341minimize the burden of that maintenance. Consider that when you
342are receiving comments, those comments are influenced by two
343things:
344
345- How the reviewer personally feels about the change ("Would I
346 be happy to see this code in a year?" or "Would I be happy if
347 I wrote this?") and
348- How the reviewer feels the change abides by style and usage
349 requirements ("I may not personally mind, but we have to do it
350 this way.")
351
352Remembering these things when reading comments helps to separate
353what can feel like needless negativity.
354
355#### Doing Code Review and Writing Comments ####
356
357**Code review is *extremely* important!** We need every bit of code
358 review you can give. In many cases this is the bottleneck for
359 new contributors who do not fully understand how certain
360 language constructs should be used, what best practices are,
361 etc. In these cases it is important to give constructive
362 feedback.
363
364Writing comments is somewhat counter-intuitive on Gerrit. If you are
365signed in through a modern browser, you can leave a comment in a file
366either by clicking on the line number, by selecting some text you want
367to comment and pressing 'c', or by clicking on someone else's
368comment. After typing, click the `Save` button there. After navigating
369through the patch set with the arrows at the top-right of the Gerrit
370UI, you then must click the up-arrow to get back to the Change
371screen. **At this point your comments have *not* been made yet!** You
372must then click the `Reply...` button, and assign a score. If you
373correctly saved your comments, they will be shown at the bottom of
374that box. Once you click post, the comments will be made public to
375others.
376
377Minimally, a review *must* include:
378
379- A score (usually -1, 0, or +1)
380- An "itemized" commentary on each objection you have, or a
381 justification for a whole-change objection.
382
383Optimally, a review should include:
384
385- A useful explanation of *why* you object to some item. This is
386 more important than it first appears. Consider that although
387 you may have been writing code since before you could count,
388 not everyone has. Some things may not be obvious to others,
389 and sharing your knowledge is key to making an open-source
390 project work.
391- Comments about good design decisions. These help motivate
392 developers when otherwise a review is entirely negative
393 comments.
394
395#### Expediting the Code Review Process ####
396
397If you observe that code review takes a long time, there are a
398few things that you can do to to expedite the process:
399
4001. **Think about language best practices.**
4012. **Ask yourself how you would feel about this code, if you saw it "in the wild."**
4023. **When making code decisions, ask yourself "why *shouldn't* I do it this way?"**
403
404#### Responding to Code Review ####
405
406There are a few things to remember when responding to code review, including:
407
408- **Don't** click "Done" on a comment if you agree with a comment and
409 are updating the code accordingly. These comments are essentially
410 useless and only clutter the discussion. Gerrit has a convenient
411 mechanism to check the differences between two patch sets, so
412 reviewers are expected to check that their comments have been
413 addressed.
414- **Don't** blindly follow what is suggested. Review is just that: a
415 review. Sometimes what is suggested is functionally equivalent to
416 what you have implemented. Other times, the reviewer has not
417 considered something when writing their review, and their
418 suggestion will not work. Lastly, if you disagree with a suggestion
419 for some other reason, feel free to object, but you may be asked to
420 provide an explanation.
421- **How** to reply. To reply to a comment, click on the comment in
422 the Gerrit interface, type your reply, and then press save. After
423 replying, you **must remember** to go to the main patch set change
424 screen, and press `Reply...`. Your comments will be shown as
425 drafts, and you must click `Post` to make them visible to others.
426
427### Jenkins ###
428
429As a supplement to the code review process, every patch set is automatically
430compiled and tested on multiple platforms
431using [our instance of Jenkins](http://jenkins.named-data.net/), the
432continuous integration system. Interacting with Jenkins is not usually
433necessary, as Jenkins automatically picks up new patch sets and posts
434the results. Typically the only interaction needed with Jenkins is
435when some kind of glitch occurs and a build needs to be retriggered.
436
437It is expected that code is checked locally. Reviewers may wait until
438Jenkins checks the code before doing a more functional review of the
439code. Since Jenkins checks can take a while, you can save some time by
440checking yourself first.
441
442### Gerrit Change-Id Commit Hook ###
443
Nick Gordon88043fc2017-08-10 15:34:06 -0500444If you encounter an error like this when trying to push work:
445
446 remote: ERROR: [4311462] missing Change-Id in commit message footer
447 remote:
448 remote: Hint: To automatically insert Change-Id, install the hook:
449 remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 someuser@gerrit.named-data.net:hooks/commit-msg ${gitdir}/hooks/
450 remote: And then amend the commit:
451 remote: git commit --amend
452
453Then your commit hook has not been set up correctly, somehow. Follow
454the instructions in the terminal to resolve this.
Nick Gordon27b38542017-01-05 10:48:29 -0600455
456### Code Style Robot ###
457
458As part of CI, there is a script that checks every patch uploaded to
459Gerrit for code style consistency. Checking these kinds of things is
460notoriously difficult, and while the robot is very good in general, it
461will occasionally report false positives and miss things. So all
462issues it raises should be inspected manually to ensure they really
463are style problems. Further, since this automated check is not
464perfect, you should take steps (e.g., configure your editor or run a
465linter before you commit) to ensure you adhere to code style rules.
466
Nick Gordon88043fc2017-08-10 15:34:06 -0500467### <a name="type-less"></a> Typing Less to Upload Patches to Gerrit ###
468
469If typing `HEAD:refs/for/master` feels
470repetitive, you have a few options:
471
472* You can configure git to do the work for you, as described
473 in [this blog post](https://yoursunny.com/t/2017/NFD-devbox/#Uploading-to-Gerrit)
474
475* Git has an alias system that you can use to specify certain
476 commands. For example, you can use `git config --global alias.pg
Nick Gordon7b8e7972018-05-07 15:57:47 -0500477 "push origin HEAD:refs/for/master"` to make `git pg` push to
478 Gerrit. [Learn about git aliases here.](https://githowto.com/aliases)
Nick Gordon88043fc2017-08-10 15:34:06 -0500479
480* If using Linux or macOS, it is relatively simple to create a shell
481 alias: `alias gs="git status"` for example, or `alias gitpush="git
482 push origin HEAD:refs/for/master`. The alias itself must be one
483 word, but it can represent multiple words. To persist your
484 aliases, they need to go in your environment file, which is
485 generally at `~/.bashrc` or `~/.zshrc` or `~/.profile`. The exact
486 syntax of aliases and the environment variables file will vary by
487 shell. You should be careful not to overuse aliases, however.
488
489[type-less]: #type-less