303 lines
12 KiB
HTML
303 lines
12 KiB
HTML
{% extends "global/layout.html" %}
|
|
{% block title %}{{ _('Developer Guidelines and Coding Style') }}{% endblock %}
|
|
{% block lastupdated %}2022-01{% endblock %}
|
|
{% block content %}
|
|
<p>{% trans newdevs=site_url('get-involved/guides/new-developers') -%}
|
|
Read the <a href="{{ newdevs }}">new developers guide</a> first.
|
|
{%- endtrans %}</p>
|
|
|
|
<h2>{{ _('Basic Guidelines and Coding Style') }}</h2>
|
|
|
|
<p>{% trans -%}
|
|
Most of the following should be common sense for anybody who has worked on open source or in a commercial
|
|
programming envrionment.
|
|
The following applies mostly to the main development branch i2p.i2p.
|
|
Guidelines for other branches, plugins, and external apps may be substantially different;
|
|
check with the appropriate developer for guidance.
|
|
{%- endtrans %}</p>
|
|
|
|
<h3>{{ _('Community') }}</h3>
|
|
<ul>
|
|
<li>{% trans -%}
|
|
Please don't just "write code". If you can, participate in other development activities, including:
|
|
development discussions and support on IRC, zzz.i2p, and i2pforum.i2p; testing;
|
|
bug reporting and responses; documentation; code reviews; etc.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Active devs should be available periodically on IRC #i2p-dev.
|
|
Be aware of the current release cycle.
|
|
Adhere to release milestones such as feature freeze, tag freeze, and
|
|
the checkin deadline for a release.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
|
|
<h3>{{ _('Release Cycle') }}</h3>
|
|
<p>
|
|
Our normal release cycle is 6-12 weeks.
|
|
Following are the approximate deadlines within a typical 8-week cycle.
|
|
Actual deadlines for each release are set by the lead developer after consultation with the full team.
|
|
</p>
|
|
|
|
<ul>
|
|
<li>{% trans -%}
|
|
1-2 days after previous release: Checkins to trunk are allowed.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
2-3 weeks after previous release: Deadline to propagate major changes from other branches to trunk.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
4-5 weeks before release: Deadline to request new home page links.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
3-4 weeks before release: Feature freeze. Deadline for major new features.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
2-3 weeks before release: Hold project meeting to review new home page link requests, if any.
|
|
{%- endtrans %}</li>
|
|
<li>
|
|
10-14 days before release: String freeze. No more changes to translated ("tagged") strings.
|
|
Push strings to Transifex, announce translation deadline on Transifex.
|
|
</li>
|
|
<li>
|
|
10-14 days before release: Feature deadline. Bug fixes only after this time. No more features, refactoring or cleanup.
|
|
</li>
|
|
<li>
|
|
3-4 days before release: Translation deadline. Pull translations from Transifex and check in.
|
|
</li>
|
|
<li>
|
|
3-4 days before release: Checkin deadline. No checkins after this time without the permission of the release builder.
|
|
</li>
|
|
<li>{% trans -%}
|
|
Hours before release: Code review deadline.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
|
|
|
|
<h3>Git</h3>
|
|
<ul>
|
|
<li>{% trans -%}
|
|
Have a basic understanding of distributed source control systems, even if you haven't
|
|
used git before. Ask for help if you need it.
|
|
Once pushed, checkins are forever, there is no undo. Please be careful.
|
|
If you have not used git before, start with baby steps.
|
|
Check in some small changes and see how it goes.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Test your changes before checking them in.
|
|
If you prefer the checkin-before-test development model,
|
|
use your own development branch
|
|
and propagate back to i2p.i2p once it is working well.
|
|
Do not break the build. Do not cause regressions.
|
|
In case you do (it happens), please do not vanish for a long period after
|
|
you push your change.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
If your change is non-trivial, or you want people to test it and need good test reports
|
|
to know whether your change was tested or not, add a checkin comment to history.txt
|
|
and increment the build revision in RouterVersion.java.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Ensure that you 'git pull' to the latest revision before you check in and push.
|
|
If you inadvertently diverge, merge and push as soon as possible.
|
|
Don't routinely make others merge for you.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Do not check in major changes into the main i2p.i2p branch late in the release cycle.
|
|
If a project will take you more than a couple days, create your own branch in git
|
|
and do the development there so you do not block releases.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
<h3>{{ _('Coding Style') }}</h3>
|
|
<ul>
|
|
<li>{% trans -%}
|
|
Coding style throughout most of the code is 4-spaces for indentation. Do not use tabs.
|
|
Do not reformat code. If your IDE or editor wants to reformat everything, get control of it.
|
|
Yes, we know 4 spaces is a pain, but perhaps you can configure your editor appropriately.
|
|
In some places, the coding style is different.
|
|
Use common sense. Emulate the style in the file you are modifying.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
All new public and package-private classes and methods require Javadocs. Add @since release-number.
|
|
Javadocs for new private methods are desirable.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
For any Javadocs added, there must not be any doclint errors or warnings.
|
|
Run 'ant javadoc' with Oracle Java 14 or higher to check.
|
|
All params must have @param lines, all non-void methods must have @return lines,
|
|
all exceptions declared thrown must have @throws lines, and no HTML errors.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Classes in core/ (i2p.jar) and portions of i2ptunnel are part of our official API.
|
|
There are several out-of-tree plugins and other applications that rely on this API.
|
|
Be careful not to make any changes that break compatibility.
|
|
Don't add methods to the API unless they are of general utility.
|
|
Javadocs for API methods should be clear and complete.
|
|
If you add or change the API, also update the documentation on the website (i2p.www branch).
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Tag strings for translation where appropriate, which is true for all UI strings.
|
|
Don't change existing tagged strings unless really necessary, as it will break existing translations.
|
|
Do not add or change tagged strings after the "tag freeze" in the release cycle so that
|
|
translators have a chance to update before the release.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Use generics and concurrent classes where possible. I2P is a highly multi-threaded application.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Be familiar with common Java pitfalls that are caught by findbugs.
|
|
Run 'ant findbugs' to learn more.
|
|
{%- endtrans %}</li>
|
|
<li>
|
|
We require Java 8 to build and run I2P as of release 0.9.47.
|
|
Do not use Java 7 or 8 classes or methods in embedded subsystems: addressbook, core, i2ptunnel.jar (non-UI), mstreaming, router, routerconsole (news only), streaming.
|
|
These subsystems are used by
|
|
Android and embedded applications that require only Java 6. All classes must be available in Android API 14.
|
|
Java 7 language features are acceptable in these subsystems if supported by the current version
|
|
of the Android SDK and they compile to Java 6-compatible code.
|
|
</li>
|
|
<li>
|
|
Try-with-resources cannot be used in embedded subsystems as it requires java.lang.AutoCloseable
|
|
in the runtime, and this is not available until Android API 19 (KitKat 4.4).
|
|
</li>
|
|
<li>
|
|
The java.nio.file package cannot be used in embedded subsystems as it
|
|
is not available until Android API 26 (Oreo 8).
|
|
</li>
|
|
<li>
|
|
Other than the above limitations,
|
|
Java 8 classes, methods, and constructs may be used in the following subsystems only:
|
|
BOB, desktopgui, i2psnark, i2ptunnel.war (UI), jetty-i2p.jar, jsonrpc, routerconsole (except news), SAM, susidns, susimail, systray.
|
|
</li>
|
|
<li>
|
|
Plugin authors may require any minimum Java version via the plugin.config file.
|
|
</li>
|
|
<li>{% trans -%}
|
|
Explicitly convert between primitive types and classes;
|
|
don't rely on autoboxing/unboxing.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't use URL. Use URI.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't catch Exception. Catch RuntimeException and checked exceptions individually.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't use String.getBytes() without a UTF-8 charset argument. You may also use DataHelper.getUTF8() or DataHelper.getASCII().
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Always specify a UTF-8 charset when reading or writing files. The DataHelper utilities may be helpful.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Always specify a locale (for example Locale.US) when using String.toLowerCase() or String.toUpperCase().
|
|
Do not use String.equalsIgnoreCase(), as a locale cannot be specified.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't use String.split(). Use DataHelper.split().
|
|
{%- endtrans %}</li>
|
|
<li>
|
|
Don't add code to format dates and times. Use DataHelper.formatDate() and formatTime().
|
|
</li>
|
|
<li>{% trans -%}
|
|
Ensure that InputStreams and OutputStreams are closed in finally blocks.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Use {} for all for and while blocks, even if only one line.
|
|
If you use {} for either the if, else, or if-else block, use it for all blocks.
|
|
Put "} else {" on a single line.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Specify fields as final wherever possible.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't store I2PAppContext, RouterContext, Log, or any other references to router or context items in static fields.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Don't start threads in constructors. Use I2PAppThread instead of Thread.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
|
|
<h3>{{ _('Logging') }}</h3>
|
|
The following guidelines apply to the router, webapps, and all plugins.
|
|
<ul>
|
|
<li>
|
|
For any messages not displayed at the default log level (WARN, INFO, and DEBUG),
|
|
unless the message is a static string (no concatenation),
|
|
always use log.shouldWarn(), log.shouldInfo(), or log.shouldDebug()
|
|
before the log call to avoid unnecessary Object churn.
|
|
</li><li>
|
|
Log messages that may be displayed at the default log level (ERROR, CRIT, and logAlways())
|
|
should be brief, clear, and understandable to a non-technical user.
|
|
This includes exception reason text that may also be displayed.
|
|
Consider translating if the error is likely to happen (for example, on form submission errors).
|
|
Otherwise, translation is not necessary, but it may be helpful to search for and reuse
|
|
a string that is already tagged for translation elsewhere.
|
|
</li><li>
|
|
Log messages not displayed at the default log level (WARN, INFO, and DEBUG)
|
|
are intended for developer use, and do not have the above requirements.
|
|
However, WARN messages are available in the Android log tab, and may be of assistance
|
|
to users debugging issues, so use some care with WARN messages as well.
|
|
</li><li>
|
|
INFO and DEBUG log messages should be used sparingly, especially in hot code paths.
|
|
While useful during development, consider removing them or commenting them out
|
|
after testing is complete.
|
|
</li><li>
|
|
Do not log to stdout or stderr (wrapper log).
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
|
|
<h3>{{ _('Licenses') }}</h3>
|
|
<ul>
|
|
<li>{% trans -%}
|
|
Only check in code that you wrote yourself.
|
|
Before checking in any code or library jars from other sources,
|
|
justify why it is necessary,
|
|
verify the license is compatible,
|
|
and obtain approval from the lead developer.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
If you do obtain approval to add external code or jars,
|
|
and binaries are available in any Debian or Ubuntu package,
|
|
you must implement build and packaging options to use the external package instead.
|
|
Checklist of files to modify:
|
|
{%- endtrans %}
|
|
build.properties, build.xml, debian/control, debian/i2p-router.install, debian/i2p-router.links, debian/rules, sub-build.xml
|
|
</li>
|
|
<li>{% trans -%}
|
|
For any images checked in from external sources,
|
|
it is your responsibility to first verify the license is compatible.
|
|
Include the license and source information in the checkin comment.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
<h3>{{ _('Bugs') }}</h3>
|
|
<ul>
|
|
<li>{% trans trac=i2pconv('trac.i2p2.i2p') -%}
|
|
Managing Trac tickets is everybody's job, please help.
|
|
Monitor {{ trac }} for tickets you have been assigned or can help with.
|
|
Assign, categorize, comment on, fix, or close tickets if you can.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
New developers should start by fixing a bug.
|
|
Search for bugs with the 'easy' keyword on trac.
|
|
When you have a fix, attach your patch to the ticket and add the keyword 'review-needed'.
|
|
Do not close the ticket until it's been successfully reviewed and you've checked your changes in.
|
|
Once you've done this smoothly for a couple of tickets, you may follow the normal procedure below.
|
|
{%- endtrans %}</li>
|
|
<li>{% trans -%}
|
|
Close a ticket when you think you've fixed it.
|
|
We don't have a test department to verify and close tickets.
|
|
If you arent sure you fixed it, close it and add a note saying
|
|
"I think I fixed it, please test and reopen if it's still broken".
|
|
Add a comment with the dev build number or revision and set
|
|
the milestone to the next release.
|
|
{%- endtrans %}</li>
|
|
</ul>
|
|
|
|
{% endblock %}
|