Difference between revisions of "Contributing to Phobos"
(initial version) |
m (Fix issue -> Fix Bugzilla issue) |
||
(28 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | |||
− | |||
Welcome to the D community and thanks for your interest in contributing! | Welcome to the D community and thanks for your interest in contributing! | ||
+ | If you need help you can ask questions on <code>#d</code> IRC channel on libera.chat ([https://kiwiirc.com/nextclient/irc.libera.chat/d web interface]) or on [https://forum.dlang.org/ our forum]. | ||
− | + | For a lists of ideas on how to contribute, please see [[Get_involved|Get involved]]. This document provides advice on making a good pull request to Phobos. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | = | + | == Guidelines for contributing to Phobos == |
The usual workflow is: | The usual workflow is: | ||
− | # [https:// | + | # [https://docs.github.com/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo Fork] [https://github.com/dlang/phobos Phobos] on GitHub |
# Create your [https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches own branch] | # Create your [https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches own branch] | ||
− | # [Starting as a Contributor# | + | # [[Starting as a Contributor#Building_from_source|Work locally]] on your new feature or fix (see the tips below) |
− | # [[# | + | # [[#Unittest_phobos|Test]] your improvements locally |
− | # Submit your [https:// | + | # Submit your [https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request pull request] (PR) |
+ | You can find [[Starting_as_a_Contributor#Building_from_source|build instructions here]]. | ||
Below is a list of tips and checks that you should consider before opening your pull request: | Below is a list of tips and checks that you should consider before opening your pull request: | ||
+ | |||
+ | == Unittest <tt>phobos</tt> == | ||
+ | |||
+ | This section explains commands which are commonly used to test the D standard library <tt>phobos</tt>. | ||
+ | |||
+ | === Full build === | ||
+ | |||
+ | If you want to work on phobos itself, you need to run unittests—either for the full library, a package, or a module. To unittest the entire library: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -j16 -f posix.mak unittest | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Adjust the parameter passed to <tt>-j</tt> depending on your machine (beefier machines support larger parameters). This command unittests <tt>phobos</tt> in both debug and release mode. To only test one of them, add <tt>BUILD=debug</tt> or <tt>BUILD=release</tt> to the command line, for example: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -j16 -f posix.mak BUILD=debug unittest | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Specifying <tt>BUILD</tt> makes unittesting faster so it is recommended in iterative development. Just make sure both debug and release builds are tested before e.g. submitting a pull request. | ||
+ | |||
+ | === Test a single Phobos module === | ||
+ | |||
+ | While changing one specific package or module, it's useful to be able to only unittest that particular entity. The following two commands only unittest (in debug mode) the <tt>std.algorithm</tt> package: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -j16 -f posix.mak BUILD=debug std/algorithm.test | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Several modules, packages, or mix thereof may be specified for testing in the same command line. For example, this command also tests (and also in debug mode) the <tt>std.algorithm</tt> package and the <tt>std.conv</tt> module, with better parallelism: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -j16 -f posix.mak BUILD=debug std/algorithm.test std/conv.test | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Test a single module without rebuilding Phobos === | ||
+ | |||
+ | You can test a module directly with <tt>rdmd</tt>: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | rdmd --compiler=~/dlang/dmd/generated/linux/release/64/dmd -unittest -main std/algorithm/sorting.d | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | (If you are on a different platform, replace <tt>linux></tt> with your respective platform) | ||
+ | |||
+ | However, be aware that this method doesn't recompile the Phobos library and thus only checks the executed file. | ||
+ | Thus you should only use this for fast builds on small changes. | ||
+ | |||
+ | == Run CI checks == | ||
+ | |||
+ | The auto-tester will fail your PR if your changes contain trailing whitespace or incorrect line endings. You can run this test locally with the command: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -j16 -f posix.mak checkwhitespace | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | CircleCi will also run various checks for the [http://dlang.org/dstyle.html DStyle] and ensures that every example is runnable on <tt>dlang.org</tt>. | ||
+ | You can run this test locally with: | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
+ | make -f posix.mak style | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Code == | ||
=== Code style === | === Code style === | ||
Line 28: | Line 85: | ||
* Stick to the [http://dlang.org/dstyle.html style guide]? (e.g. braces in their own lines (allman style) or white spaces between operators) | * Stick to the [http://dlang.org/dstyle.html style guide]? (e.g. braces in their own lines (allman style) or white spaces between operators) | ||
* Avoid unnecessarily importing other Phobos modules | * Avoid unnecessarily importing other Phobos modules | ||
− | * Try to not require | + | * Try to not require the garbage collector (this is not a must) |
* Avoid code duplication | * Avoid code duplication | ||
− | |||
− | |||
* Avoid using <code>auto</code> as return type wherever possible (makes the documentation easier to read) | * Avoid using <code>auto</code> as return type wherever possible (makes the documentation easier to read) | ||
* Use <code>static</code> nested structs for ranges (aka [[Voldemort types]]) and thus store function parameters explicitly in the nested struct | * Use <code>static</code> nested structs for ranges (aka [[Voldemort types]]) and thus store function parameters explicitly in the nested struct | ||
* Avoid <code>unittest</code> in templates (it will generate a new unittest for each instance) - put your tests outside | * Avoid <code>unittest</code> in templates (it will generate a new unittest for each instance) - put your tests outside | ||
+ | * Do overflow checks when computing sizes for <code>malloc</code> and <code>realloc</code> | ||
=== Code advice === | === Code advice === | ||
Line 40: | Line 96: | ||
* Don't be afraid to use the new compiler or language features (e.g. <code>Foo!Range</code> vs. <code>Foo!(Range)</code>) | * Don't be afraid to use the new compiler or language features (e.g. <code>Foo!Range</code> vs. <code>Foo!(Range)</code>) | ||
* Be critical when looking at Phobos code (some parts of Phobos are a bit older and have some relics due to lacking functionality of the compiler) | * Be critical when looking at Phobos code (some parts of Phobos are a bit older and have some relics due to lacking functionality of the compiler) | ||
− | * | + | * Is there an easier or more performant way to do it? |
− | * | + | * Does your PR address only one topic? Can it be split up in smaller PRs? |
− | * | + | * Is your code flexible enough to accommodate more use cases? |
− | * | + | * Read through your code again - is there any part that is not understandable? |
=== Tests === | === Tests === | ||
* [[Git Commit Tester|Autotester]] will automatically compile the code in your PR and test it on all supported platforms. For your first PR you need approval from any reviewer - ping them in case they forget. | * [[Git Commit Tester|Autotester]] will automatically compile the code in your PR and test it on all supported platforms. For your first PR you need approval from any reviewer - ping them in case they forget. | ||
− | * | + | * Do all [[Starting as a Contributor#Unittest_phobos| tests pass locally]]? You can run the tests of |
** single module or packages with <code>make -f posix.mak std/algorithm/comparison.test</code> or <code>make -f posix.mak std/algorithm.test</code> | ** single module or packages with <code>make -f posix.mak std/algorithm/comparison.test</code> or <code>make -f posix.mak std/algorithm.test</code> | ||
** all tests with <code>make -f posix.mak unittest</code> (add <code>-j NUMBER_OF_CORES</code> if you have multiple cores) | ** all tests with <code>make -f posix.mak unittest</code> (add <code>-j NUMBER_OF_CORES</code> if you have multiple cores) | ||
** for small changes in a single module faster with <code>rdmd -main -unittest comparison.d</code> (be careful, this links to your current Phobos version) | ** for small changes in a single module faster with <code>rdmd -main -unittest comparison.d</code> (be careful, this links to your current Phobos version) | ||
** for Windows have a look at [[Starting as a Contributor#Windows_2|building Phobos under windows]]) | ** for Windows have a look at [[Starting as a Contributor#Windows_2|building Phobos under windows]]) | ||
− | * | + | * Do your tests cover all cases? (you can check code coverage in the resulting <code>module.lst</code> of <code>rdmd -cov -main -unittest module.d</code>) |
+ | * Make sure the new code compiles with the -dip1000 switch. | ||
− | + | == Review process == | |
* All PRs ''must'' pass all tests for all supported platforms of [[Git Commit Tester|autotester]] before they will be merged | * All PRs ''must'' pass all tests for all supported platforms of [[Git Commit Tester|autotester]] before they will be merged | ||
Line 61: | Line 118: | ||
* Smaller additions like individual functions can be merged directly after [https://github.com/andralex @andralex] approves | * Smaller additions like individual functions can be merged directly after [https://github.com/andralex @andralex] approves | ||
* Refactoring or bug fixes just need approval (LGTM) from two reviewers and enough time passed (usually 2-3 days, depending on weekends and holidays) to give everyone an opportunity to shout | * Refactoring or bug fixes just need approval (LGTM) from two reviewers and enough time passed (usually 2-3 days, depending on weekends and holidays) to give everyone an opportunity to shout | ||
− | * For low-level changes the other compiler | + | * For low-level changes the other compiler developers ([[GDC]] and [[LDC]]) should be consulted |
− | * Trivial changes (e.g. small documentation enhancements) are usually merged in less than | + | * Trivial changes (e.g. small documentation enhancements) are usually merged in less than 24h - otherwise ping for reviewers |
* If your PR is stalled (no activity for 2-3 days) and you addressed all concerns, don't hesitate to ping your reviewers | * If your PR is stalled (no activity for 2-3 days) and you addressed all concerns, don't hesitate to ping your reviewers | ||
− | * | + | * See [[People#Phobos|here]] for whom to ping |
− | * See [[Starting as a Contributor#rebasing | + | * See [[Starting as a Contributor#Rebasing|rebasing]] if you need to sync your fork with master |
+ | |||
+ | == Naming guidelines == | ||
− | === | + | === General advice === |
+ | * Phobos uses a distinct [[Naming conventions|naming scheme]] | ||
* Use a Capitalized short (50 chars or less) Git commit summary | * Use a Capitalized short (50 chars or less) Git commit summary | ||
* If necessary, wrap your Git explanation paragraph [http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html to 72 chars] | * If necessary, wrap your Git explanation paragraph [http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html to 72 chars] | ||
− | * | + | * Do you use clear variable names? |
− | * | + | * Does your PR have a concise and informative title? |
− | * | + | * Are your Git messages clear and informative (otherwise use <code>git commit --amend</code> for a single commit or <code>git rebase</code> for multiple commits)? |
− | * | + | * Ideally, every commit should contain one easily-explained, self-contained change. [[Starting_as_a_Contributor#Someone_asked_me_to_squash_my_commits.2C_what_does_that_mean.3F|Squash]] fix-ups to your previous commits into the commit they target. |
− | === | + | === Issues === |
* Bug fix PRs should have a separate commit for each bugzilla issue that it fixes | * Bug fix PRs should have a separate commit for each bugzilla issue that it fixes | ||
− | * The message of the commit actually fixes the bug should start with "Fix issue X" where X is the number of the corresponding [https://issues.dlang.org bugzilla] issue. For example: | + | * The message of the commit actually fixes the bug should start with "Fix Bugzulla issue X" where X is the number of the corresponding [https://issues.dlang.org bugzilla] issue. For example: |
<pre>+ Refactor the code assist with the bug fix | <pre>+ Refactor the code assist with the bug fix | ||
− | + Fix issue 17000 - map doesn't accept some range types | + | + Fix Bugzulla issue 17000 - map doesn't accept some range types |
− | + Fix issue 17001 - map doesn't work with some other range type</pre> | + | + Fix Bugzulla issue 17001 - map doesn't work with some other range type</pre> |
* Unrelated fixes, refactorings or additions should preferably go separate pull request(s) (tightly related fixes are okay in the same PR) | * Unrelated fixes, refactorings or additions should preferably go separate pull request(s) (tightly related fixes are okay in the same PR) | ||
+ | |||
+ | See the [https://github.com/dlang-bots/dlang-bot#automated-references Dlang-Bot explanation] on referencing issues for more details. | ||
== Documentation == | == Documentation == | ||
Line 90: | Line 152: | ||
=== Documentation style === | === Documentation style === | ||
− | * The documentation is written in [ | + | * The documentation is written in [https://dlang.org/spec/ddoc.html Ddoc] |
* Use complete English sentences with correct syntax, grammar, and punctuation | * Use complete English sentences with correct syntax, grammar, and punctuation | ||
* Use precise technical terms. Avoids colloquialisms | * Use precise technical terms. Avoids colloquialisms | ||
Line 101: | Line 163: | ||
=== Documentation checks === | === Documentation checks === | ||
− | * | + | * Read your documentation text aloud - is it understandable? |
− | * | + | * Check the output of CyberShadows's DAutoTest of the documentation (or run [https://github.com/dlang/dlang.org it] yourself) |
− | * | + | * All user impacting changes should have a corresponding [https://github.com/dlang/phobos/blob/master/changelog.dd changelog] entry |
− | * | + | * Did you add your method to the summary booktable or cheat sheet of a module? (might be in <code>package.d</code>) |
=== Documentation tricks === | === Documentation tricks === | ||
Line 117: | Line 179: | ||
* Don't put examples in your ddoc header - use the <code>///</code> magic to annotate them. Ddoc will automatically add the annotated test(s) to the <code>Examples</code> section of the method, e.g.: | * Don't put examples in your ddoc header - use the <code>///</code> magic to annotate them. Ddoc will automatically add the annotated test(s) to the <code>Examples</code> section of the method, e.g.: | ||
− | < | + | <syntaxhighlight lang=D>/// |
unittest | unittest | ||
{ | { | ||
assert(1 == 1); | assert(1 == 1); | ||
− | }</ | + | }</syntaxhighlight> |
+ | |||
* Use <code>/// ditto</code> to join multiple methods in the documentation | * Use <code>/// ditto</code> to join multiple methods in the documentation | ||
Line 129: | Line 192: | ||
Thank you for your contribution! | Thank you for your contribution! | ||
+ | |||
+ | == See Also == | ||
+ | |||
+ | * [[Starting as a Contributor]] | ||
+ | * [[Guidelines for maintainers]] | ||
+ | * [[Get involved]] | ||
+ | |||
+ | [[Category: Contribution Guidelines]] |
Latest revision as of 12:53, 9 October 2024
Welcome to the D community and thanks for your interest in contributing!
If you need help you can ask questions on #d
IRC channel on libera.chat (web interface) or on our forum.
For a lists of ideas on how to contribute, please see Get involved. This document provides advice on making a good pull request to Phobos.
Contents
Guidelines for contributing to Phobos
The usual workflow is:
- Fork Phobos on GitHub
- Create your own branch
- Work locally on your new feature or fix (see the tips below)
- Test your improvements locally
- Submit your pull request (PR)
You can find build instructions here. Below is a list of tips and checks that you should consider before opening your pull request:
Unittest phobos
This section explains commands which are commonly used to test the D standard library phobos.
Full build
If you want to work on phobos itself, you need to run unittests—either for the full library, a package, or a module. To unittest the entire library:
make -j16 -f posix.mak unittest
Adjust the parameter passed to -j depending on your machine (beefier machines support larger parameters). This command unittests phobos in both debug and release mode. To only test one of them, add BUILD=debug or BUILD=release to the command line, for example:
make -j16 -f posix.mak BUILD=debug unittest
Specifying BUILD makes unittesting faster so it is recommended in iterative development. Just make sure both debug and release builds are tested before e.g. submitting a pull request.
Test a single Phobos module
While changing one specific package or module, it's useful to be able to only unittest that particular entity. The following two commands only unittest (in debug mode) the std.algorithm package:
make -j16 -f posix.mak BUILD=debug std/algorithm.test
Several modules, packages, or mix thereof may be specified for testing in the same command line. For example, this command also tests (and also in debug mode) the std.algorithm package and the std.conv module, with better parallelism:
make -j16 -f posix.mak BUILD=debug std/algorithm.test std/conv.test
Test a single module without rebuilding Phobos
You can test a module directly with rdmd:
rdmd --compiler=~/dlang/dmd/generated/linux/release/64/dmd -unittest -main std/algorithm/sorting.d
(If you are on a different platform, replace linux> with your respective platform)
However, be aware that this method doesn't recompile the Phobos library and thus only checks the executed file. Thus you should only use this for fast builds on small changes.
Run CI checks
The auto-tester will fail your PR if your changes contain trailing whitespace or incorrect line endings. You can run this test locally with the command:
make -j16 -f posix.mak checkwhitespace
CircleCi will also run various checks for the DStyle and ensures that every example is runnable on dlang.org. You can run this test locally with:
make -f posix.mak style
Code
Code style
- Stick to the style guide? (e.g. braces in their own lines (allman style) or white spaces between operators)
- Avoid unnecessarily importing other Phobos modules
- Try to not require the garbage collector (this is not a must)
- Avoid code duplication
- Avoid using
auto
as return type wherever possible (makes the documentation easier to read) - Use
static
nested structs for ranges (aka Voldemort types) and thus store function parameters explicitly in the nested struct - Avoid
unittest
in templates (it will generate a new unittest for each instance) - put your tests outside - Do overflow checks when computing sizes for
malloc
andrealloc
Code advice
- Don't be afraid to use the new compiler or language features (e.g.
Foo!Range
vs.Foo!(Range)
) - Be critical when looking at Phobos code (some parts of Phobos are a bit older and have some relics due to lacking functionality of the compiler)
- Is there an easier or more performant way to do it?
- Does your PR address only one topic? Can it be split up in smaller PRs?
- Is your code flexible enough to accommodate more use cases?
- Read through your code again - is there any part that is not understandable?
Tests
- Autotester will automatically compile the code in your PR and test it on all supported platforms. For your first PR you need approval from any reviewer - ping them in case they forget.
- Do all tests pass locally? You can run the tests of
- single module or packages with
make -f posix.mak std/algorithm/comparison.test
ormake -f posix.mak std/algorithm.test
- all tests with
make -f posix.mak unittest
(add-j NUMBER_OF_CORES
if you have multiple cores) - for small changes in a single module faster with
rdmd -main -unittest comparison.d
(be careful, this links to your current Phobos version) - for Windows have a look at building Phobos under windows)
- single module or packages with
- Do your tests cover all cases? (you can check code coverage in the resulting
module.lst
ofrdmd -cov -main -unittest module.d
) - Make sure the new code compiles with the -dip1000 switch.
Review process
- All PRs must pass all tests for all supported platforms of autotester before they will be merged
- Big additions (new modules) should go to
std.experimental
first (after they pass the review process) - Smaller additions like individual functions can be merged directly after @andralex approves
- Refactoring or bug fixes just need approval (LGTM) from two reviewers and enough time passed (usually 2-3 days, depending on weekends and holidays) to give everyone an opportunity to shout
- For low-level changes the other compiler developers (GDC and LDC) should be consulted
- Trivial changes (e.g. small documentation enhancements) are usually merged in less than 24h - otherwise ping for reviewers
- If your PR is stalled (no activity for 2-3 days) and you addressed all concerns, don't hesitate to ping your reviewers
- See here for whom to ping
- See rebasing if you need to sync your fork with master
Naming guidelines
General advice
- Phobos uses a distinct naming scheme
- Use a Capitalized short (50 chars or less) Git commit summary
- If necessary, wrap your Git explanation paragraph to 72 chars
- Do you use clear variable names?
- Does your PR have a concise and informative title?
- Are your Git messages clear and informative (otherwise use
git commit --amend
for a single commit orgit rebase
for multiple commits)? - Ideally, every commit should contain one easily-explained, self-contained change. Squash fix-ups to your previous commits into the commit they target.
Issues
- Bug fix PRs should have a separate commit for each bugzilla issue that it fixes
- The message of the commit actually fixes the bug should start with "Fix Bugzulla issue X" where X is the number of the corresponding bugzilla issue. For example:
+ Refactor the code assist with the bug fix + Fix Bugzulla issue 17000 - map doesn't accept some range types + Fix Bugzulla issue 17001 - map doesn't work with some other range type
- Unrelated fixes, refactorings or additions should preferably go separate pull request(s) (tightly related fixes are okay in the same PR)
See the Dlang-Bot explanation on referencing issues for more details.
Documentation
Documentation style
- The documentation is written in Ddoc
- Use complete English sentences with correct syntax, grammar, and punctuation
- Use precise technical terms. Avoids colloquialisms
- Honestly describe limitations and dangers
- Add
Params
,Returns
and if neededSee_Also
sections - Provide at least one ddoced unittest for a new method
- Have a brief one sentence summary for at the beginning of a method
- Give a synopsis at the beginning of a module accompanied by an example
Documentation checks
- Read your documentation text aloud - is it understandable?
- Check the output of CyberShadows's DAutoTest of the documentation (or run it yourself)
- All user impacting changes should have a corresponding changelog entry
- Did you add your method to the summary booktable or cheat sheet of a module? (might be in
package.d
)
Documentation tricks
- Use backticks
`code`
instead of$(D foo)
- Start with a Capital letter in all blocks of the method header
- Use
$(REF)
for links to other methods (format is$(REF _stripLeft, std, algorithm, mutation)
) - Use
$(REF_ALTTEXT)
for a different link name (format is$(REF_ALTTEXT your text, formattedRead, std, format)
- Variables will be automatically put in backticks, use an underscore to avoid this behavior (e.g.
_foo
) - Section headings are marked by a line with a single word followed by a colon
:
, use an underscore to avoid this behavior (e.g.with the following \n code:
needs_code
to avoid the creation of a section) - Section headings with multiple words should use underscores instead of spaces (e.g.
See_Also:
) - Don't put examples in your ddoc header - use the
///
magic to annotate them. Ddoc will automatically add the annotated test(s) to theExamples
section of the method, e.g.:
///
unittest
{
assert(1 == 1);
}
- Use
/// ditto
to join multiple methods in the documentation
Happy hacking!
If you find a new gotcha, don't hesitate to edit this guide.
Thank you for your contribution!