blob: ff3c65156eb49f0f4c6590b072f73f2869652e44 [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)
107- [NDN codebase for IoT](https://github.com/named-data-ndnSIM)
108- [ndnSIM codebase](https://github.com/named-data-iot)
109- [Other NDN codebase (REMAP)](https://github.com/remap)
110
111If you are unfamiliar with git, some kind of tutorial on git
112should be your first step,
113[such as this one](https://git-scm.com/book/en/v1/Getting-Started).
114There is also a [Git game](http://learngitbranching.js.org/index.html)
115you can play. Finally, there is a
116[wiki page](https://redmine.named-data.net/projects/nfd/wiki#Development-process)
117on NFD's Redmine that has more useful links.
118
119There are a lot of different projects, so take some time to look
120through them for ones that pertain to your interests. NDN projects
121use [Gerrit](https://gerrit.named-data.net/) for code review purposes.
122
123Occasionally there will be other repositories used privately to test
124changes, but this is uncommon. In general, you will not need to refer
125to these repositories.
126
127### Style ###
128
129Most NDN projects are written in C++, and there is a
130[style guide](https://named-data.net/doc/ndn-cxx/current/code-style.html).
131In general the NDN style is similar to the GNU style, but there are
132some significant changes. This style guide is not exhaustive, and in
133all cases not covered by the guide you should emulate the current
134style of the project.
135
136There is a
137[partial styleguide](https://redmine.named-data.net/projects/nfd/wiki/CodeStyle)
138for Python. It applies many of the provisions from the C++ guide, in
139addition to some other Python-specific things.
140
141Some NDN projects are writtin 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.
142
143#### Commit Messages ####
144
145Commit messages are very important, as they are usually the first
146thing (besides the changelog file) a developer looks at when trying to
147understand the timeline of a project. Commit messages should:
148
149- Have a short, descriptive first line, starting with the module
150 they change. A good rule of thumb is a maximum length of 65
151 characters.
152- If including a body, leave a blank line between the first line and
153 the rest, and ensure that it's no longer than 72 characters.
154- Include Redmine issue numbers. The exact syntax is given below.
155- Be written in an imperative mood. E.g. `"Make foo a bar"` and not
156 `"Foo is now a bar"`
157- Use the present tense. E.g. `"Make foo a bar"` and not `"Made foo a
158 bar"`
159
160To explain, the anatomy of a typical commit message is like this:
161
162 docs: write contributing guide and code of conduct
163
164 refs: #3898
165 Change-Id: Ife89360305027dba9020f0b298793c1121ae1fd6c
166
167Explaining this:
168
169- `docs` is the module that the commit affects. We want this because
170 it lets someone know at a glance what part of the project it
171 changes. For some projects, there will be only one module or only
172 very small other modules. This practice should be observed in
173 those cases, too.
174- `#3898` is the Redmine issue number. Gerrit transforms these into
175 clickable links, and it is useful to reviewers to gain background
176 understanding of the issue. You can have multiple by separating
177 them with commas.
178- `Change-Id` should be filled in
179 [automatically][change-id-hook]. It is used by Gerrit to track
180 changes.
181
182### Unit Tests ###
183With a few exceptions, every patch needs to have unit tests that
184accompany them. For C++, we use
185the [Boost unit test framework](http://www.boost.org/libs/test) to
186help us out. Note that this link points to the newest version of the
187Boost Test library documentation, and you may need to refer to older
188documentation if you are using an older version of Boost. More
189information on this is available in
190the
191[NFD Dev Guide](https://named-data.net/publications/techreports/ndn-0021-7-nfd-developer-guide/)
192
193When designing and writing tests, a few things need to be kept in mind:
194
1951. Unit tests are **design** tools, *not* debug tools. Just because
196 your code passes some unit tests does not mean it is
197 bug-free. Unit tests are tools to convince you that your code does
198 what you think it does.
1992. It can be difficult to know when you should test something. If
200 you find that you are having a hard time designing a test for
201 something, ask yourself whether it is because it doesn't make
202 sense to test what you've just written, or if it's because the way
203 you designed it makes it difficult to test. Consider a second look
204 at your design if you think it's the second one.
2053. The method that gave the world unit tests says that unit tests
206 should be written *before* the code they test. This is
207 a contentious issue, so writing them either before or after is
208 acceptable. If writing them later, keep the tests in mind when
209 writing the code, and it will help design good interfaces.
2104. At the very least, write the test for a completed module/unit of
211 code before moving on. Doing this will ensure that the test gets
212 written, and will help you think about the interface that you need
213 to examine. If you don't, you may forget exactly what each piece
214 is responsible for when you're looking at the whole system
215 afterward.
2165. Separate your I/O, as it is very hard to test, so I/O should be
217 isolated if possible. Consider something like separating a
218 function that invokes I/O into two functions: one that does the
219 I/O and calls the other one, which takes that I/O result. This
220 will make it easier to test that second function than if they were
221 combined.
222
223Writing unit tests using the Boost framework is quite simple, and you
224can refer to existing unit tests for examples.
225([This is a good example.](https://github.com/named-data/NFD/blob/master/tests/rib/rib.t.cpp))
226
227#### Building and running unit tests ####
228This is mentioned in greater depth in
229the [developer's readme](README-dev.md), but the basic procedure is:
230
2311. In the base directory of the project, run `./waf distclean`. This
232 removes all prior build files.
2332. Run `./waf configure --with-tests`. This configures the next build
234 to also build the tests.
2353. Run `./waf`. This will build the tests.
2364. Then, the unit tests will be in the `build` directory, and will be
237 named `unit-tests-<module name`, e.g. `unit-tests-nlsr` or
238 `unit-tests-rib`. To run just one test suite, run
239 `./unit-tests-exampleModule -t ExampleTestSuite`. To run a
240 specific test in a suite, use `./unit-tests-exampleModule -t
241 ExampleTestSuite/ExampleTestCase`.
242
243## Gerrit: Uploading Patches and Code Review ##
244
245As mentioned above, NDN projects
246use [Gerrit](https://gerrit.named-data.net/) for code review. This is
247a web-hosted, open code review platform that allows for interactive
248code review, rebasing, and cross-linking with the Redmine, and a
249developer interacts with it using the familiar git. For issues that
250require a tracker reference, a particularly useful feature is that
251the `refs: #...` becomes a clickable link to the issue for design
252discussion.
253
254### First-time Setup ###
255
256The first-time Gerrit setup goes like this:
257
2581. Log in to Gerrit. You can authenticate using many different
259 methods, including GitHub OAuth. You need to ensure that you have a Gerrit username:
260 1. Log in.
261 2. Click on your name in the top right corner and click "Settings" in the pop-up box.
262 3. In the `Username` box, check for a name. If there's already one there, great.
263 4. If not, type one in, and this will be used in later steps.
2642. [Add Gerrit as a remote location to your local git repo.](https://gerrit.named-data.net/Documentation/user-upload.html) **Note:**
265 when the documentation specifies `HEAD:refs/for/branch`, this
266 means e.g. `HEAD:refs/for/master` or
267 `HEAD:refs/for/some-other-branch`. In most cases, you will be
268 uploading a Change for master.
2693. Set up your Gerrit credentials. This will depend on how you
270 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.
274
275 This shows what the identities panel looks like. If you do
276 not see the email here that you have configured git to use, you
277 cannot upload to Gerrit.
278 ![Web page showing what the "identities" panel looks like](./docs/images/gerrit-credentials-blurred.png)
279
280 In that case, add it under contact information panel.
281 ![Web page showing what the "contact information" panel looks like](./docs/images/gerrit-email.png).
282
283 Gerrit itself has
284 [extensive documentation](https://gerrit.named-data.net/Documentation/error-messages.html)
285 regarding error messages, and this identity-based one is by far the most
286 common. Its specific documentation can be found
287 [here.](https://gerrit.named-data.net/Documentation/error-invalid-author.html)
288
2894. <span id=#change-id-hook></span>Set up commit hooks. You will
290 encounter an error if you attempt to push to Gerrit and haven't
291 done this. We recommend that you set up commit hooks by copy and
292 pasting this into your terminal: `` curl -kLo `git rev-parse
293 --git-dir`/hooks/commit-msg
294 https://gerrit.named-data.net/tools/hooks/commit-msg; chmod +x
295 `git rev-parse --git-dir`/hooks/commit-msg) ``. Whenever you
296 write a commit message from this repo (i.e. the base directory of
297 the project), the git commit-hook should automatically assign the
298 commit a `Change-Id`.
299
300 The prompt to set up the commit hooks should look something like this:
301
302 remote: ERROR: [4311462] missing Change-Id in commit message footer
303 remote:
304 remote: Hint: To automatically insert Change-Id, install the hook:
305 remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 someuser@gerrit.named-data.net:hooks/commit-msg ${gitdir}/hooks/
306 remote: And then amend the commit:
307 remote: git commit --amend
308
309### Uploading patches ###
310
311Most patches should have a corresponding Redmine issue that they can
312reference. If you search the Redmine and notice there is no relevant
313issue for a patch you are writing, please create an issue first. You
314will need a Redmine account, which can be created there.
315
316After writing some changes, commit them locally as normal. After
317saving and exiting your editor, the commit hook will insert a unique
318`Change-Id` to the message.
319
320Once you have a commit message you are happy with, simply run `git
321push gerrit HEAD:refs/for/master` to upload your patch.
322
323**Note:** Gerrit separates commits into patch sets by the unique
324`Change-Id`s. As a result, it is important that you either:
325
3261. Amend your commit with any new changes using `git commit --amend`,
327 or, more complicatedly
3282. Collapse your various commits into one with `git rebase -i
329 <initial commit>`, ensuring that the ultimate `Change-Id` in the
330 commit is the one on the patch set on Gerrit.
331
332If you do not do this, what will happen is that each commit will be
333interpreted by Gerrit as a separate patch set. This is probably not
334what you want.
335
336### Code Review ###
337#### Dealing with Code Review ####
338
339It is important to remember that code review is about improving
340the quality of code contributed, and nothing else. Further, code
341review is highly important, as every line of code that's
342committed comes with a burden of maintenance. Code review helps
343minimize the burden of that maintenance. Consider that when you
344are receiving comments, those comments are influenced by two
345things:
346
347- How the reviewer personally feels about the change ("Would I
348 be happy to see this code in a year?" or "Would I be happy if
349 I wrote this?") and
350- How the reviewer feels the change abides by style and usage
351 requirements ("I may not personally mind, but we have to do it
352 this way.")
353
354Remembering these things when reading comments helps to separate
355what can feel like needless negativity.
356
357#### Doing Code Review and Writing Comments ####
358
359**Code review is *extremely* important!** We need every bit of code
360 review you can give. In many cases this is the bottleneck for
361 new contributors who do not fully understand how certain
362 language constructs should be used, what best practices are,
363 etc. In these cases it is important to give constructive
364 feedback.
365
366Writing comments is somewhat counter-intuitive on Gerrit. If you are
367signed in through a modern browser, you can leave a comment in a file
368either by clicking on the line number, by selecting some text you want
369to comment and pressing 'c', or by clicking on someone else's
370comment. After typing, click the `Save` button there. After navigating
371through the patch set with the arrows at the top-right of the Gerrit
372UI, you then must click the up-arrow to get back to the Change
373screen. **At this point your comments have *not* been made yet!** You
374must then click the `Reply...` button, and assign a score. If you
375correctly saved your comments, they will be shown at the bottom of
376that box. Once you click post, the comments will be made public to
377others.
378
379Minimally, a review *must* include:
380
381- A score (usually -1, 0, or +1)
382- An "itemized" commentary on each objection you have, or a
383 justification for a whole-change objection.
384
385Optimally, a review should include:
386
387- A useful explanation of *why* you object to some item. This is
388 more important than it first appears. Consider that although
389 you may have been writing code since before you could count,
390 not everyone has. Some things may not be obvious to others,
391 and sharing your knowledge is key to making an open-source
392 project work.
393- Comments about good design decisions. These help motivate
394 developers when otherwise a review is entirely negative
395 comments.
396
397#### Expediting the Code Review Process ####
398
399If you observe that code review takes a long time, there are a
400few things that you can do to to expedite the process:
401
4021. **Think about language best practices.**
4032. **Ask yourself how you would feel about this code, if you saw it "in the wild."**
4043. **When making code decisions, ask yourself "why *shouldn't* I do it this way?"**
405
406#### Responding to Code Review ####
407
408There are a few things to remember when responding to code review, including:
409
410- **Don't** click "Done" on a comment if you agree with a comment and
411 are updating the code accordingly. These comments are essentially
412 useless and only clutter the discussion. Gerrit has a convenient
413 mechanism to check the differences between two patch sets, so
414 reviewers are expected to check that their comments have been
415 addressed.
416- **Don't** blindly follow what is suggested. Review is just that: a
417 review. Sometimes what is suggested is functionally equivalent to
418 what you have implemented. Other times, the reviewer has not
419 considered something when writing their review, and their
420 suggestion will not work. Lastly, if you disagree with a suggestion
421 for some other reason, feel free to object, but you may be asked to
422 provide an explanation.
423- **How** to reply. To reply to a comment, click on the comment in
424 the Gerrit interface, type your reply, and then press save. After
425 replying, you **must remember** to go to the main patch set change
426 screen, and press `Reply...`. Your comments will be shown as
427 drafts, and you must click `Post` to make them visible to others.
428
429### Jenkins ###
430
431As a supplement to the code review process, every patch set is automatically
432compiled and tested on multiple platforms
433using [our instance of Jenkins](http://jenkins.named-data.net/), the
434continuous integration system. Interacting with Jenkins is not usually
435necessary, as Jenkins automatically picks up new patch sets and posts
436the results. Typically the only interaction needed with Jenkins is
437when some kind of glitch occurs and a build needs to be retriggered.
438
439It is expected that code is checked locally. Reviewers may wait until
440Jenkins checks the code before doing a more functional review of the
441code. Since Jenkins checks can take a while, you can save some time by
442checking yourself first.
443
444### Gerrit Change-Id Commit Hook ###
445
446<span id=#change-id-hook-explanation></span> If you have done work in
447your local repo before you upload to Gerrit, your commits may not have
448Change-Ids in them. So, you have to add them after you've set up your
449commit hooks.
450
451### Code Style Robot ###
452
453As part of CI, there is a script that checks every patch uploaded to
454Gerrit for code style consistency. Checking these kinds of things is
455notoriously difficult, and while the robot is very good in general, it
456will occasionally report false positives and miss things. So all
457issues it raises should be inspected manually to ensure they really
458are style problems. Further, since this automated check is not
459perfect, you should take steps (e.g., configure your editor or run a
460linter before you commit) to ensure you adhere to code style rules.
461
462[change-id-hook]: #change-id-hook
463[change-id-hook-explanation]: #change-id-hook-explanation