blob: 133fe721647571abb2115af14562b000c5aeaf0b [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
142Some 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.
143
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
154 the rest, and ensure that it's no longer than 72 characters.
155- 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
165 refs: #3898
166 Change-Id: Ife89360305027dba9020f0b298793c1121ae1fd6c
167
168Explaining this:
169
170- `docs` is the module that the commit affects. We want this because
171 it lets someone know at a glance what part of the project it
172 changes. For some projects, there will be only one module or only
173 very small other modules. This practice should be observed in
174 those cases, too.
175- `#3898` is the Redmine issue number. Gerrit transforms these into
176 clickable links, and it is useful to reviewers to gain background
177 understanding of the issue. You can have multiple by separating
178 them with commas.
Nick Gordon88043fc2017-08-10 15:34:06 -0500179- `Change-Id` should be filled automatically. It is used by Gerrit
180 to track changes.
Nick Gordon27b38542017-01-05 10:48:29 -0600181
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.
Nick Gordon88043fc2017-08-10 15:34:06 -0500264
2652. Set up your Gerrit credentials. This will depend on how you
Nick Gordon27b38542017-01-05 10:48:29 -0600266 configured your Gerrit remote in step 1. Among other things, you
267 need to set up identities so that the email on your Gerrit profile
268 matches whatever email you will be committing with on your git
269 repo.
Nick Gordon88043fc2017-08-10 15:34:06 -0500270 **Note:** We only support using
271 [SSH access to Gerrit](https://gerrit.named-data.net/Documentation/user-upload.html#ssh).
Nick Gordon27b38542017-01-05 10:48:29 -0600272
273 This shows what the identities panel looks like. If you do
274 not see the email here that you have configured git to use, you
275 cannot upload to Gerrit.
276 ![Web page showing what the "identities" panel looks like](./docs/images/gerrit-credentials-blurred.png)
277
278 In that case, add it under contact information panel.
279 ![Web page showing what the "contact information" panel looks like](./docs/images/gerrit-email.png).
280
281 Gerrit itself has
282 [extensive documentation](https://gerrit.named-data.net/Documentation/error-messages.html)
283 regarding error messages, and this identity-based one is by far the most
Nick Gordon88043fc2017-08-10 15:34:06 -0500284 common. This is the
285 [documentation for an identity error.](https://gerrit.named-data.net/Documentation/error-invalid-author.html)
Nick Gordon27b38542017-01-05 10:48:29 -0600286
Nick Gordon88043fc2017-08-10 15:34:06 -05002873. Clone the source for a project from Gerrit.
288 1. While logged in to Gerrit, there will be a link in the top-left
289 area, `Projects`.
290 2. From this project view, click on the `Clone with commit-msg
291 hook` tab.
292 3. Click on the `ssh` tab to select cloning over SSH. **Note:**
293 This will require setting up SSH access to Gerrit first.
294 4. Copy-and-paste the `git clone ...` command into your terminal
295 to fetch the project source.
Nick Gordon27b38542017-01-05 10:48:29 -0600296
Nick Gordon88043fc2017-08-10 15:34:06 -0500297 After this, your remotes will be set up correctly, and pushing to
298 Gerrit will only require `git push origin HEAD:refs/for/master` after
299 committing work. This section has some
300 [git tips and tricks to type less][type-less].
Nick Gordon27b38542017-01-05 10:48:29 -0600301
302### Uploading patches ###
303
304Most patches should have a corresponding Redmine issue that they can
305reference. If you search the Redmine and notice there is no relevant
306issue for a patch you are writing, please create an issue first. You
307will need a Redmine account, which can be created there.
308
309After writing some changes, commit them locally as normal. After
310saving and exiting your editor, the commit hook will insert a unique
311`Change-Id` to the message.
312
Nick Gordon88043fc2017-08-10 15:34:06 -0500313
Nick Gordon27b38542017-01-05 10:48:29 -0600314Once you have a commit message you are happy with, simply run `git
Nick Gordon88043fc2017-08-10 15:34:06 -0500315push HEAD:refs/for/master`.
Nick Gordon27b38542017-01-05 10:48:29 -0600316
317**Note:** Gerrit separates commits into patch sets by the unique
318`Change-Id`s. As a result, it is important that you either:
319
Nick Gordon88043fc2017-08-10 15:34:06 -0500320* Squash your various commits into one with `git rebase -i
321 <initial commit>`, ensuring that the ultimate `Change-Id` in the
322 commit is the one on the patch set on Gerrit. This workflow is
323 generally preferred.
324* Amend your commit with any new changes using `git commit --amend`.
Nick Gordon27b38542017-01-05 10:48:29 -0600325
326If you do not do this, what will happen is that each commit will be
327interpreted by Gerrit as a separate patch set. This is probably not
328what you want.
329
330### Code Review ###
331#### Dealing with Code Review ####
332
333It is important to remember that code review is about improving
334the quality of code contributed, and nothing else. Further, code
335review is highly important, as every line of code that's
336committed comes with a burden of maintenance. Code review helps
337minimize the burden of that maintenance. Consider that when you
338are receiving comments, those comments are influenced by two
339things:
340
341- How the reviewer personally feels about the change ("Would I
342 be happy to see this code in a year?" or "Would I be happy if
343 I wrote this?") and
344- How the reviewer feels the change abides by style and usage
345 requirements ("I may not personally mind, but we have to do it
346 this way.")
347
348Remembering these things when reading comments helps to separate
349what can feel like needless negativity.
350
351#### Doing Code Review and Writing Comments ####
352
353**Code review is *extremely* important!** We need every bit of code
354 review you can give. In many cases this is the bottleneck for
355 new contributors who do not fully understand how certain
356 language constructs should be used, what best practices are,
357 etc. In these cases it is important to give constructive
358 feedback.
359
360Writing comments is somewhat counter-intuitive on Gerrit. If you are
361signed in through a modern browser, you can leave a comment in a file
362either by clicking on the line number, by selecting some text you want
363to comment and pressing 'c', or by clicking on someone else's
364comment. After typing, click the `Save` button there. After navigating
365through the patch set with the arrows at the top-right of the Gerrit
366UI, you then must click the up-arrow to get back to the Change
367screen. **At this point your comments have *not* been made yet!** You
368must then click the `Reply...` button, and assign a score. If you
369correctly saved your comments, they will be shown at the bottom of
370that box. Once you click post, the comments will be made public to
371others.
372
373Minimally, a review *must* include:
374
375- A score (usually -1, 0, or +1)
376- An "itemized" commentary on each objection you have, or a
377 justification for a whole-change objection.
378
379Optimally, a review should include:
380
381- A useful explanation of *why* you object to some item. This is
382 more important than it first appears. Consider that although
383 you may have been writing code since before you could count,
384 not everyone has. Some things may not be obvious to others,
385 and sharing your knowledge is key to making an open-source
386 project work.
387- Comments about good design decisions. These help motivate
388 developers when otherwise a review is entirely negative
389 comments.
390
391#### Expediting the Code Review Process ####
392
393If you observe that code review takes a long time, there are a
394few things that you can do to to expedite the process:
395
3961. **Think about language best practices.**
3972. **Ask yourself how you would feel about this code, if you saw it "in the wild."**
3983. **When making code decisions, ask yourself "why *shouldn't* I do it this way?"**
399
400#### Responding to Code Review ####
401
402There are a few things to remember when responding to code review, including:
403
404- **Don't** click "Done" on a comment if you agree with a comment and
405 are updating the code accordingly. These comments are essentially
406 useless and only clutter the discussion. Gerrit has a convenient
407 mechanism to check the differences between two patch sets, so
408 reviewers are expected to check that their comments have been
409 addressed.
410- **Don't** blindly follow what is suggested. Review is just that: a
411 review. Sometimes what is suggested is functionally equivalent to
412 what you have implemented. Other times, the reviewer has not
413 considered something when writing their review, and their
414 suggestion will not work. Lastly, if you disagree with a suggestion
415 for some other reason, feel free to object, but you may be asked to
416 provide an explanation.
417- **How** to reply. To reply to a comment, click on the comment in
418 the Gerrit interface, type your reply, and then press save. After
419 replying, you **must remember** to go to the main patch set change
420 screen, and press `Reply...`. Your comments will be shown as
421 drafts, and you must click `Post` to make them visible to others.
422
423### Jenkins ###
424
425As a supplement to the code review process, every patch set is automatically
426compiled and tested on multiple platforms
427using [our instance of Jenkins](http://jenkins.named-data.net/), the
428continuous integration system. Interacting with Jenkins is not usually
429necessary, as Jenkins automatically picks up new patch sets and posts
430the results. Typically the only interaction needed with Jenkins is
431when some kind of glitch occurs and a build needs to be retriggered.
432
433It is expected that code is checked locally. Reviewers may wait until
434Jenkins checks the code before doing a more functional review of the
435code. Since Jenkins checks can take a while, you can save some time by
436checking yourself first.
437
438### Gerrit Change-Id Commit Hook ###
439
Nick Gordon88043fc2017-08-10 15:34:06 -0500440If you encounter an error like this when trying to push work:
441
442 remote: ERROR: [4311462] missing Change-Id in commit message footer
443 remote:
444 remote: Hint: To automatically insert Change-Id, install the hook:
445 remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 someuser@gerrit.named-data.net:hooks/commit-msg ${gitdir}/hooks/
446 remote: And then amend the commit:
447 remote: git commit --amend
448
449Then your commit hook has not been set up correctly, somehow. Follow
450the instructions in the terminal to resolve this.
Nick Gordon27b38542017-01-05 10:48:29 -0600451
452### Code Style Robot ###
453
454As part of CI, there is a script that checks every patch uploaded to
455Gerrit for code style consistency. Checking these kinds of things is
456notoriously difficult, and while the robot is very good in general, it
457will occasionally report false positives and miss things. So all
458issues it raises should be inspected manually to ensure they really
459are style problems. Further, since this automated check is not
460perfect, you should take steps (e.g., configure your editor or run a
461linter before you commit) to ensure you adhere to code style rules.
462
Nick Gordon88043fc2017-08-10 15:34:06 -0500463### <a name="type-less"></a> Typing Less to Upload Patches to Gerrit ###
464
465If typing `HEAD:refs/for/master` feels
466repetitive, you have a few options:
467
468* You can configure git to do the work for you, as described
469 in [this blog post](https://yoursunny.com/t/2017/NFD-devbox/#Uploading-to-Gerrit)
470
471* Git has an alias system that you can use to specify certain
472 commands. For example, you can use `git config --global alias.pg
473 "push origin HEAD:refs/for/master"` to make `git pg` push to Gerrit. You
474 can [learn about git aliases.](https://githowto.com/aliases)
475
476* If using Linux or macOS, it is relatively simple to create a shell
477 alias: `alias gs="git status"` for example, or `alias gitpush="git
478 push origin HEAD:refs/for/master`. The alias itself must be one
479 word, but it can represent multiple words. To persist your
480 aliases, they need to go in your environment file, which is
481 generally at `~/.bashrc` or `~/.zshrc` or `~/.profile`. The exact
482 syntax of aliases and the environment variables file will vary by
483 shell. You should be careful not to overuse aliases, however.
484
485[type-less]: #type-less