|
Packit Service |
dff8e4 |
Guidelines for Contributing
|
|
Packit Service |
dff8e4 |
===========================
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Community
|
|
Packit Service |
dff8e4 |
---------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Check out website https://networkmanager.dev and our [GNOME page](https://wiki.gnome.org/Projects/NetworkManager).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
The release tarballs can be found at [download.gnome.org](https://download.gnome.org/sources/NetworkManager/).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Our mailing list is networkmanager-list@gnome.org ([archive](https://mail.gnome.org/archives/networkmanager-list/)).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Find us on IRC channel `#nm` on freenode.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Report issues and send patches via [gitlab.freedesktop.org](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/)
|
|
Packit Service |
dff8e4 |
or our mailing list.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Legal
|
|
Packit Service |
dff8e4 |
-----
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
NetworkManager is partly licensed under terms of GNU Lesser General Public License
|
|
Packit Service |
dff8e4 |
version 2 or later ([LGPL-2.1-or-later](COPYING.LGPL)). That is for example the case for libnm.
|
|
Packit Service |
dff8e4 |
For historical reasons, the daemon itself is licensed under terms of GNU General
|
|
Packit Service |
dff8e4 |
Public License, version 2 or later ([GPL-2.0-or-later](COPYING)). See the SPDX license comment
|
|
Packit Service |
dff8e4 |
in the source files.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Note that all new contributions to NetworkManager **MUST** be made under terms of
|
|
Packit Service |
dff8e4 |
LGPL-2.1-or-later, that is also the case for files that are currently licensed GPL-2.0-or-later.
|
|
Packit Service |
dff8e4 |
The reason is that we might one day use the code under terms of LGPL-2.1-or-later and all
|
|
Packit Service |
dff8e4 |
new contributions already must already agree to that.
|
|
Packit Service |
dff8e4 |
For more details see [RELICENSE.md](RELICENSE.md).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Coding Standard
|
|
Packit Service |
dff8e4 |
---------------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
The formatting uses clang-format with clang 11.0. Run
|
|
Packit Service |
dff8e4 |
`./contrib/scripts/nm-code-format.sh -i` to reformat the code
|
|
Packit Service |
dff8e4 |
or call `clang-format` yourself.
|
|
Packit Service |
dff8e4 |
You may also call `./contrib/scripts/nm-code-format-container.sh`
|
|
Packit Service |
dff8e4 |
which runs a Fedora 33 container using podman.
|
|
Packit Service |
dff8e4 |
You are welcome to not bother and open a merge request with
|
|
Packit Service |
dff8e4 |
wrong formatting, but note that we then will automatically adjust
|
|
Packit Service |
dff8e4 |
your contribution before merging.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
The automatic reformatting was done by commit 328fb90f3e0d4e35975aff63944ac0412d7893a5.
|
|
Packit Service |
dff8e4 |
Use `--ignore-rev` option or `--ignore-revs-file .git-blame-ignore-revs` to ignore
|
|
Packit Service |
dff8e4 |
the reformatting commit with git-blame:
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
$ git config --add 'blame.ignoreRevsFile' '.git-blame-ignore-revs'
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Since our coding style is entirely automated, the following are just
|
|
Packit Service |
dff8e4 |
some details of the style we use:
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* Indent with 4 spaces. (_no_ tabs).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* Have no space between the function name and the opening '('.
|
|
Packit Service |
dff8e4 |
- GOOD: `g_strdup(x)`
|
|
Packit Service |
dff8e4 |
- BAD: `g_strdup (x)`
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* C-style comments
|
|
Packit Service |
dff8e4 |
- GOOD: `f(x); /* comment */`
|
|
Packit Service |
dff8e4 |
- BAD: `f(x); // comment`
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* Keep assignments in the variable declaration area pretty short.
|
|
Packit Service |
dff8e4 |
- GOOD: `MyObject *object;`
|
|
Packit Service |
dff8e4 |
- BAD: `MyObject *object = complex_and_long_init_function(arg1, arg2, arg3);`
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* 80-cols is a guideline, don't make the code uncomfortable in order to fit in
|
|
Packit Service |
dff8e4 |
less than 80 cols.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
* Constants are CAPS_WITH_UNDERSCORES and use the preprocessor.
|
|
Packit Service |
dff8e4 |
- GOOD: `#define MY_CONSTANT 42`
|
|
Packit Service |
dff8e4 |
- BAD: `static const unsigned myConstant = 42;`
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Assertions in NetworkManager code
|
|
Packit Service |
dff8e4 |
---------------------------------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
There are different kind of assertions. Use the one that is appropriate.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
1) `g_return_*()` from glib. This is usually enabled in release builds and
|
|
Packit Service |
dff8e4 |
can be disabled with `G_DISABLE_CHECKS` define. This uses `g_log()` with
|
|
Packit Service |
dff8e4 |
`G_LOG_LEVEL_CRITICAL` level (which allows the program to continue,
|
|
Packit Service |
dff8e4 |
unless `G_DEBUG=fatal-criticals` or `G_DEBUG=fatal-warnings` is set). As such,
|
|
Packit Service |
dff8e4 |
this is usually the preferred way for assertions that are supposed to be
|
|
Packit Service |
dff8e4 |
enabled by default. \
|
|
Packit Service |
dff8e4 |
\
|
|
Packit Service |
dff8e4 |
Optimally, after a `g_return_*()` failure the program can still continue. This is
|
|
Packit Service |
dff8e4 |
also the reason why `g_return_*()` is preferable over `g_assert()`.
|
|
Packit Service |
dff8e4 |
For example, that is often not the case for functions that return a `GError`, because
|
|
Packit Service |
dff8e4 |
`g_return_*()` will return failure without setting the error output. That often leads
|
|
Packit Service |
dff8e4 |
to a crash immediately after, because the caller requires the `GError` to be set.
|
|
Packit Service |
dff8e4 |
Make a reasonable effort so that an assertion failure may allow the process
|
|
Packit Service |
dff8e4 |
to proceed. But don't put too much effort in it. After all, it's an assertion
|
|
Packit Service |
dff8e4 |
failure that is not supposed to happen either way.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
2) `nm_assert()` from NetworkManager. This is disabled by default in release
|
|
Packit Service |
dff8e4 |
builds, but enabled if you build `--with-more-assertions`. See the `WITH_MORE_ASSERTS`
|
|
Packit Service |
dff8e4 |
define. This is preferred for assertions that are expensive to check or
|
|
Packit Service |
dff8e4 |
nor necessary to check frequently. It's also for conditions that can easily
|
|
Packit Service |
dff8e4 |
be verified to be true and where future refactoring is unlikely to break the
|
|
Packit Service |
dff8e4 |
invariant.
|
|
Packit Service |
dff8e4 |
Use such asserts deliberately and assume they are removed from production builds.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
3) `g_assert()` from glib. This is used in unit tests and commonly enabled
|
|
Packit Service |
dff8e4 |
in release builds. It can be disabled with `G_DISABLE_ASSERT` define.
|
|
Packit Service |
dff8e4 |
Since such an assertion failure results in a hard crash, you
|
|
Packit Service |
dff8e4 |
should almost always prefer `g_return_*()` over `g_assert()` (except in unit tests).
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
4) `assert()` from C89's `<assert.h>`. It is usually enabled in release builds and
|
|
Packit Service |
dff8e4 |
can be disabled with `NDEBUG` define. Don't use it in NetworkManager,
|
|
Packit Service |
dff8e4 |
it's basically like g_assert().
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
5) `g_log()` from glib. These are always compiled in, depending on the logging level
|
|
Packit Service |
dff8e4 |
they act as assertions too. `G_LOG_LEVEL_ERROR` messages abort the program, `G_LOG_LEVEL_CRITICAL`
|
|
Packit Service |
dff8e4 |
log a critical warning (like `g_return_*()`, see `G_DEBUG=fatal-criticals`)
|
|
Packit Service |
dff8e4 |
and `G_LOG_LEVEL_WARNING` logs a warning (see `G_DEBUG=fatal-warnings`).
|
|
Packit Service |
dff8e4 |
`G_LOG_LEVEL_DEBUG` level is usually not printed, unless `G_MESSAGES_DEBUG` environment
|
|
Packit Service |
dff8e4 |
variable enables it. \
|
|
Packit Service |
dff8e4 |
\
|
|
Packit Service |
dff8e4 |
In general, avoid using `g_log()` in NetworkManager. We have nm-logging instead
|
|
Packit Service |
dff8e4 |
which logs to syslog or systemd-journald.
|
|
Packit Service |
dff8e4 |
From a library like libnm it might make sense to log warnings (if something
|
|
Packit Service |
dff8e4 |
is really wrong) or debug messages. But better don't. If it's important,
|
|
Packit Service |
dff8e4 |
find a way to report the condition via the API to the caller. If it's
|
|
Packit Service |
dff8e4 |
not important, keep silent.
|
|
Packit Service |
dff8e4 |
In particular, don't use levels `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING` because
|
|
Packit Service |
dff8e4 |
we treat them as assertions and we want to run all out tests with `G_DEBUG=fatal-warnings`.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
6) `g_warn_if_*()` from glib. These are always compiled in and log a `G_LOG_LEVEL_WARNING`
|
|
Packit Service |
dff8e4 |
warning. Don't use this.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
7) `G_TYPE_CHECK_INSTANCE_CAST()` from glib. Unless building with `WITH_MORE_ASSERTS`,
|
|
Packit Service |
dff8e4 |
we set `G_DISABLE_CAST_CHECKS`. This means, cast macros like `NM_DEVICE(ptr)`
|
|
Packit Service |
dff8e4 |
translate to plain C pointer casts. Use such cast macros deliberately, in production
|
|
Packit Service |
dff8e4 |
code they are cheap, with more asserts enabled they check that the pointer type is
|
|
Packit Service |
dff8e4 |
suitable.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Of course, every assertion failure is a bug, and calling it must have no side effects.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Theoretically, you are welcome to set `G_DISABLE_CHECKS`, `G_DISABLE_ASSERT` and
|
|
Packit Service |
dff8e4 |
`NDEBUG` in production builds. In practice, nobody tests such a configuration, so beware.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
For testing, you also want to run NetworkManager with environment variable
|
|
Packit Service |
dff8e4 |
`G_DEBUG=fatal-warnings` to crash upon `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING`
|
|
Packit Service |
dff8e4 |
`g_log()` message. NetworkManager won't use these levels for regular logging
|
|
Packit Service |
dff8e4 |
but for assertions.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Git Notes (refs/notes/bugs)
|
|
Packit Service |
dff8e4 |
---------------------------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
We use special tags in commit messages like "Fixes", "cherry picked from" and "Ignore-Backport".
|
|
Packit Service |
dff8e4 |
The [find-backports](contrib/scripts/find-backports) script uses these to find patches that
|
|
Packit Service |
dff8e4 |
should be backported to older branches. Sometimes we don't know a-priory to mark a commit
|
|
Packit Service |
dff8e4 |
with these tags so we can instead use the `bugs` notes.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
The git notes reference is called "refs/notes/bugs".
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
So configure:
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
$ git config --add 'remote.origin.fetch' 'refs/notes/bugs:refs/notes/bugs'
|
|
Packit Service |
dff8e4 |
$ git config --add 'notes.displayref' 'refs/notes/bugs'
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
For example, set notes with
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
$ git notes --ref refs/notes/bugs add -m "(cherry picked from $COMMIT_SHA)" HEAD
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
You should see the notes in git-log output as well.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
To resync our local notes use:
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
$ git fetch origin refs/notes/bugs:refs/notes/bugs -f
|
|
Packit Service |
dff8e4 |
```
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Code Structure
|
|
Packit Service |
dff8e4 |
---------------------------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./contrib`- Contains a lot of required package, configuration for different platform and environment, build NM from source tree.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./data`- Contains some configurations and rules.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./docs`- Contains the generated documentation for libnm and for the D-Bus API.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./examples`- Some code examples for basic networking operations and status checking.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./introspection`- XML docs describing various D-Bus interface and their properties.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./m4`- Contains M4 macros source files for autoconf.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./man`- NM manual files.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./po`- contains text-based portable object file. These .PO files are referenced by GNU gettext as a property file and these files are human readable used for translating purpose.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./src`- source code for libnm, nmcli, nm-cloud-setup, nmtui…
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
`./tools`- tools for generating the intermediate files or merging the file.
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
Cscope/ctags
|
|
Packit Service |
dff8e4 |
---------------------------
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
NetworkManager's source code is large. It may be a good idea to use tools like cscope/ctags to index the
|
|
Packit Service |
dff8e4 |
source code and navigate it. These tools can integrate with editors like `Vim` and `Emacs`. See:
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
- http://cscope.sourceforge.net/cscope_vim_tutorial.html
|
|
Packit Service |
dff8e4 |
- https://www.emacswiki.org/emacs/CScopeAndEmacs
|