contributing.md
# Contributing
Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts.
* [Sharing your opinion and raising issues](http://docs.silverstripe.org/en/4.3/contributing/issues_and_bugs/)
* [Providing code, whether it's creating a feature or fixing a bug](http://docs.silverstripe.org/en/4.3/contributing/code/)
* [Writing and translating documentation](http://docs.silverstripe.org/en/4.3/contributing/translations/)
* [Translating user-interface elements](http://docs.silverstripe.org/en/4.3/contributing/translation_process/)
## Signing commits
It is highly recommended to sign commits with your PGP key to ensure integrity.
# Further notes
Parts of this contributing guidelines are taken from https://github.com/bitfield/script/blob/master/CONTRIBUTING.md#Documentation
## Documentation
It doesn't matter if you write the greatest piece of code in the history of the world, if no one knows it exists, or how to use it.
Write doc comments
Any functions or methods you write should have useful documentation comments in the standard PHP Docblock format. Specifically, they should say what inputs the function takes, what it does (in detail), and what outputs it returns. If it returns an error value, explain under what circumstances this happens.
For example:
```php
/**
* Method to enable predictive search
* Gives the user a prediction on what it is trying to search for
* @param string $searchTerm
* @return ArrayList
*/
```
This is the whole user manual for your code. It will be included in the autogenerated documentation for the whole package. Remember that readers will often see it without the accompanying code, so it needs to make sense on its own.
## Write a use case
This is probably the most important thing to bear in mind. A great design principle for software libraries is
to start with a real-world use case, and try to implement it using the feature you have in mind.
No issues or PRs will be accepted into script without an accompanying use case (See the project board).
And I hold myself to that rule just as much as anybody else.
What do I mean by "use case"? I mean a real problem that you or someone else actually has, that could be solved using the feature.
For example, you might think it's a very cool idea to add a Frobnicate() method to this module.
Maybe it is, but what's it for? Where would this be used in the real world? Can you give an example of a
problem that could be solved by a program using Frobnicate()? If so, what would the program look like?
The reason for insisting on this up front is that it's much easier to design a feature the right way if you start
with its usage in mind. It's all too easy to design something in the abstract, and then find later that when you
try to use it in a program, the API is completely unsuitable.
Another reason for having a use case is that it gives us a useful example program,
which can be included with the library to show how the feature is used.
The final reason is that it's tempting to over-elaborate a design and add all sorts of bells and whistles
that nobody actually wants. Simple APIs are best. If you think of an enhancement,
but it's not needed for your use case, leave it out. Things can always be enhanced later if necessary.
## Update the docs
Any change to the API should also be accompanied by an update to the docs.
If you add a new method, add it in the appropriate place (sources, filters, etc.),
in its correct order alphabetically, and with a suitable (brief) example of its use.
# Before submitting your pull request
Here's a handy checklist for making sure your PR will be accepted as quickly as possible.
- [ ] Have you opened an issue to discuss the feature and agree its general design?
- [ ] Do you have a use case and, ideally, an example program using the feature?
- [ ] Do you have tests covering 90%+ of the feature code (and, of course passing)
- [ ] Have you written complete and accurate doc comments?
- [ ] Have you updated the README and its table of contents?
- [ ] You rock. Thanks a lot.
# After submitting your PR
Here's a nice tip for PR-driven development in general. After you've submitted the PR, do a 'pre-code-review'.
Go through the diffs, line by line, and be your own code reviewer. Does something look weird?
Is something not quite straightforward? It's quite likely that you'll spot errors at this stage which you missed before,
simply because you're looking at the code with a reviewer's mindset.
If so, fix them! But if you can foresee a question from a code reviewer, comment on the code to answer it in advance.
(Even better, improve the code so that the question doesn't arise.)
# The code review process
If you've completed all these steps, I _will_ invest significant time and energy in giving your PR a detailed code review.
This is a powerful and beneficial process which can not only improve the code, but can also help you learn to be a better
engineer and a better Go programmer—and the same goes for me!
## Expect to be taken seriously
Don't think of code review as a "you got this wrong, fix it" kind of conversation (this isn't a helpful review comment).
Instead, think of it as a discussion where both sides can ask questions, make suggestions, clarify problems and misunderstandings,
catch mistakes, and add improvements.
You shouldn't be disappointed if you don't get a simple 'LGTM' and an instant merge.
If this is what you're used to, then your team isn't really doing code review to its full potential.
Instead, the more comments you get, the more seriously it means I'm taking your work. Where appropriate,
I'll say what I liked as well as what I'd like to see improved.
## Dealing with comments
Now comes the tricky bit. You may not agree with some of the code review comments.
Reviewing code is a delicate business in the first place, requiring diplomacy as well as discretion,
but responding to code reviews is also a skilled task.
If you find yourself reacting emotionally, take a break. Go walk in the woods for a while,
or play with a laughing child. When you come back to the code, approach it as though it were someone else's,
not your own, and ask yourself seriously whether or not the reviewer _has a point_.
If you genuinely think the reviewer has just misunderstood something, or made a mistake,
try to clarify the issue. Ask questions, don't make accusations. Remember that every project has a certain way of doing things,
which may not be your way. It's polite to go along with these practices and conventions.
You may feel as though you're doing the project maintainer a favour by contributing, as indeed you are,
but an open source project is like somebody's home. They're used to living there, they probably like it the way it is,
and they don't always respond well to strangers marching in and rearranging the furniture.
Be considerate, and be willing to listen and make changes.
## This may take a while
Don't be impatient. We've all had the experience of sending in our beautifully-crafted PR and then waiting, waiting, waiting.
Why won't those idiots just merge it? How come other issues and PRs are getting dealt with ahead of mine? Am I invisible?
In fact, doing a _proper_ and serious code review is a time-consuming business. It's not just a case of skim-reading the diffs.
The reviewer will need to check out your branch, run the tests, think carefully about what you've done,
make suggestions, test alternatives. It's almost as much work as writing the PR in the first place.
Open source maintainers are just regular folk with jobs, kids, and zero free time or energy.
They may not be able to drop everything and put in several hours on your PR.
The task may have to wait a week or two until they can get sufficient time and peace and quiet to work on it.
Don't pester them. It's fine to add a comment on the PR if you haven't heard anything for a while,
asking if the reviewer's been able to look at it and whether there's anything you can do to help speed things up.
Comments like 'Y U NO MERGE' are unlikely to elicit a positive response.
Thanks again for helping out!